【问题标题】:Java 8 internal iterationJava 8 内部迭代
【发布时间】:2014-01-23 16:10:57
【问题描述】:

是否只使用CollectionforEach 方法执行内部迭代? 对象或也可以使用Stream 的方法,如filterreduce 等?

【问题讨论】:

  • 这和your previous question有区别吗?
  • 是的,我想知道像 sum 这样的方法是否也使用内部迭代。
  • sum 是一个终端操作,所以是的,它确实会迭代...如果您真的对流 api 的内部结构感兴趣,您应该检查代码...
  • @assylias,哪里可以看到sum的实现代码?
  • 下载jdk 8(自带源码),使用sum编写代码,在debug模式下运行,进入方法。

标签: java java-8


【解决方案1】:

从根本上说,要对集合的所有成员进行操作,需要对其进行迭代。

它执行的确切方式可能会根据收集和操作而改变,但它需要发生的事实是不可避免的。

【讨论】:

  • +1 ArrayList 可以避免创建Iterator,但它仍然会遍历元素。
  • 这并没有回答迭代是内部还是外部的问题。
  • @LouisWasserman 从来没有问过这个问题。问题是它是否只为 forEach 执行,或者它是否也在其他人上执行 - 答案是过滤/减少之类的事情需要某种形式的迭代......
  • @TimB:在问题的 cmets 中,OP 询问“我想知道诸如 sum 之类的方法是否也使用内部迭代”,这在我看来仍然像他在问内部迭代与外部迭代。我已经删除了反对票,但我仍然认为你误解了这个问题。
  • 啊,那条评论是在我回复后添加的。
【解决方案2】:

也许您应该首先定义您所理解的术语“外部迭代”。由于在调用 filtermapreduce 时不会编写循环,因此根据定义,它不是外部迭代。

您可以尝试改变您的观点并查看filtermapreduce 方法的内部。但在尝试理解概念时,查看实现不一定有用。

在执行filtermapreduce 时,您正在根据PredicateFunctionBiFunctionBinaryOperator 定义一个操作。而且它们都不会使用Iterator 实现循环,因此它仍然不是外部循环。

您似乎想知道迭代代码是在 Collection 类内还是在 Stream 类内,但这是一个不重要的实现细节,因为它们是同一库/框架的一部分,因此是迭代在任何一种情况下,都将被视为关于此库/框架的“内部”。

即使是第三个选项,有另一方,Spliterator 执行循环也不会改变迭代的性质。这是典型的内部迭代,乍一看你无法看到迭代实际发生在哪里。

【讨论】:

    【解决方案3】:

    流操作基于Spliterators 之上,这是内部和外部迭代之间某种奇怪的混合。 Spliterator 是集合的 spliterator() 方法返回的外部对象,但 Spliterator 本身接受回调以将方法传递给,就像内部迭代一样。

    例如,collection.stream().forEach(consumer) 将(基本上)等价于collection.spliterator().forEachRemaining(consumer),或者它可以像这样使用

    Spliterator<T> spliterator = collection.spliterator();
    while (spliterator.tryAdvance(consumer)) {
       // do something
    }
    

    【讨论】:

      【解决方案4】:

      @Tim B 指出存在内部迭代,但并非始终处理所有项目。当您链接多个操作以避免不必要的计算时,会出现过滤和短路。

      参考here

      【讨论】:

        猜你喜欢
        • 2016-02-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-09
        • 1970-01-01
        • 2019-02-04
        相关资源
        最近更新 更多