任何匹配是否像过滤器 + 查找第一一样具有确定性?



anyMatch是确定性的(对于有序流(像filter + findFirst吗? 除了返回值之外,还有其他差异吗?

如果我有一个有序的流asList("a","b","c"(.filter(predicate(.findFirst((,则可以保证谓词将按照给定的顺序("a"比"b"比"c"(为流的每个元素计算,直到匹配(findFirst(。我想知道asList("a","b","c"(.anyMatch(谓词(是否也会按给定顺序("a"比"b"比"c"(计算谓词?

anyMatch如果流的任何元素与提供的谓词匹配trueboolean返回值,否则返回falsewhere asfindFirst返回Optional<T>如果存在,它将包含匹配元素,否则将返回空的 Optional。您可以根据您要执行的操作进行选择。如果您只想检查该值是否存在,则可以使用anyMatch因为它为您提供了值。如果要查找值并对其进行处理,可以使用findFirst。下面是一个小的代码片段,显示两者在与stream一起使用时以完全相同的方式进行,当与parallelStream一起使用时,该方法是不可预测的。

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
class Scratch {
public static void main(String[] args) {
List<MyInteger> myIntegers= new ArrayList<>();
for (int i = 1; i < 10; i++) {
myIntegers.add(new MyInteger(i));
}
System.err.println("----------findFirst------------");
Optional<MyInteger> result = myIntegers.stream().filter(m -> m.equals(5)).findFirst();
if(result.isPresent()){
System.err.println("Matching Record Found: " + result.get());
}else {
System.err.println("Matching Record Not Found.");
}
System.err.println("----------anyMatch------------");
System.err.println("anyMatch Result: " + myIntegers.stream().anyMatch(m -> m.equals(5)));
}
}
class MyInteger {
private int number;
public MyInteger(int number) {
this.number = number;
}
@Override
public String toString() {
return "MyInteger{" +
"number=" + number +
'}';
}
boolean equals(int match){
System.err.println("Matching " + number + " with " + match);
return number == match;
}
}

输出是

----------findFirst------------
Matching 1 with 5
Matching 2 with 5
Matching 3 with 5
Matching 4 with 5
Matching 5 with 5
Matching Record Found: MyInteger{number=5}
----------anyMatch------------
Matching 1 with 5
Matching 2 with 5
Matching 3 with 5
Matching 4 with 5
Matching 5 with 5
anyMatch Result: true

这里没有太多确定性的东西;至少你要求的比较没有什么意义。filter.findFirst将返回一个Optional<T>,所以如果你关心找到哪个元素,它真的是有序流的第一个吗?如果是这样,答案是肯定的 - 但似乎你已经意识到了这一点。

anyMatch的情况下 - 决定论只是关于结果,这是一个boolean,所以没有太多的确定性,真的; 对于有序流与否。结果将"确定性地"true/false- 这是您获得的唯一保证。

如果您的问题是否在anyMatch的情况下从头开始遍历流是一个完全不同的问题。当然,这是一个实现细节;但它不必以这种方式遍历。流内部很容易有不同的路径,在anyMatch的情况下:一个完全虚构的例子,但完全有可能:

Stream.of(6, 5, 4, 3, 2, 1)
.sorted(Comparator.naturalOrder())
.anyMatch(x -> x > 4);

内部流可以"记住"此流的最小值为1,最大值为6,因为此anyMatch可能需要6并且测试是针对max的,如果匹配,您就完成了。因此,可以与最后一个元素进行比较 -6,这将与filter.findFirst-5不同。

我非常怀疑这样的优化(甚至可能比"优化"更有害(永远不会完成;但理论上是可能的。

StreamanyMatch函数返回此流的任何元素是否与提供的谓词匹配。如果不是确定结果所必需的,则它可能不会计算所有元素的谓词。这是一个短路终端操作,返回一个布尔值。

List<Integer> list1 = Arrays.asList(3, 1);
List<Integer> list2 = Arrays.asList(1, 4, 6, 12, 20);
boolean b = list1.stream().anyMatch(list2::contains);

上述语句返回 false。

筛选器返回与给定谓词匹配的元素的流。这是一个中间操作。这些操作总是惰性的,即执行中间操作(如 filter(( (实际上并不执行任何过滤,而是创建一个新流,该流在遍历时包含与给定谓词匹配的初始流元素。

Stream FindFirst是一个终端操作。它返回 Optional (流中遇到的第一个值(或空的 Optional (如果流为空(。isPresent 是一个布尔函数,用于标识可选项是否具有值。

List<Integer> list1 = Arrays.asList(3, 11);
List<Integer> list2 = Arrays.asList(1, 4, 6, 12, 20);
Optional<Integer> first = list1.stream().filter(list2::contains).findFirst();
if(first.isPresent())
System.out.println(first.get());

相关内容

  • 没有找到相关文章

最新更新