Java流操作在终点的执行顺序[重复]

2023-11-23

我一直试图从官方 Java 文档中找到关于 Java 流的明确约定,一旦调用终端操作,处理元素并调用中间操作。

例如,让我们看一下这些同时使用 Java 流版本和普通迭代版本的示例(两者产生相同的结果) .

示例1:

    List<Integer> ints = Arrays.asList(1, 2, 3, 4, 5);
    Function<Integer, Integer> map1 = i -> i;
    Predicate<Integer> f1 = i -> i > 2;

    public int findFirstUsingStreams(List<Integer> ints){
        return ints.stream().map(map1).filter(f1).findFirst().orElse(-1);
    }

    public int findFirstUsingLoopV1(List<Integer> ints){
        for (int i : ints){
            int mappedI = map1.apply(i);
            if ( f1.test(mappedI) ) return mappedI;
        }
        return -1;
    }

    public int findFirstUsingLoopV2(List<Integer> ints){
        List<Integer> mappedInts = new ArrayList<>( ints.size() );

        for (int i : ints){
            int mappedI = map1.apply(i);
            mappedInts.add(mappedI);
        }

        for (int mappedI : mappedInts){
            if ( f1.test(mappedI) ) return mappedI;
        }
        return -1;
    }

Java流会进来吗findFirstUsingStreams之后的方法findFirst被称为运行map1按照中描述的顺序findFirstUsingLoopV1 (map不适用于所有元素)或如中所述findFirstUsingLoopV2 (map为所有元素运行)?

这个顺序在 Java 的未来版本中会改变吗?或者有一个官方文档可以保证我们的顺序map1 calls?

示例2:

Predicate<Integer> f1 = i -> i > 2;
Predicate<Integer> f2 = i -> i > 3;


public List<Integer> collectUsingStreams(List<Integer> ints){
    return ints.stream().filter(f1).filter(f2).collect( Collectors.toList() );
}

public List<Integer> collectUsingLoopV1(List<Integer> ints){
    List<Integer> result = new ArrayList<>();
    for (int i : ints){
        if ( f1.test(i) && f2.test(i) ) result.add(i);
    }
    return result;
}

public List<Integer> collectUsingLoopV2(List<Integer> ints){
    List<Integer> result = new ArrayList<>();
    for (int i : ints){
        if ( f2.test(i) && f1.test(i) ) result.add(i);
    }
    return result;
}

Java 流将再次传入collectUsingStreams之后的方法collect被称为运行f1 and f2按照中描述的顺序collectUsingLoopV1 (f1之前评估过f2)或如中所述collectUsingLoopV2 (f2之前评估过f1)?

这个顺序在 Java 的未来版本中会改变吗?或者有一个官方文档可以保证我们的顺序f1 and f2 calls?

Edit

感谢您的所有答案和评论,但不幸的是,我仍然没有看到有关处理元素的顺序的良好解释。文档确实说将为列表保留遇到顺序,但他们没有指定如何处理这些元素。例如,如果findFirst该文档保证map1首先会看到 1 然后是 2 但它并没有说map14 和 5 不会被执行。这是否意味着我们不能保证我们的处理顺序将与我们期望的 Java 未来版本一样?可能是。


这个顺序在 Java 的未来版本中会改变吗?或者有官方文档可以保证我们调用 map1 的顺序吗?

javadoc,包括包摘要(人们经常以某种方式忽略这些)是 API 合约。可观察但未由 javadoc 定义的行为通常应被视为实现细节,该细节可能在未来版本中发生更改。

因此,如果在 javadoc 中找不到它,则无法保证。

未指定流管道阶段的调用和交错顺序。所规定的是在什么情况下所谓的遭遇顺序流被保留。假设有序流,仍然允许实现执行任何交错、批处理和内部重新排序,以保留遇到顺序。例如。 Asorted(comparator).filter(predicate).findFirst()可以在内部替换为filter(predicate).min(comparator)这当然会显着影响谓词和比较器的调用方式,但会产生相同的结果,即使在有序流中也是如此。

这是否意味着我们不能保证我们的处理顺序将符合我们对 Java 未来版本的预期?可能是。

是的,这应该不是问题,因为大多数流 API要求回调是无国籍的 and 无副作用,这意味着他们不应该关心流管道的内部执行顺序,并且结果应该是相同的,以无序流授予的余地为模。

明确的要求和缺乏保证为 JDK 开发人员提供了如何实现流的灵活性。

如果您考虑到任何特定情况,这很重要,您应该提出一个更具体的问题,关于您想要避免的执行重新排序。


您应该始终记住流可以是并行的,例如由第 3 方代码传递的实例,或包含源或中间流操作,该操作比理论上的惰性要少(目前flatMap就是这样的操作)。如果有人提取并重新包装分割器或使用自定义实现,流管道还可以包含自定义行为Stream 界面.

因此,虽然特定的流实现可能会在您以特定方式使用它们时表现出一些可预测的行为,并且该特定情况的未来优化可能被认为极不可能,但这并不能推广到所有可能的流管道,因此 API 无法提供此类一般保证。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java流操作在终点的执行顺序[重复] 的相关文章

