gpt4 book ai didi

lambda - 为什么 java 8 引入了 iterable.forEach() 循环,即使它有每个循环?

转载 作者:行者123 更新时间:2023-12-04 22:18:11 26 4
gpt4 key购买 nike

我无法理解为什么 java 8 有 forEach 循环并将消费者功能接口(interface)作为参数。即使我们可以使用传统的 for each 循环来完成相同的任务,而不会产生任何额外的开销来创建一个从 Consumer 实现的类并实现一个方法,然后将其作为引用传递给 forEach()。虽然有 lambda 表达式使它变短。

Q1-为什么是 iterable.forEach()?

Q2。在哪里使用它?

Q3。对于 Java 8 forEach() 中的每一个,哪一个更快?

样本:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;
import java.lang.Integer;

public class ForEachExample {

public static void main(String[] args) {

//creating sample Collection
List<Integer> myList = new ArrayList<Integer>();
for(int i=0; i<10; i++) myList.add(i);

//traversing using Iterator
Iterator<Integer> it = myList.iterator();
while(it.hasNext()){
Integer i = it.next();
System.out.println("Iterator Value::"+i);
}

//traversing through forEach method of Iterable with anonymous class
myList.forEach(new Consumer<Integer>() {

public void accept(Integer t) {
System.out.println("forEach anonymous class Value::"+t);
}

});

//traversing with Consumer interface implementation
MyConsumer action = new MyConsumer();
myList.forEach(action);

}

}

//Consumer implementation that can be reused
**class MyConsumer implements Consumer<Integer>{
public void accept(Integer t) {
System.out.println("Consumer impl Value::"+t);
}
}**

最佳答案

受函数式编程启发的新 API 的总体思想是表达要做什么而不是如何去做。即使使用简化的 for-each 循环,

for(Integer i: myList) System.out.println("Value::"+i);

它只是“获取 Iterator”指令的语法糖。实例和反复调用 hasNext()next()在上面”。

相反,当使用
myList.forEach(i -> System.out.println("Value::"+i));

你提供了一个 Action ,应用于每个元素,但没有指定如何做。 default实现将只执行 Iterator基于循环,但实际 Iterable实现可能会覆盖它以不同方式执行操作。

注意很多 Iterator实现会执行两次检查,一次在 hasNext() ,然后在 next()因为不能保证调用者做了 hasNext()首先,抛出一个 NoSuchElementException如果没有下一个元素。有时这甚至意味着在 Iterator 中持有额外的状态。实例来记住是否已经执行了特定的“fetch-next”操作。专属 forEach实现可以更直接、更高效,同时代码更简单。

例如, ArrayList执行 int -基于索引的循环,不构造 Iterator例如, Collections.emptyList()除了检查 Consumer 什么都不做反对 null , TreeSet分别它的后盾 TreeMap遍历入口链接,比它的 Iterator简单多了必须支持 remove 的实现操作等等。

是否专用 forEach实现可能会补偿 Consumer与构造相关的开销,如果有的话(请注意 not every lambda expression creates a new object),是不可预测的,并且对此的假设不应驱动软件设计。通常,性能差异可以忽略不计。

但也可能存在语义差异。当使用 Collections.synchronized… 返回的集合之一时, 一个 Iterator当底层集合被另一个线程修改时,基于循环不能提供一致性保证。应用程序需要手动锁定集合,并且必须注意使用正确的对象实例,例如如果迭代是 subList subSet .相比之下,专门的 forEach(Consumer)在整个操作期间正确锁定,而操作本身就像委托(delegate)给源的 forEach 一样简单方法,仍然根据实际的底层集合以最佳方式执行它。

关于lambda - 为什么 java 8 引入了 iterable.forEach() 循环,即使它有每个循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51016229/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com