Negate a Predicate Method Reference with Java 11 – 用Java 11否定一个谓词方法引用

最后修改: 2019年 5月 21日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this short tutorial, we’ll see how to negate a Predicate method reference using Java 11.

在这个简短的教程中,我们将看到如何使用Java 11来否定一个Predicate方法引用。

We’ll start with the limitations encountered in order to achieve this before Java 11. Then we’ll see how the Predicate.not() method helps, as well.

我们将从Java 11之前为了实现这一目标所遇到的限制开始。然后我们将看到Predicate.not()方法也有帮助。

2. Before Java 11

2.在Java 11之前

First, let’s see how we managed to negate a Predicate before Java 11.

首先,让我们看看在Java 11之前,我们是如何设法否定一个Predicate的。

To start with, let’s create a Person class with an age field and an isAdult() method:

首先,让我们创建一个Person类,其中有一个age字段和一个isAdult()方法。

public class Person {
    private static final int ADULT_AGE = 18;

    private int age;

    public Person(int age) {
        this.age = age;
    }

    public boolean isAdult() {
        return age >= ADULT_AGE;
    }
}

Now, let’s imagine we have a list of people:

现在,让我们想象一下,我们有一个人的名单。

List<Person> people = Arrays.asList(
  new Person(1),
  new Person(18),
  new Person(2)
);

And we want to retrieve all the adult ones. To achieve that in Java 8, we can:

而我们想检索所有的成人。为了在Java 8中实现这一目标,我们可以。

people.stream()                      
  .filter(Person::isAdult)           
  .collect(Collectors.toList());

However, what if we want to retrieve the non-adult people instead? Then we have to negate the predicate:

然而,如果我们想检索非成年人呢?那么我们就必须否定这个谓词。

people.stream()                       
  .filter(person -> !person.isAdult())
  .collect(Collectors.toList());

Unfortunately, we are forced to let go of the method reference, even though we find it easier to read. A possible workaround is to create an isNotAdult() method on the Person class and then use a reference to this method:

不幸的是,我们不得不放弃方法引用,尽管我们发现它更容易阅读。一个可能的变通方法是在Person类上创建一个isNotAdult()方法,然后使用这个方法的引用。

people.stream()                 
  .filter(Person::isNotAdult)   
  .collect(Collectors.toList());

But maybe we don’t want to add this method to our API, or maybe we just can’t because the class isn’t ours. That’s when Java 11 arrives with the Predicate.not() method, as we’ll see in the following section.

但是,也许我们不想把这个方法添加到我们的API中,或者我们只是不能因为这个类不是我们的。这时,Java 11就出现了Predicate.not()方法,我们将在下一节看到。

3. The Predicate.not() Method

3.Predicate.not()方法

The Predicate.not() static method has been added to Java 11 in order to negate an existing Predicate.

Java 11中加入了Predicate.not()静态方法,以否定现有的Predicate

Let’s take our previous example and see what that means. Instead of using a lambda or creating a new method on the Person class, we can just use this new method:

让我们以我们之前的例子为例,看看这意味着什么。我们不需要使用lambda或者在Person类上创建一个新的方法,而是直接使用这个新方法。

people.stream()                          
  .filter(Predicate.not(Person::isAdult))
  .collect(Collectors.toList());

That way, we don’t have to modify our API and still can rely on the readability of method references.

这样,我们就不必修改我们的API,仍然可以依靠方法引用的可读性。

We can make this even clearer with a static import:

我们可以通过静态导入的方式使之更加清晰。

people.stream()                  
  .filter(not(Person::isAdult))  
  .collect(Collectors.toList());

4. Conclusion

4.总结

In this short article, we’ve seen how to leverage the Predicate.not() method in order to maintain usage of method references for predicates, even if they are negated.

在这篇短文中,我们看到了如何利用Predicate.not()方法,以保持谓词的方法引用的使用,即使它们被否定了。

As usual, the full code of the article can be found over on GitHub.

像往常一样,文章的完整代码可以在GitHub上找到over