前言
本篇记录学习forEach方法时遇到的问题和解决方案,包括continue功能的实现,forEach()和steam().forEach()的区别等。
如何实现continue功能
在遍历的过程中部分数据不需要处理,在 forEach 中使用 continue 会报错“continue 位于循环外部”。
方案一:使用return代替continue
在 forEach 方法中使用 return 会导致 Consumer 函数式接口的 accept 方法立即返回,从而跳过当前元素继续下一个迭代。
准备一个包含 0~9 十个数字的模拟list,下文中使用同一个list,相同代码不再重复:
List<Integer> list = new ArrayList<>();
for(int i = 0; i < 10; i++) {
list.add(i);
}
// 遍历
list.forEach(number -> {
if (number < 5) {
// 使用 return 代替 continue
return;
}
System.out.println(number);
});
运行结果:
5
6
7
8
9
方案二:先使用filter过滤数据
在遍历前去除需用使用continue跳过的元素,从而实现类似continue在for循环中的功能。这里filter的条件是需要遍历的内容,和方案一中的条件不同:
// 使用filter过滤符合条件的数据
list.stream().filter(number -> number >= 5).forEach(number -> {
System.out.println(number);
});
运行结果:
5
6
7
8
9
list.forEach()和list.stream().forEach()的区别
在处理刚才的代码时发现,使用 .filter() 前需要使用 .stream() 方法,所以顺带研究了一下list.forEach() 和 list.stream().forEach() 的区别。
list.forEach()
list.forEach()会按顺序遍历元素,是一个阻塞方法,只有执行完对当前元素的操作后才会进入下一个循环。
使用 Thread.sleep() 模拟耗时操作:
list.forEach(element -> {
try {
// 模拟耗时操作
System.out.println(element + "开始");
Thread.sleep(100);
System.out.println(element + "结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
方法执行耗时1005毫秒,输出结果:
0开始
0结束
1开始
1结束
2开始
2结束
3开始
3结束
4开始
4结束
5开始
5结束
6开始
6结束
7开始
7结束
8开始
8结束
9开始
9结束
list.stream().forEach()
list.stream().forEach() 首先将List转换成 Stream 对象,允许使用 Stream API 提供的操作方法,比如 filter(),在遍历之前先对数据进行处理,然后调用 forEach() 方法,对元素执行并行的操作:
list.stream().forEach(element -> {
try {
// 模拟耗时操作
System.out.println(element + "开始");
Thread.sleep(100);
System.out.println(element + "结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
方法执行耗时106毫秒,输出结果:
6开始
2开始
0开始
4开始
1开始
3开始
5开始
9开始
8开始
7开始
2结束
5结束
7结束
9结束
8结束
0结束
6结束
3结束
4结束
1结束
可以看出 list.stream().forEach() 的执行不按顺序、同步执行多个元素的操作、效率更高。
list.stream().forEachOrdered()
如果对遍历的顺序有要求,同时还希望使用 Stream API 的操作方法,可以使用 Stream 提供的 forEachOrdered() 方法。该方法类似直接调用 forEach() :
list.stream().forEachOrdered(element -> {
try {
System.out.println(element + "开始");
Thread.sleep(100);
System.out.println(element + "结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
方法执行耗时1006毫秒,输出结果:
0开始
0结束
1开始
1结束
2开始
2结束
3开始
3结束
4开始
4结束
5开始
5结束
6开始
6结束
7开始
7结束
8开始
8结束
9开始
9结束
版权归原作者 Seyyu 所有, 如有侵权,请联系我们删除。