News Ticker

Recently there was an interesting discussion on the use of predicate negation in the .filter method on a stream by members of the LJC mailing list, so I thought it would be worth summarizing it in a blog post. The discussion was about ways to use .filter and to negate the predicate.

Code for this post is available in my GitHub account.

## Question: How can you use .filter to negate the predicate

This is perhaps how you might think about doing,

```Stream.of(1, 2, 3, 4, 5, 6, 7)
.filter(((Predicate) c -> c % 2 == 0).negate())```

but here are some alternative ways.

## Answer 1: Write a predicate utility method

You can simplify this by writing a utility method that performs the negation.

```public static <R> Predicate<R> not(Predicate<R> predicate) {
return predicate.negate();
}```

Which results in much neater code.

```Stream.of(1, 2, 3, 4, 5, 6, 7)
.filter(not(c -> c % 2 == 0))```

View source on GitHub

## Answer 2: Use an identity function to convert the method reference to a Predicate

We use a utility method to convert a method reference to a predicate.

```public static <T> Predicate<T> predicate(Predicate<T> predicate) {
return predicate;
}```

although the code is not as neat.

```Stream.of("Cat", "", "Dog")
.filter(predicate(String::isEmpty).negate())```

References: Heinz’s Lambda Reduction Principle

## Answer 3: Use the not (!) operator

Use the familiar, not operator.

```Stream.of(1, 2, 3, 4, 5, 6, 7)
.filter((c -> c % 2 != 0))

Stream.of("Cat", "", "Dog")
.filter(str -> !str.isEmpty())```

The code is much simpler and immediately familiar.

## Conclusion

It is argued that method references are often harder to read and are trickier when refactoring than simple lambdas and that mixing lambdas and method references in a Stream chain is confusing to the reader. Reference: Java SE 8 Best Practices

When you use a method reference and want the IDE to create the method, IntelliJ creates this as a static method with the object as the first argument. Using the not operator avoids this.

Here are some useful references:

#### 1 Comment on Java 8 Streams: .filter and Predicate Negation

1. Was surprised that – after so many years of previous functional languages to learn lessons from – the intrinsically ambiguously named method “filter” was used at all in Java8.

I much prefer a pair of methods: “accept” (or “select”) and “reject”. Doesn’t everyone?