A quick guide to java 8 streams filtering concept with multiple conditions. This demonstrates how to use filter() in a more advanced way with examples
More Info: 1Z0-809: Java SE 8 Programmer II
1. Overview
In this tutorial, We’ll learn how to utilise stream filter() with several filter conditions (can be more than one condition).
Normally, we apply a single condition to streams using filter() method with lambda and then store the results in Lists or Sets.
However, we’ll learn how to use the filter() method with as many condition filters as we require.
More filters can be applied in a variety of methods, such using the filter() method twice or supplying another predicate to the Predicate.and() method.
In the next sections, we’ll look at examples with single and multiple conditions.
2. Stream.filter() with Single Condition
First, We’ll start by looking at how to apply the single filter condition to java streams.
Predicate is passed as an argument to the filter() method. Each value in the stream is evaluated to this predicate logic.
There are only a few methods in Predicate functional interface, such as and(), or(), or negate(), and isEquals().
package com.oraclejavacertified.java8.streams.filter;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Example to filter the steam with single condition.
*
*/
public class FilterSingleCondition {
public static void main(String[] args) {
System.out.println("Fruites stream : " + getStream().collect(Collectors.toList()));
// filter 1
Predicate<String> nofruitWordFilter = name -> !name.contains("fruit");
List<String> filteredList1 = getStream().filter(nofruitWordFilter).collect(Collectors.toList());
System.out.println("filteredList 1 : " + filteredList1);
// filter 1
Predicate<String> noLetterOFilter = name -> !name.contains("o");
List<String> noLetterOFilterList = getStream().filter(noLetterOFilter).collect(Collectors.toList());
System.out.println("noLetterOFilterList : " + noLetterOFilterList);
}
// creating the stream of strings.
private static Stream<String> getStream() {
Stream<String> fruitesStream = Stream.of("mango", "grapes", "apple", "papaya", "jack fruit", "dragon fruit");
return fruitesStream;
}
}
Output:
Fruites stream : [mango, grapes, apple, papaya, jack fruit, dragon fruit]
filteredList 1 : [mango, grapes, apple, papaya]
noLetterOFilterList : [grapes, apple, papaya, jack fruit]
In the preceding example, we generated two predicate filters but only applied one of them to the stream at a time.
And it has generated two distinct outputs, which you should carefully examine.
3. Stream.filter() – Java 8 Stream Filter Multiple Parameters or Conditions
In the previous section, we have seen how to create a filter in java for stream
Next, we’ll attempt two different approaches of applying many conditions to a stream.
3.1 Invoking the filter() method on the stream multiple times
Take a look at the results after using the filter() method twice with different predicates criteria.
package com.oraclejavacertified.java8.streams.filter;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Example to filter the steam with multiple conditions.
*
*/
public class FilterMultipleCondition {
public static void main(String[] args) {
System.out.println("Fruites stream : " + getStream().collect(Collectors.toList()));
// filter 1
Predicate<String> nofruitWordFilter = name -> !name.contains("fruit");
// filter 2
Predicate<String> noLetterOFilter = name -> !name.contains("o");
// to remove the fruites with word "fruit" and with letter "o".
List<String> result = getStream().filter(nofruitWordFilter)
.filter(noLetterOFilter)
.collect(Collectors.toList());
// printing the final result
System.out.println("Final result : " + result);
}
// creating the stream of strings.
private static Stream<String> getStream() {
Stream<String> fruitesStream = Stream.of("mango", "grapes", "apple", "papaya", "jack fruit", "dragon fruit");
return fruitesStream;
}
}
Output:
Fruites stream : [mango, grapes, apple, papaya, jack fruit, dragon fruit]
Final result : [grapes, apple, papaya]
3.2 Invoking Predicate.and() method with two conditions
Let’s utilise the method firstPredicate.and(secondPredicate) now. Pass the second predicate as a parameter to the and() function on the first predicate.
This signifies that the first predicate receives each instance from the stream. If the first predicate returns true, the second predicate receives the same value.
Finally, the result of filter() method will be satisfied by first and second predicate’s.
You can also use p1.and(p2.and(p3) to call with multiple predicates.
List<String> andPredicateResult = getStream().filter(nofruitWordFilter
.and(noLetterOFilter))
.collect(Collectors.toList());
System.out.println("andPredicateResult : "+andPredicateResult);
andPredicateResult : [grapes, apple, papaya]
When you call the filter() method several times and the predicate.and() method, the results are the same. However, it is recommended that you use the predicate and() method as needed.
this is similar to the grouping the multiple conditions into the single conditions as single predicate to filter() method.
You can use predicate or() or isEquals() methods with the multiple predicate conditions.
Source: javacodegeeks.com