同时拥有 Iterator.forEachRemaining() 和 Iterable.forEach() 有什么意义?

what's the point of having both Iterator.forEachRemaining() and Iterable.forEach()?

并且他们都得到一个消费者作为参数。所以如果 Java 8, 是为了避免混淆,就像它在 Time API 中所做的那样,为什么它增加了一个新的混淆?还是我漏掉了什么?

要理解为什么这两种方法都存在,你需要先了解什么是IteratorIterable

一个 Iterator 基本上是有一个 "next element" 并且通常有一个结束的东西。

Iterable 是包含有限或无限序列中的元素的东西,因此可以通过不断获取下一个元素来迭代。换句话说,Iterables 可以被 Iterators 迭代。

既然你明白了这一点,我可以谈谈这两种方法之间的区别。

我们以数组列表为例。这是数组列表中的内容:

[1, 3, 6, 8, 0]

现在,如果我调用 Iterable.forEach() 并传入 System.out::print(),将打印 13680。这是因为 Iterable.forEach 遍历了整个元素序列。

另一方面,如果我得到数组列表的 Iterator 并调用 next 两次,在用 System.out::print() 调用 forEachRemaining 之前,680 将被打印。 Iterator 已经遍历了前两个元素,所以 "remaining" 是 6、8 和 0。

简而言之,forEachRemaining()是Iterator的改进版,在JDK8之前我们使用hasNext(),next()遍历任意集合(ArrayList,HastSet等)

JDK8 之前

List<String> fruits= new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Grapes");
fruits.add("Orange");
Iterator<String> iterator = fruits.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

现在在 JDK8 中,如果我们想要遍历任何集合,我们可以这样做:

JDK8之后:

List<String> fruits=new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Grapes");
fruits.add("Orange");

Iterator<String> iterator = fruits.iterator();
iterator.forEachRemaining((fruit) -> System.out.println(fruit));

Now, JDK8 forEach() is improved version JDK7 with lamda expression.

只是为 Scala 和 Kotlin 用户总结:在 Java 中,IteratorforEach 被称为 forEachRemaining(而 Iterable 有一个 forEach 方法).