java8 stream接口终端操作 count,anyMatch,allMatch,noneMatch,startsWith匹配,以及findAny findFirst对比

101 篇文章 14 订阅

1、说明

count方法,跟List接口的size一样,返回的都是这个集合流的元素的长度,不同的是,流是集合的一个高级工厂,中间操作是工厂里的每一道工序,我们对这个流操作完成后,可以进行元素的数量的和;

anyMatch表示,判断的条件里,任意一个元素成功,返回true

allMatch表示,判断条件里的元素,所有的都是,返回true

noneMatch跟allMatch相反,判断条件里的元素,所有的都不是,返回true

下面,看几个例子

List<String> strs = Arrays.asList("a", "a", "a", "a", "b");
        boolean aa = strs.stream().anyMatch(str -> str.equals("a"));
        boolean bb = strs.stream().allMatch(str -> str.equals("a"));
        boolean cc = strs.stream().noneMatch(str -> str.equals("a"));
        long count = strs.stream().filter(str -> str.equals("a")).count();
        System.out.println(aa);// TRUE
        System.out.println(bb);// FALSE
        System.out.println(cc);// FALSE
        System.out.println(count);// 4


通过例子可以看到,变量aa的表达式,strs里的元素,任意有“a”,表示true

变量bb的表达式,strs里的元素,全部为“a”,表示true,否则false

变量cc的表达式,strs里的元素,全部不为“a”,表示true,否则false

2、结合startsWith匹配

检查IP是否在list中(以开头匹配为规则)

List<String> ipAddresses = Arrays.asList("10.", "132.174.", "192.168.");

//"192.168.0.1"是以"192.168."开头, isMatch=true
boolean isMatch = ipAddresses.stream().anyMatch("192.168.0.1"::startsWith);

同时可以查看我另外一篇文章:https://blog.csdn.net/zzhongcy/article/details/98489749

3、Java 8 Stream findFirst() 与 findAny()

3.1 使用Stream.findAny()

findAny()方法允许您从Stream中找到任何元素,在寻找元素而无需注意相遇顺序是使用他。该方法返回一个Optional实例,如果Stream为空,则改实例为空。

@Test
public void createStream_whenFindAnyResultIsPresent_thenCorrect() {
    List<String> list = Arrays.asList("A","B","C","D");
 
    Optional<String> result = list.stream().findAny();
 
    assertTrue(result.isPresent());
    assertThat(result.get(), anyOf(is("A"), is("B"), is("C"), is("D")));
}
复制代码

在并行操作中,他可能会返回Stream中的第一个元素,但是对策不能保证。为了在处理并行操作时获得最佳性能,无法可靠地确定结果:

@Test
public void createParallelStream_whenFindAnyResultIsPresent_thenCorrect()() {
    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
    Optional<Integer> result = list
      .stream().parallel()
      .filter(num -> num < 4).findAny();
 
    assertTrue(result.isPresent());
    assertThat(result.get(), anyOf(is(1), is(2), is(3)));
}
复制代码

3.2 使用Stream.findFirst()

在使用findFirst()方法查找在第一元素流。特别需要序列中的第一个元素时,将使用此方法。如果没有遇到顺序,他将从Stream返回任何元素。该`java.util.stream``包文件说:

流可能具有也可能没有定义的遇到顺序,他取决于源和中间操作

返回类型也是Optional实例,如果Stream也为空,则该实例也为空:

@Test
public void createStream_whenFindFirstResultIsPresent_thenCorrect() {
 
    List<String> list = Arrays.asList("A", "B", "C", "D");
 
    Optional<String> result = list.stream().findFirst();
 
    assertTrue(result.isPresent());
    assertThat(result.get(), is("A"));
}
复制代码

在并行方案中,findFirst()方法的行为不会更改。如果遇到顺序存在,它将始终具有确定性。

3.3 结论

  • findAny()方法返回从任何元素流而使用
  • findFirst()方法返回在第一个元素流

      可以看到findAny()操作,返回的元素是不确定的,对于同一个列表多次调用findAny()有可能会返回不同的值。使用findAny()是为了更高效的性能。如果是数据较少,串行地情况下,一般会返回第一个结果,如果是并行的情况,那就不能确保是第一个。

比如下面的例子会随机地返回OptionalInt[50]。

System.out.println(IntStream.range(0, 100).parallel().findAny());

让我们来举另外一个例子:

List<String> lst1 = Arrays.asList("Jhonny", "David", "Jack", "Duke", "Jill","Dany","Julia","Jenish","Divya");
List<String> lst2 = Arrays.asList("Jhonny", "David", "Jack", "Duke", "Jill","Dany","Julia","Jenish","Divya");
 
Optional<String> findFirst = lst1.parallelStream().filter(s -> s.startsWith("D")).findFirst();
Optional<String> fidnAny = lst2.parallelStream().filter(s -> s.startsWith("J")).findAny();
 
System.out.println(findFirst.get()); //总是打印出David
System.out.println(fidnAny.get()); //会随机地打印出Jack/Jill/Julia

参考:

https://stackoverflow.com/questions/54096730/java-8-filter-a-string-x-from-a-list-using-startswith-and-save-the-string-x-to

https://blog.csdn.net/qq_28410283/article/details/80783946

https://www.baeldung.com/java-stream-findfirst-vs-findany

请我喝咖啡

如果觉得文章写得不错,能对你有帮助,可以扫描我的微信二维码请我喝咖啡哦~~哈哈~~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值