Ways to Iterate Over a List in Java – 在Java中对列表进行迭代的方法

最后修改: 2018年 11月 30日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.绪论

Iterating over the elements of a list is one of the most common tasks in a program.

迭代一个列表的元素是程序中最常见的任务之一。

In this tutorial, we’ll review the different ways to do this in Java. We’ll focus on iterating through the list in order, though going in reverse is simple, too.

在本教程中,我们将回顾在 Java 中实现这一目的的不同方法。我们将重点讨论按顺序迭代列表的问题,不过反向迭代也很简单。

2. for Loop

2.for 循环

First, let’s review some for loop options.

首先,让我们回顾一下一些for循环选项。

We’ll begin by defining a list of countries for our examples:

我们将首先为我们的例子定义一个国家清单。

List<String> countries = Arrays.asList("Germany", "Panama", "Australia");

2.1. Basic for Loop

2.1.基本for循环

The most common flow control statement for iteration is the basic for loop.

迭代最常见的流程控制语句是基本的for循环。

The for loop defines three types of statements separated with semicolons. The first statement is the initialization statement. The second one defines the termination condition. The last statement is the update clause.

for循环定义了三种用分号分隔的语句。第一条语句是初始化语句。第二条定义了终止条件。最后一条语句是更新条款。

Here we’re simply using an integer variable as an index:

这里我们只是用一个整数变量作为索引。

for (int i = 0; i < countries.size(); i++) {
    System.out.println(countries.get(i));
}

In the initialization, we must declare an integer variable to specify the starting point. This variable typically acts as the list index.

在初始化过程中,我们必须声明一个整数变量来指定起点。这个变量通常作为列表的索引。

The termination condition is an expression that returns a boolean after evaluation. Once this expression evaluates to false, the loop finishes.

终止条件是一个表达式,评估后返回一个布尔值。一旦这个表达式评估为false,循环就结束了。

The update clause is used to modify the current state of the index variable, increasing it or decreasing it until the point of termination.

更新子句用于修改索引变量的当前状态,增加或减少它,直到终止点。

2.2. Enhanced for Loop

2.2.增强的for循环

The enhanced for loop is a simple structure that allows us to visit every element of a list. It’s similar to the basic for loop, but more readable and compact. Consequently, it’s one of the most commonly used forms to traverse a list.

增强的 for 循环是一个简单的结构,它允许我们访问列表中的每个元素。它类似于基本的 for 循环,但更易读和紧凑。因此,它是最常用的遍历列表的形式之一。

Notice that the enhanced for loop is simpler than the basic for loop:

注意,增强的for循环比基本的for循环更简单。

for (String country : countries) {
    System.out.println(country); 
}

3. Iterators

3.迭代器

An Iterator is a design pattern that offers us a standard interface to traverse a data structure without having to worry about the internal representation.

Iterator是一种设计模式,它为我们提供了一个标准的接口来遍历一个数据结构,而不必担心内部表示。

This way of traversing data structures offers many advantages, among which we can emphasize that our code doesn’t depend on the implementation.

这种遍历数据结构的方式有很多优点,其中我们可以强调的是,我们的代码并不依赖于实现。

Therefore, the structure can be a binary tree or a doubly linked list, since the Iterator abstracts us from the way of performing the traversal. In this way, we can easily replace data structures in our code without unpleasant problems.

因此,该结构可以是二叉树或双链表,因为Iterator将我们从执行遍历的方式中抽象出来。通过这种方式,我们可以轻松地在代码中替换数据结构,而不会出现令人不快的问题。

3.1. Iterator

3.1. 迭代器

In Java, the Iterator pattern is reflected in the java.util.Iterator class. It’s widely used in Java Collections. There are two key methods in an Iterator, the hasNext() and next() methods.

在Java中,Iterator模式体现在java.util.Iterator类中。它在Java的Collections中被广泛使用。在Iterator中,有两个关键方法:hasNext()next()方法。

Here we’ll demonstrate the use of both:

这里我们将演示这两种方法的使用。

Iterator<String> countriesIterator = countries.iterator();

while(countriesIterator.hasNext()) {
    System.out.println(countriesIterator.next()); 
}

The hasNext() method checks if there are any elements remaining in the list.

hasNext()方法检查列表中是否还有任何元素

The next() method returns the next element in the iteration.

next()方法返回迭代的下一个元素

3.2. ListIterator

3.2.ListIterator

A ListIterator allows us to traverse a list of elements in either forward or backward order.

一个ListIterator允许我们以向前或向后的顺序遍历一个元素的列表。

Scrolling a list with ListIterator forward follows a mechanism similar to that used by the Iterator. In this way, we can move the iterator forward with the next() method, and we can find the end of the list using the hasNext() method.

ListIterator向前滚动列表,遵循与Iterator类似的机制。这样,我们可以用next()方法将迭代器向前移动,我们可以用hasNext()方法找到列表的末端。

As we can see, the ListIterator looks very similar to the Iterator that we used previously:

我们可以看到,ListIterator看起来与我们之前使用的Iterator非常相似。

ListIterator<String> listIterator = countries.listIterator();

while(listIterator.hasNext()) {
    System.out.println(listIterator.next());
}

4. forEach()

4.forEach()

4.1. Iterable.forEach()

4.1.Iterable.forEach()

Since Java 8, we can use the forEach() method to iterate over the elements of a list.  This method is defined in the Iterable interface, and can accept Lambda expressions as a parameter.

自 Java 8 起,我们可以使用 forEach() 方法来遍历列表中的元素。 这个方法定义在Iterable接口中,并且可以接受Lambda表达式作为参数。

The syntax is pretty simple:

语法相当简单。

countries.forEach(System.out::println);

Before the forEach function, all iterators in Java were active, meaning they involved a for or while loop that traversed the data collection until a certain condition was met.

forEach函数之前,Java中的所有迭代器都是活动的,这意味着它们涉及一个for或while循环,该循环遍历数据集合,直到满足某个条件。

With the introduction of forEach as a function in the Iterable interface, all classes that implement Iterable have the forEach function added.

随着forEach作为Iterable接口中的一个函数的引入,所有实现Iterable的类都增加了forEach函数。

4.2. Stream.forEach()

4.2. Stream.forEach()

We can also convert a collection of values to a Stream, and have access to operations such as forEach()map(), and filter().

我们还可以将一个值的集合转换为一个流,并可以访问诸如forEach()map()filter()等操作。

Here we’ll demonstrate a typical use for streams:

这里我们将演示流的一个典型用途。

countries.stream().forEach((c) -> System.out.println(c));

5. Conclusion

5.总结

In this article, we demonstrated the different ways to iterate over the elements of a list using the Java API. These options included the for loop, enhanced for loop, Iterator, ListIterator, and the forEach() method (included in Java 8).

在这篇文章中,我们演示了使用 Java API 迭代列表中的元素的不同方法。这些方法包括for循环、增强的for循环、IteratorListIteratorforEach()方法(包含在Java 8中)。

Then we learned how to use the forEach() method with Streams.

然后我们学习了如何使用forEach()方法与Streams

Finally, all the code used in this article is available in our Github repo.

最后,本文中使用的所有代码都可以在我们的Github repo中找到。