java - 流内部如何处理数据?

标签 java java-8 java-stream

如果我在流上执行多个操作,它们是如何在内部计算的。

  1. 它的计算顺序是否与输入集合的顺序相同?
  2. 它是否将函数应用于所有元素,然后移动以评估下一个函数?或者它将所有功能应用于一个元素,然后是第二个元素……依此类推。
  3. 在性能方面,它与对集合执行的正常迭代有何不同。

    List<Integer> ee = new ArrayList<Integer>();
    Function<? super Integer, ? extends Integer> f1 = x -> x * 2;
    Function<? super Integer, ? extends Integer> f2 = x -> x * x;
    Function<? super Integer, ? extends Integer> f3 = x -> x / 2;
    ee.stream().map(f1.compose(f2.andThen(f3))).collect(Collectors.toList());

    ee.stream().map(f1).map(f2).map(f3).collect(Collectors.toList());

在问题中编辑以添加多个 map 操作。在多个映射函数应用程序的情况下如何计算映射函数。在谈论非并行流时,元素的计算顺序是否仅取决于输入集合的类型(即,有序列表、linkedHashmap、sortedset 和 hashSet 无序等)。另外,我能否对流的内部工作有更多的了解,以便更好地决定什么时候不建议使用流,什么时候建议使用最多。(集合大小、序列性质等,)

最佳答案

订单

  1. Is it computed in the same sequence as that of the input collection?

没有必要。有很多东西可以决定顺序。在流本身上,有 unordered()parallel() 影响它。然后,您还可以通过终端操作来影响它,例如 forEach vs forEachOrdered()。对于 collect,它取决于您要收集到的底层 Collection。对于 toList(),它会按照您的流当前服务的顺序收集它们。因此,如果您没有调用 unordered() 或其他任何方法,它将被排序。

来自official documentation :

Returns a Collector which collects all the input elements into a List, in encounter order.


Action 流水线

  1. Does it apply function to all the elements and then moves to evaluate the next function ? or it applies all functions on one element , then second element ... so on.

只要您不应用终端操作,例如collect,就不会发生任何事情。它会记住您的操作并创建一个操作管道。一旦开始,通过 collect,它将一个接一个地迭代所有项目,并将完整的操作管道应用于它。因此它将采用一个元素并将所有函数应用于它,然后将其填充到结果列表中,然后继续下一个元素。

但是,在您的特定情况下,您只有一个 map(...) 操作。因此,您没有告诉流应用 3 个函数,而是使用函数中的方法将 3 个函数组合成一个大函数,并将该单个函数提供给流。所以流只有一个函数可以使用,它在应用时一个接一个地执行所有 3 个操作。通常人们会使用多个 map(...) 调用:

ee.stream()
    .map(f1)
    .map(f2)
    .map(f3)
    .collect(Collectors.toList());

性能

  1. How is it any different from normal iterations performed on collection in respect of performance.

一般来说,有更多的逻辑附加到流。您需要构建一些对象,创建一些操作管道等。因此它会引入一些开销,但并不严重。因此,只要您没有微小的迷你数据集并且您需要每一纳秒,就认为它与普通迭代一样好。

虽然有几个优点。一个是可读性(当然不总是)。另一个突出的优势是 Stream API 免费提供多线程。您只需调用 parallel() 来建议用法,如果 Java 认为这是个好主意,它将同时开始处理多个元素。

请记住,多线程会带来很大的开销。因此,如果您的数据源不大,总体上可能会比较慢。

关于java - 流内部如何处理数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58813659/

相关文章:

java - 用另一个流中的字符串替换一个流中的字符串

java - 如何在 Java 中使用 for 循环从类创建新对象?

java - 我在 Windows 中输入 mvn 命令,但命令行返回一个 java 提示

java - 每个线程使用唯一 ID 并释放它以供重用

java - 在 Java 8 中计算两个日期之间的天数

java - 使用 Java 流打印列表项

java - 如何在BIRT中将字符串拆分为字符数组?

java - java中功能接口(interface)实例的相等性

java - 如何在 Java 8 的 map 中展平列表

java - 应用比较器和谓词的顺序重要吗?