对 Java 中的流应用过滤器
Apply filter to stream in Java
鉴于以下代码,我希望输出为“-3-2-101231”,因为过滤器应该遍历流的所有项目,从而打印正在评估的项目。当评估 allMatch 函数时,它应该打印“1”,因为它正在接收正整数流,所以它应该在发现第一个元素不是负数后短路。
为什么打印“-3-2-1011”而不是“-3-2-101231”?
List<Integer> list = Arrays.asList(-3,-2,-1,0,1,2,3);
Predicate<Integer> positive = i->{
System.out.print(i);
return i>0;
};
Predicate<Integer> negative = i->{
System.out.print(i);
return i<0;
};
list.stream().filter(positive).allMatch(negative);
不,过滤器不应遍历流中的每个项目。那将是一种浪费。一旦 allMatch()
操作看到一个非负项,管道就会终止。
不能保证流中的所有项目都会被过滤;保证是由 allMatch()
测试的任何项目都首先通过了前面的过滤器。
您看到的输出是来自过滤器的 -3 -2 -1 0 1,然后来自最终谓词的 1,这终止了该过程。当终端操作已经确定其结果时,无需从上游过滤器操作中获取 2。
用文档的话来说,Stream
是
— Laziness-seeking. Many stream operations, such as filtering, mapping, or duplicate removal, can be implemented lazily, exposing opportunities for optimization. For example, "find the first String with three consecutive vowels" need not examine all the input strings. Stream operations are divided into intermediate (Stream-producing) operations and terminal (value- or side-effect-producing) operations. Intermediate operations are always lazy.
并且,
Processing streams lazily allows for significant efficiencies; in a pipeline such as the filter-map-sum example above, filtering, mapping, and summing can be fused into a single pass on the data, with minimal intermediate state. Laziness also allows avoiding examining all the data when it is not necessary; for operations such as "find the first string longer than 1000 characters", it is only necessary to examine just enough strings to find one that has the desired characteristics without examining all of the strings available from the source. (This behavior becomes even more important when the input stream is infinite and not merely large.)
对于“1”,值为 false。和 false && (任何其他)将始终为 false,因此它不会评估任何其他内容。
与 true 和 false 的 if 语句类似,它执行惰性评估:
public static void main(String[] args){
System.out.println("Test1: False && anything else:");
if (returnFalse() && returnTrue()) {
}
System.out.println("Test2: False || anything else:");
if (returnFalse() || returnTrue()) {
}
System.out.println("Test3: True || anything else:");
if (returnTrue() || returnTrue()) {
}
System.out.println("Test4: True && anything else:");
if (returnTrue() && returnTrue()) {
}
}
public static boolean returnFalse() {
System.out.println("false");
return false;
}
public static boolean returnTrue() {
System.out.println("true");
return true;
}
结果将是:
Test1: False && anything else:
false
Test2: False || anything else:
false
true
Test3: True || anything else:
true
Test4: True && anything else:
true
true
鉴于以下代码,我希望输出为“-3-2-101231”,因为过滤器应该遍历流的所有项目,从而打印正在评估的项目。当评估 allMatch 函数时,它应该打印“1”,因为它正在接收正整数流,所以它应该在发现第一个元素不是负数后短路。
为什么打印“-3-2-1011”而不是“-3-2-101231”?
List<Integer> list = Arrays.asList(-3,-2,-1,0,1,2,3);
Predicate<Integer> positive = i->{
System.out.print(i);
return i>0;
};
Predicate<Integer> negative = i->{
System.out.print(i);
return i<0;
};
list.stream().filter(positive).allMatch(negative);
不,过滤器不应遍历流中的每个项目。那将是一种浪费。一旦 allMatch()
操作看到一个非负项,管道就会终止。
不能保证流中的所有项目都会被过滤;保证是由 allMatch()
测试的任何项目都首先通过了前面的过滤器。
您看到的输出是来自过滤器的 -3 -2 -1 0 1,然后来自最终谓词的 1,这终止了该过程。当终端操作已经确定其结果时,无需从上游过滤器操作中获取 2。
用文档的话来说,Stream
是
— Laziness-seeking. Many stream operations, such as filtering, mapping, or duplicate removal, can be implemented lazily, exposing opportunities for optimization. For example, "find the first String with three consecutive vowels" need not examine all the input strings. Stream operations are divided into intermediate (Stream-producing) operations and terminal (value- or side-effect-producing) operations. Intermediate operations are always lazy.
并且,
Processing streams lazily allows for significant efficiencies; in a pipeline such as the filter-map-sum example above, filtering, mapping, and summing can be fused into a single pass on the data, with minimal intermediate state. Laziness also allows avoiding examining all the data when it is not necessary; for operations such as "find the first string longer than 1000 characters", it is only necessary to examine just enough strings to find one that has the desired characteristics without examining all of the strings available from the source. (This behavior becomes even more important when the input stream is infinite and not merely large.)
对于“1”,值为 false。和 false && (任何其他)将始终为 false,因此它不会评估任何其他内容。
与 true 和 false 的 if 语句类似,它执行惰性评估:
public static void main(String[] args){
System.out.println("Test1: False && anything else:");
if (returnFalse() && returnTrue()) {
}
System.out.println("Test2: False || anything else:");
if (returnFalse() || returnTrue()) {
}
System.out.println("Test3: True || anything else:");
if (returnTrue() || returnTrue()) {
}
System.out.println("Test4: True && anything else:");
if (returnTrue() && returnTrue()) {
}
}
public static boolean returnFalse() {
System.out.println("false");
return false;
}
public static boolean returnTrue() {
System.out.println("true");
return true;
}
结果将是:
Test1: False && anything else:
false
Test2: False || anything else:
false
true
Test3: True || anything else:
true
Test4: True && anything else:
true
true