java predicate原理_从零单排Java 8(1) —— Predicate使用介绍

简介

a76d16f45c6d

image.png

在接下来的阶段中,将和大家分享Java 8 系列的一些知识点。本文和大家讲述Predicate的使用方法介绍以及其背景。

简单示例

首先,让我们看看如何使用简单的filter()来过滤一个List集合:

@Test

public void whenFilterList(){

List names = Arrays.asList("Apps", "Alibaba", "william", "Son");

List result = names.stream()

.filter(name -> name.startsWith("A"))

.collect(Collectors.toList());

assertEquals(2, result.size());

assertThat(result, contains("Apps","Alibaba"));

}

在此示例中,我们过滤了List集合,保留以“A”开头的数据 :

name -> name.startsWith("A")

但是假如需要过滤多个条件的话,应该如何?

多个过滤条件

如果我们想要应用多个过滤,一个比较简单地方式就是设置多个过滤器:

@Test

public void whenFilterListWithMultiple(){

List result = names.stream()

.filter(name -> name.startsWith("A"))

.filter(name -> name.length() < 5)

.collect(Collectors.toList());

assertEquals(1, result.size());

assertThat(result, contains("Apps"));

}

看上面的示例,通过提取以“A”开头并且长度小于5的数据来过滤我们的集合。

我们使用了两个过滤条件。

改进版本

现在,我们可以使用一个带有复杂的过滤器,而不是使用多个过滤器filer():

@Test

public void whenFilterListWithComplexPredicate(){

List result = names.stream()

.filter(name -> name.startsWith("A") && name.length() < 5)

.collect(Collectors.toList());

assertEquals(1, result.size());

assertThat(result, contains("Adam"));

}

这个改进比第一个更灵活,因为我们可以使用按位运算来构建我们想要的复杂语句。

组合Predicates

接下来,如果我们不想使用按位运算构建复杂语句,Java 8 Predicate可以使用有用的方法来组合过滤条件。

我们将使用Predicate.and(),Predicate.or()和Predicate.negate()方法组合Predicates。

Predicate.and()

我们来看看只用 and()的方式,可以怎么用

@Test

public void whenFilterListWithCombinedPredicatesUsingAnd(){

Predicate predicate1 = str -> str.startsWith("A");

Predicate predicate2 = str -> str.length() < 5;

List result = names.stream()

.filter(predicate1.and(predicate2))

.collect(Collectors.toList());

assertEquals(1, result.size());

assertThat(result, contains("Adam"));

}

这样的语法非常直观,方法名称表明了操作的类型。使用and(),我们通过仅提取满足两个条件的名称来过滤我们的List。

Predicate.or()

接下来,我们看看or()的方式使用。条件为w开头、或者长度小于4;

@Test

public void whenFilterListWithCombinedPredicatesUsingOr(){

Predicate predicate1 = str -> str.startsWith("w");

Predicate predicate2 = str -> str.length() < 4;

List result = names.stream()

.filter(predicate1.or(predicate2))

.collect(Collectors.toList());

assertEquals(2, result.size());

assertThat(result, contains("John","Tom"));

}

Predicate.negate()

现在我们来结合一下看看 negate()的使用场景,这个方法是指相反条件,即 <>,!xxx。

@Test

public void whenFilterListWithCombinedPredicatesUsingOrAndNegate(){

Predicate predicate1 = str -> str.startsWith("w");

Predicate predicate2 = str -> str.length() < 4;

List result = names.stream()

.filter(predicate1.or(predicate2.negate()))

.collect(Collectors.toList());

assertEquals(3, result.size());

assertThat(result, contains("Apps","Alibaba","william"));

}

上示例的代码中,条件是为 w开头的或者 数据的长度不是小于4的过滤条件。

predicate新写法

我们甚至也可以不用写 and()、or()、negate()就可以使用predicate方法:

@Test

public void whenFilterListWithCombinedPredicatesInline(){

List result = names.stream()

.filter(((Predicate)name -> name.startsWith("A"))

.and(name -> name.length()<5))

.collect(Collectors.toList());

assertEquals(1, result.size());

assertThat(result, contains("Apps"));

}

复杂的条件组合

最后,让我们看看如何通过编写出一个可以支持多个复杂条件的过滤方法。

在下面的例子中,我们有一个列表集合,我们使用组合Predicate.and() :

@Test

public void whenFilterListWithCollectionOfPredicatesUsingAnd(){

List> allPredicates = new ArrayList>();

allPredicates.add(str -> str.startsWith("A"));

allPredicates.add(str -> str.contains("ba"));

allPredicates.add(str -> str.length() > 4);

List result = names.stream()

.filter(allPredicates.stream().reduce(x->true, Predicate::and))

.collect(Collectors.toList());

assertEquals(1, result.size());

assertThat(result, contains("Alibaba"));

}

请留意,我们使用了一个关键性代码:

x->true

但是如果我们想要使用Predicate.or()组合它们会有所不同:

@Test

public void whenFilterListWithCollectionOfPredicatesUsingOr(){

List result = names.stream()

.filter(allPredicates.stream().reduce(x->false, Predicate::or))

.collect(Collectors.toList());

assertEquals(2, result.size());

assertThat(result, contains("Apps","Alibaba"));

}

结论

本文主要是讲解了如何更好的过滤List中的数据,filter()、Predicates的使用方法,已经针对的场景。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值