在for循环中使用以下代码和破坏行为:
package test;
import java.util.Arrays;
import java.util.List;
public class Test {
private static List<Integer> integerList = Arrays.asList(1, 2, 3, 4);
public static void main(String[] args) {
countTo2(integerList);
}
public static void countTo2(List<Integer> integerList) {
for (Integer integer : integerList) {
System.out.println("counting " + integer);
if (integer >= 2) {
System.out.println("returning!");
return;
}
}
}
}
尝试使用forEach()
使用Lambda表达它将改变行为,因为for循环不再破坏:
public static void countTo2(List<Integer> integerList) {
integerList.forEach(integer -> {
System.out.println("counting " + integer);
if (integer >= 2) {
System.out.println("returning!");
return;
}
});
}
这实际上是有道理的,因为return;
语句只在lambda表达式本身内部(在内部迭代中)强制执行而不是整个执行序列,所以有没有办法获得所需的行为(打破for loop)使用lambda表达式?
答案 0 :(得分:3)
以下代码在逻辑上等同于您的代码:
public static void countTo2(List<Integer> integerList) {
integerList.stream()
.peek(i -> System.out.println("counting " + i))
.filter(i -> i >= 2)
.findFirst()
.ifPresent(i -> System.out.println("returning!"));
}
如果您对任何事情感到困惑,请告诉我们!
答案 1 :(得分:2)
您正在寻找的是short-circuit
终端操作,虽然这是这样做的方式:
integerList.stream()
.peek(x -> System.out.println("counting = " + x))
.filter(x -> x >= 2)
.findFirst()
.ifPresent(x -> System.out.println("retunrning"));
仅在处理sequential
流时才是等效的。只要您添加parallel
peek
可能会显示您不希望的元素,因为没有定义processing order
,但有encounter order
- 意味着元素将是正确送入终端操作。
答案 2 :(得分:1)
我能想到的一种方法是使用anyMatch
和反向:
if (integerList.stream().noneMatch(val -> val >= 2)) {
System.out.println("counting " + val);
}
if (integerList.stream().anyMatch(val -> val >= 2)) {
System.out.println("returning!");
}
但在内部会迭代列表两次,并且我认为不是最优的。