第五章(3)查找和匹配

     另一个常见的数据处理套路是看看数据集中的某些元素是否匹配一个给定的属性。Stream API通过allMatch、anyMatch、noneMatch、findFirst和findAny方法提供了这样的工具。

1.检查谓词是否至少匹配一个元素anyMatch

       检查谓词是否至少匹配一个元素anyMatch方法可以回答“流中是否有一个元素能匹配给定的谓词”。比如,你可以用它来看看菜单里面是否有素食可选择:

List<Dish> menu = Arrays.asList( new Dish("pork", false, 800, Dish.Type.MEAT), 
				new Dish("beef", false, 700, Dish.Type.MEAT), 
				new Dish("chicken", false, 400, Dish.Type.MEAT), 
				new Dish("french fries", true, 530, Dish.Type.OTHER), 
				new Dish("rice", true, 350, Dish.Type.OTHER), 
				new Dish("season fruit", true, 120, Dish.Type.OTHER),
				new Dish("pizza", true, 550, Dish.Type.OTHER),
				new Dish("prawns", false, 300, Dish.Type.FISH), 
				new Dish("salmon", false, 450, Dish.Type.FISH) );
Boolean boolean1 = menu.parallelStream().anyMatch(Dish::isVegetarian);
System.out.println(boolean1);//true

2.检查谓词是否匹配所有元素allMatch

      检查谓词是否匹配所有元素allMatch方法的工作原理和anyMatch类似,但它会看看流中的元素是否都能匹配给定的谓词。比如,你可以用它来看看菜品是否有利健康(即所有菜的热量都低于500卡路里):

Boolean boolean1 = menu.parallelStream().allMatch(d->d.getCalories()<500);
System.out.println(boolean1);//false

3.检查谓词是否都不匹配所有元素noneMatch

Boolean boolean1 = menu.parallelStream().noneMatch(d->d.getCalories()>1000);
System.out.println(boolean1);//true

     anyMatch、allMatch和noneMatch这三个操作都用到了我们所谓的短路,这就是大家熟悉的Java中&&和||运算符短路在流中的版本。

4.查找元素findAny

     findAny方法将返回当前流中的任意元素。它可以与其他流操作结合使用。比如,你可能想找到一道素食菜肴。你可以结合使用filter和findAny方法来实现这个查询:

Optional<Dish> dish = menu.parallelStream().filter(Dish::isVegetarian).findAny();

流水线将在后台进行优化使其只需走一遍,并在利用短路找到结果时立即结束。但是你可能会疑惑,Optional是个什么玩意?

你现在只需知道Optional<T>类(java.util.Optional)是一个容器类,代表一个值存在或不存在。在上面的代码中,findAny可能什么元素都没找到。Java 8的库设计人员引入了Optional<T>,这样就不用返回众所周知容易出问题的null了。

我们在这里简单的了解一下其拥有的一些实用方法,在后面我们会有详细的介绍:

1.isPresent()将在Optional包含值的时候返回true, 否则返回false。

Optional<Dish> dish = menu.parallelStream().filter(Dish::isVegetarian).findAny();
System.out.println(dish.isPresent());//true

2.ifPresent(Consumer<T> block)会在值存在的时候执行给定的代码块。我们在第3章介绍了Consumer函数式接口;它让你传递一个接收T类型参数,并返回void的Lambda表达式。

Optional<Dish> dish = menu.parallelStream().filter(Dish::isVegetarian).findAny();
dish.ifPresent(dish2 -> System.out.println(dish2.getName()));

3.T get()会在值存在时返回值,否则抛出一个NoSuchElement异常。

4.T orElse(T other)会在值存在时返回值,否则返回一个默认值。

5.查找第一个元素findFrist

       有些流有一个出现顺序(encounter order)来指定流中项目出现的逻辑顺序(比如由List或排序好的数据列生成的流)。对于这种流,你可能想要找到第一个元素。为此有一个findFirst方法,它的工作方式类似于findany。例如,给定一个数字列表,下面的代码能找出第一个平方能被3整除的数:

Optional<Integer> optional = someNumbers.parallelStream().filter(i->i*i%3==0).findFirst();
System.out.println(optional.get());//3

何时使用findFirst和findAny你可能会想,为什么会同时有findFirst和find-Any呢?答案是并行。找到第一个元素在并行上限制更多。如果你不关心返回的元素是哪个,请使用find-Any,因为它在使用并行流时限制较少。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值