1. 集合的遍历
1.0 创建集合代码
List<String> strList = new ArrayList<>();
strList.add("huawei");
strList.add("xiaomi");
strList.add("tencent");
strList.add("google");
strList.add("baidu");
1.1 for 循环
在性能要求不高的情况下,使用普通的 for 循环遍历集合是一种简单方便的选择。我们也可以使用增强 for 循环(也称为 for each 循环) 来遍历集合,但这种方式通常比普通的 for 循环慢一些
// 最基本的 for 循环
for (int i = 0;i < strList.size();i++) {
System.out.print(strList.get(i) + " ");
}
1.2 使用迭代器遍历
当我们需要在遍历集合的同时对其进行修改时,使用迭代器是一个不错的选择。迭代器可以让我们在遍历集合的同时删除或添加元素,而不需要了解底层实现细节。
// 迭代器(Iterator)遍历
Iterator<String> iterator = strList.iterator();
while(iterator.hasNext()){
System.out.print(iterator.next() + " ");
}
与 for each 循环相比,使用 iterator 的方式更加灵活,因为它允许手动控制迭代过程,例如在迭代过程中修改集合、跳过元素或在多个集合之间进行迭代。比如下面样例在迭代过程中修改集合:
注意:使用 for-each 循环时不能在循环内修改集合,否则会抛出java.lang.UnsupportedOperationException 异常。
// 迭代器(Iterator)遍历
Iterator<String> iterator = strList.iterator();
while(iterator.hasNext()){
String it = iterator.next();
if (it.equals("google")) {
iterator.remove();
}
}
strList.forEach(str->{
System.out.print(str + " ");
});
1.3 使用 for each 循环(增强 for 循环)遍历
// 增强 for 循环(也称为 for each 循环)
for (String str : stringList) {
System.out.println(str);
}
// Java8 对 for each 的简化 1
stringList.forEach(str->{
System.out.println(str);
});
// Java8 对 for each 的简化 2
stringList.forEach(System.out::println);
for each 循环本质上是使用了迭代器模式,它将选代器的实现细节隐藏在了语法层面。当使用 for-each 循环遍历集合时,编译器会将其转换为使用迭代器的方式。比如上面代码会被编译器转换为类似于以下代码,在底层实现上,for-each 循环和使用 iterator 的方式是等价的:
// 迭代器(Iterator)遍历
Iterator<String> iterator = stringList.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
1.4 使用 Stream API 的 forEach 方法遍历
Stream API 的 forEach 方法出了可以遍历集合的,还可以用来遍历任何支持流的对象,包括集合、数组、文件、函数生成器等。
// 使用 Stream API 的 forEach 方法遍历 1
stringList.stream().forEach(str->{
System.out.println(str);
});
// 使用 Stream API 的 forEach 方法遍历 2
stringList.stream().forEach(System.out::println);
1.5 使用 ListIterator 接口遍历集合
如果我们需要在遍历 List 集合的同时进行改动,并且希望能够在遍历过程中向前或向后移动遍历位置,那么使用 Listlterator 就是一个不错的选择。
Listlterator 是 iterator 接口的子接口。Listlterator 可以向前或向后遍历列表中的元素,并允许在列表中插入、替换和删除元素。
// 从前向后遍历集合中所有元素
ListIterator<String> iterator = stringList.listIterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
// 从后向前遍历集合中所有元素
ListIterator<String> iterator = stringList.listIterator(stringList.size());
while (iterator.hasPrevious()) {
System.out.println(iterator.previous());
}
// 从前向后遍历集合中所有元素
ListIterator<String> iterator = stringList.listIterator();
while (iterator.hasNext()) {
String it = iterator.next();
// 在 xiaomi 之后加入 redmi
if (it.equals("xiaomi")) {
iterator.add("redmi");
}
// 修改 baidu 为 baidu.com
if (it.equals("baidu")) {
iterator.set("baidu.com");
}
// 删除 google
if (it.equals("google")) {
iterator.remove();
}
}
stringList.forEach(System.out::println);
1.6 使用并行流遍历
如果我们需要对大型集合进行并行处理,那么使用并行流就是一种不错的选择。并行流使用多个线程来并行处理集合中的元素,可以提高处理速度。
// 创建一个并行流(将 parallel 标志指定为 true 表示创建并行流)
Stream<String> parallelStream = strList.parallelStream();
// 查看流是否支持并行遍历
System.out.println("流是否支持遍历:" + parallelStream.isParallel());
// 使用 forEach 方法遍历并行流
parallelStream.forEach(str->{
System.out.println(str);
});
运行结果如下,由于使用了多个线程同时遍历列表中的元素,输出结果可能是乱序的