随机推荐

  • 使用 C# 查询、过滤和更新 MongoDB 中的多级嵌套数组

    我有这个 MongoDB 文档 我正在开发一个 MVC 应用程序并尝试使用 C 更新注释数组 注释描述为 更新后注释 我正在使用新的 mongodb 版本 ProjectID 1 ProjectName Project test Proje
  • 创建缩略图,然后转换为字节数组

    我在创建缩略图然后将它们转换为字节数组方面遇到了很大的麻烦 我尝试了三种方法 3次都出错了 第一个是使用 Bitmap GetThumbnailImage 我过去使用过它 然后直接保存到 Response OutputStream 中 第二
  • 具有自定义逻辑的 Java 8 Stream groupingBy

    我有一个清单Records 其中有两个字段 LocalDateTime instant and a Double data 我想按小时对所有记录进行分组并创建一个Map
  • Java中的协议缓冲区“ParseFromString”用于解析文本格式?

    Is ParseFromStringJava 中的协议缓冲区可用吗 C 版本有 here 留言A 方法TextFormat getParser merge str builder 可以 例如 AOuterClass A Builder bu
  • 如何在phpmyadmin中使用“中心列”?

    PMA 具有用于添加中心列的工具 据我了解 它是在国外的限制下使用的 我有两张桌子 TableA and TableB 结构TableA id of A name of A value 结构TableB id of B foreign id
  • 如何在 PySpark 中展平嵌套列表?

    我有一个 RDD 结构 例如 rdd 1 2 3 4 5 6 7 8 9 10 我希望它变成 rdd 1 2 3 4 5 6 7 8 9 10 如何编写映射或归约函数才能使其正常工作 例如你可以flatMap并使用列表理解 rdd flat
  • 中断异常的原因

    从 J2me 文档我们知道 java lang InterruptedException 当线程正在等待 睡眠或以其他方式暂停很长时间并且另一个线程中断它时抛出 问题是 如果我从一个线程为其他线程调用 Thread Interupt 而其他
  • 图形中的边交叉减少

    是否有任何算法可以最小化图中的边交叉 例如 如果我有图形的转换矩阵 我找到了一些方法 例如尝试将节点放置在另一个节点周围 但我想知道一些其他想法 有一系列为图形绘制应用程序开发的成熟算法 库 您可以获得一些背景知识here 要绘制无向图 一
  • WebDriver 和 C# - NoSuchElement 异常

    我有以下代码用于从给定列表中选择一个选项 它通常可以工作 但有时会失败 并在第二个 if 上出现 NoSuchElement 异常 我的印象是 如果它没有找到该元素 它就会再次返回到循环 我相信解释很简单 有人能启发我吗 public st
  • Git 工作流程以及 rebase 与合并问题

    我和另一位开发人员在一个项目中使用 Git 已有几个月了 我有多年的经验SVN 所以我想我给这段关系带来了很多包袱 我听说 Git 非常适合分支和合并 但到目前为止 我只是没有看到它 当然 分支非常简单 但是当我尝试合并时 一切都变得一团糟
  • clang-format 堆叠所有 if 语句参数(如果它们太长)

    我有一个if声明有几个or编辑的论点 为了便于阅读 我将它们垂直堆叠如下 if health flag a health flag b health flag c health flag d health flag e health fla
  • python-docx 中的运行级别内容是什么?

    我对 python docx 中 运行级别内容 的概念有点困惑 我知道如果我想检查段落是否为粗体 我需要检查 run bold 但到底是什么它 官方的定义是 run是与内联内容关联最密切的对象 在段落内的块项目边界之间流动的文本 图片和其他
  • 如何在发布模式下为 .net 托管项目生成 PDB?

    我知道 PDB 是为managed通过为编译器提供 debug 参数来在 NET 中进行项目 有没有办法在 VS 2005 GUI 中指定这一点 到目前为止 我可以让它在发布模式下生成 PDB 的唯一方法是手动修改 csproj 文件并添加
  • 具有多个“操作”的 HTML 表单

    我正在设置一个表单 其中我需要两个 操作 两个按钮 1 提交此表格以供批准 2 保存此应用程序供以后使用 如何创建支持多个 操作 的 HTML 表单 EG
  • Git克隆:远程端意外挂起,尝试更改postBuffer但仍然失败

    我正在尝试克隆存储库 第一次我到了82 然后半个小时没动 所以我取消了克隆并重新开始 此后 每次我尝试克隆它时 都会得到 6 10 之间的结果 然后失败并出现错误 远程端意外挂起 早期 EOF 我查找了错误并尝试了我能找到的所有解决方案 最
  • Python 扫描 WiFi

    我正在寻找一个可以扫描 WiFi 网络并打印所有 SSID 的程序 我尝试使用 scapy 但失败了 我正在使用 pyCharm 编辑器 我尝试了这段代码 from scapy all import from scapy layers do
  • Peterson 的算法能满足饥饿问题吗?

    我一直在搜索有关的信息彼得森算法但遇到的参考资料表明它不能解决饥饿问题 而只能解决僵局 这是真的 如果是这样 有人可以详细说明为什么不吗 彼得森算法 flag 0 0 flag 1 0 turn P0 flag 0 1 turn 1 whi
  • SVG 线性渐变 objectBoundingBox 与 userSpaceOnUse

    我正在制作两个渐变 一个以 objectBoundingBox 为单位 另一个以 userSpaceOnUse 为单位 这个想法是让它们看起来一样 但不知怎的 他们是不同的 这是 svg 文件
  • C# 中相当于 PHP 的“self::”的是什么?

    在 C 中 当我想从该类的另一个静态方法调用该类的静态方法时 是否有一个通用前缀我可以使用 PHP 等self 而不是类名 所以在下面的例子中 而不是说Customer DatabaseConnectionExists 我该怎么说Self
  • Java流操作在终点的执行顺序[重复]

    这个问题在这里已经有答案了 我一直试图从官方 Java 文档中找到关于 Java 流的明确约定 一旦调用终端操作 处理元素并调用中间操作 例如 让我们看一下这些同时使用 Java 流版本和普通迭代版本的示例 两者产生相同的结果 示例1 Li