Java Lambda表达式forEach无法跳出循环的解决思路
如果你使用过forEach方法来遍历集合,你会发现在lambda表达式中的return并不会终止循环,这是由于lambda的底层实现导致的,看下面的例子:
public static void main(String[] args) {
List<String> list = Lists.newArrayList();
list.add("a");
list.add("b");
list.add("c");
list.forEach(s -> {
System.out.println("s = " + s);
if (s.equals("b")) {
return;
}
});
}
//返回结果:
//s = a
//s = b
//s = c
可以看到在forEach方法中即是采用了return,循环却仍在继续,那有什么办法能跳出循环呢?
可以通过抛异常的方法:
public static void main(String[] args) {
List<String> list = Lists.newArrayList();
list.add("a");
list.add("b");
list.add("c");
try {
list.forEach(s -> {
System.out.println("s = " + s);
if (s.equals("b")) {
throw new RuntimeException();
}
});
}catch (Exception e){}
}
//返回结果:
//s = a
//s = b
但仔细想想,这样也太挫了,其实可以换一种思路,跳出的前提肯定是满足了某一条件的,所以可以使用anyMatch()方法:
anyMatch()里接收一个返回值为boolean类型的表达式,只要返回true就会终止循环,这样可以将业务逻辑写在返回判断结果前。
public static void main(String[] args) {
List<String> list = Lists.newArrayList();
list.add("a");
list.add("b");
list.add("c");
list.stream().anyMatch(s -> {
System.out.println("do something");
System.out.println("s=" + s);
return s.equals("b");
});
}
// do something
// s=a
// do something
// s=b
同理,采用类似的思路可以使用filter()方法,思路是一样的,其中findAny表示只要找到满足的条件时停止。
public static void main(String[] args) {
List<String> list = Lists.newArrayList();
list.add("a");
list.add("b");
list.add("c");
list.stream().filter(s -> {
System.out.println("s=" + s);
return s.equals("b");
}).findAny();
}
//返回结果:
//s = a
//s = b