1. Introduction
1.绪论
Iterating over elements is one of the most fundamental operations we can execute on a collection.
对元素进行迭代是我们可以在一个集合上执行的最基本的操作之一。
In this tutorial, we’ll take a look at how to iterate over elements of a Set and how it differs from the similar tasks on a List or array.
在本教程中,我们将看看如何迭代Set中的元素,以及它与List或数组的类似任务有何不同。
2. Getting Access to Elements in a Set
2.获得对一个集合中的元素的访问
A Set, unlike a List and many other collections, isn’t sequential. Their elements aren’t indexed, and depending on the implementation, they may not maintain order.
与List和许多其它集合不同,Set并不具有顺序性。它们的元素没有索引,而且根据不同的实现,它们可能不会保持顺序。
That means that we can’t ask about a specific element of the set by its number. Because of that, we can’t use a typical for loop or any other index-based method.
这意味着我们不能通过编号来询问集合中的某个特定元素。正因为如此,我们不能使用典型的for循环或任何其他基于索引的方法。
2.1. Iterator
2.1. 迭代器
The most basic and close-to-metal method of iterating over the set is invoking the iterator method exposed by every Set:
对集合进行迭代的最基本和最接近于金属的方法是调用每个Set暴露的iterator方法。
Set<String> names = Sets.newHashSet("Tom", "Jane", "Karen");
Iterator<String> namesIterator = names.iterator();
Then we can use the obtained iterator to get elements of that Set, one by one. The most iconic way is checking if the iterator has a next element in the while loop:
然后我们可以使用获得的iterator来逐一获得该Set中的元素。最具代表性的方法是检查iterator在while循环中是否有下一个元素。
while(namesIterator.hasNext()) {
System.out.println(namesIterator.next());
}
We can also use the forEachRemaining method added in Java 8:
我们还可以使用Java 8中添加的forEachRemaining方法。
namesIterator.forEachRemaining(System.out::println);
We can also mix these solutions:
我们还可以混合这些解决方案。
String firstName = namesIterator.next(); // save first name to variable
namesIterator.forEachRemaining(System.out::println); // print rest of the names
All other methods will use an Iterator in some way under the hood.
所有其他方法都会以某种方式使用Iterator。
3. Streams
3.水流s
Every Set exposes the spliterator() method. Because of that, a Set can be easily transformed into a Stream:
每个Set都暴露了spliterator()方法。正因为如此,一个Set可以很容易地转变为Stream。
names.stream().forEach(System.out::println);
We can also leverage the rich Streams API to create more complex pipelines. For example, let’s map, log, and then reduce elements of the set to a single string:
我们还可以利用丰富的Streams API来创建更复杂的管道。例如,让我们映射、记录,然后将集合中的元素还原成一个字符串。
String namesJoined = names.stream()
.map(String::toUpperCase)
.peek(System.out::println)
.collect(Collectors.joining());
4. Enhanced Loop
4.强化环路
While we can’t use a simple, indexed for loop to iterate over a Set, we can use the enhanced loop feature introduced in Java 5:
虽然我们不能使用简单的、有索引的for循环来迭代Set,但我们可以使用Java 5中引入的增强循环功能。
for (String name : names) {
System.out.println(name);
}
5. Iterating with Index
5.用指数进行迭代
5.1. Converting to Array
5.1.转换为数组
Sets aren’t indexed, but we can add an index artificially. One possible solution is to simply convert the Set to some more approachable data structure like an array:
Sets没有索引,但是我们可以人为地添加一个索引。一个可能的解决方案是简单地将Set转换为一些更容易接近的数据结构,如数组。
Object[] namesArray = names.toArray();
for (int i = 0; i < namesArray.length; i++) {
System.out.println(i + ": " + namesArray[i]);
}
Mind that conversion to an array alone will iterate over the Set once. So, in terms of complexity, we’ll be iterating over the Set twice. That may be a problem if performance is crucial.
请注意,仅转换为数组就会对Set进行一次迭代。因此,就复杂性而言,我们将在Set上迭代两次。如果性能很重要的话,这可能是个问题。
5.2. Zipping with Index
5.2.带索引的拉链
Another approach is to create an index and zip it with our Set. While we could do it in vanilla Java, there are libraries that provide tools just for that.
另一种方法是创建一个索引,并将其与我们的Set一起压缩。虽然我们可以在vanilla Java中做到这一点,但有一些库专门为此提供了工具。
For example, we can use Vavr’s streams:
例如,我们可以使用Vavr的流。
Stream.ofAll(names)
.zipWithIndex()
.forEach(t -> System.out.println(t._2() + ": " + t._1()));
6. Summary
6.归纳总结
In this tutorial, we looked at various ways of iterating over elements of the Set instance. We explored the usage of iterators, streams, and loops, and the differences between them.
在本教程中,我们研究了对Set实例中的元素进行迭代的各种方法。我们探讨了迭代器、流和循环的用法,以及它们之间的区别。
As always, examples are available over GitHub.
像往常一样,在GitHub上可以找到实例。