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

2022-09-01 12:23:21

并且它们都获得一个 Consumer 作为参数。那么,如果Java 8旨在避免混淆,就像它在Time API中所做的那样,为什么它增加了新的混淆呢?还是我错过了一些要点?


答案 1

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

一个基本上是具有“下一个元素”的东西,通常是结束。Iterator

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

现在您已经了解了这一点,我可以谈谈所讨论的两种方法之间的区别。

让我们使用数组列表作为示例。这是数组列表中的内容:

[1, 3, 6, 8, 0]

现在如果我打电话并传入,将被打印出来。这是因为循环访问整个元素序列。Iterable.forEach()System.out::print()13680Iterable.forEach

另一方面,如果我得到数组列表并调用两次,在调用之前,将打印。已经迭代了前两个元素,因此“剩余”元素是 6、8 和 0。IteratornextforEachRemainingSystem.out::print()680Iterator


答案 2

简单来说,forEachRemaining()是迭代器的改进版本,在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));

现在,JDK8 forEach() 是带有 lamda 表达式的改进版 JDK7。