一、简介
迭代元素是我们可以在集合上执行的最基本的操作之一。
在本教程中,我们将了解如何迭代 Set 的元素以及它与 List 或数组上的类似任务有何不同。
2. 访问集合中的元素
与 列表 和许多其他集合不同, 集合 不是连续的。它们的元素没有索引,并且根据实现的不同,它们可能无法维持顺序。
这意味着我们不能通过编号来询问集合中的特定元素。因此,我们不能使用典型的 for 循环或任何其他基于索引的方法。
2.1. 迭代器
迭代集合的最基本且最接近金属的方法是调用每个 Set 公开的 迭代器 方法:
Set<String> names = Sets.newHashSet("Tom", "Jane", "Karen");
Iterator<String> namesIterator = names.iterator();
然后我们可以使用获得的 迭代器 来一一获取该 Set 的元素 。最具标志性的方法是检查 迭代器 在 while 循环中是否有下一个元素:
while(namesIterator.hasNext()) {
System.out.println(namesIterator.next());
}
我们还可以使用Java 8中添加的 forEachRemaining 方法:
namesIterator.forEachRemaining(System.out::println);
我们还可以混合使用这些解决方案:
String firstName = namesIterator.next(); // save first name to variable
namesIterator.forEachRemaining(System.out::println); // print rest of the names
所有其他方法都将在幕后以某种方式使用 迭代器 。
3. 流
每个 Set 都公开 spliterator() 方法。因此, Set* 可以轻松转换为 *Stream :
names.stream().forEach(System.out::println);
我们还可以利用丰富的 Streams API来创建更复杂的管道。例如,让我们映射、记录集合中的元素,然后将其缩减为单个字符串:
String namesJoined = names.stream()
.map(String::toUpperCase)
.peek(System.out::println)
.collect(Collectors.joining());
4. 增强循环
虽然我们不能使用简单的索引 for 循环来迭代 Set ,但我们可以使用 Java 5 中引入的增强循环功能:
for (String name : names) {
System.out.println(name);
}
5. 用索引迭代
5.1.转换为数组
Set 没有索引,但我们可以人为地添加索引。一种可能的解决方案是简单地 将 Set 转换为一些更易于访问的数据结构,例如数组 :
Object[] namesArray = names.toArray();
for (int i = 0; i < namesArray.length; i++) {
System.out.println(i + ": " + namesArray[i]);
}
请注意,单独转换为数组将迭代 Set 一次。因此,就复杂性而言,我们将迭代 Set 两次。如果性能至关重要,这可能是一个问题。
5.2.带索引的压缩
另一种方法是创建一个索引并使用我们的 Set 对其进行压缩。虽然我们可以使用普通 Java 来完成此操作,但有一些库专门为此提供了工具。
例如,我们可以使用Vavr的流:
Stream.ofAll(names)
.zipWithIndex()
.forEach(t -> System.out.println(t._2() + ": " + t._1()));
六、总结
在本教程中,我们了解了迭代 Set 实例的元素的各种方法。我们探讨了迭代器、流和循环的用法以及它们之间的差异。
与往常一样,示例可以在 GitHub 上找到。