How to filter a list with Predicate

Introduction

This post would demo how to filter a list with Predicate.

You will see:

  • Filter list with Predicate
  • Filter list with Predicate and removeIf
  • Filter list with Predicate and java 8 stream
  • Filter list with Predicate and apache commons-collections example1
  • Filter list with Predicate and apache commons-collections example2

Before we continue our examples ,we should review the java.util.function.Predicate’s definination:

@FunctionalInterface public interface Predicate

Represents a predicate (boolean-valued function) of one argument.

It’s a FunctionalInterface, so you can reference it with lambda expressions.

Environments

  • Java 1.8

1. Setup the environment

The pom.xml

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <!-- Import dependency management from Spring Boot -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>1.5.12.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

As you can see, I use the 1.5.12 springboot and add the springboot test starter for unit testing.

If you don’t know how to do unit testing with springboot , you can reference the post: How to do unit testing with springboot hello world example

2. Examples

2.1 The utility method to print a list content

private static <T> void consumeCollection(Collection<T> collection, Consumer<T> consumer) {
    for(T t:collection) {
        consumer.accept(t);
    }
}

We use a Consumer function to process every element of the list.

2.2 Filter list with Predicate

public static <T> List<T> filterList(List<T> originList, Predicate<T> thePredicate) {
    List<T> result = new ArrayList<T>();//line 1
    for(T t:originList) {
        if(thePredicate.test(t)) {//line 2
            result.add(t);
        }
    }
    return result;
}

Explanation:

  • The param is a list of T named originList
  • The return value is a list of T
  • The originList should not be modifed by this filter method

The lines explanation:

  • line 1
    • we define an ArrayList to store the result
  • line 2
    • we use the Predicate’s test method to check if the condition is met

The test code:

public static void main(String[] args) {
    List<String> s = Arrays.asList("a","bc","asdf","232323");

    System.out.println("after filter");
    List<String> result = filterList(s,temp->temp.length()>3);
    consumeCollection(result,temp-> System.out.println(temp));

    System.out.println("\nbefore filter:");
    consumeCollection(s,temp-> System.out.println(temp));
}

And we got this:

after filter
asdf
232323

before filter:
a
bc
asdf
232323

2.2 Filter list with Predicate and removeIf

There is a removeIf method in java.util.Collection interface. It would remove the elements if it matches the Predicate conditions.

java.util.Collection.removeIf

default boolean removeIf(Predicate<? super E> filter) Removes all of the elements of this collection that satisfy the given predicate. Errors or runtime exceptions thrown during iteration or by the predicate are relayed to the caller.

The example code:

public static <T> List<T> filterListWithRemoveIf(List<T> originList,
                                                 Predicate<T> thePredicate) {
    List<T> result = new ArrayList<T>(originList);//line 1
    result.removeIf(thePredicate);//line 2
    return result;
}

Explanation:

  • line 1
    • Because the removeIf would affects the origin list, we create a new list to store the result, and use the new ArrayList(originList) to shadow copy the origin list. The shadow copy would only copy reference to elements.
  • line 2
    • we call the removeIf on the shadow copied result list, it would remove some references to the elements that match the Predicate conditions

The test code:

public static void main(String[] args) {
    List<String> s = Arrays.asList("a","bc","asdf","232323");

    System.out.println("after filter");
    List<String> result = filterListWithRemoveIf(s,temp->temp.length()>3);
    consumeCollection(result,temp-> System.out.println(temp));

    System.out.println("\nbefore filter:");
    consumeCollection(s,temp-> System.out.println(temp));
}

And we got this:

after filter
asdf
232323

before filter:
a
bc
asdf
232323

2.3 Filter list with Predicate and java 8 stream

Java 8 supplies a new stream api, which would streamlines the collections operations with a more concise way.

The stream with predicate example:

public static <T> List<T> filterListWithStream(List<T> originList,Predicate<T>
            thePredicate) {
        return 
        originList.stream() //line 1
        .filter(thePredicate) //line 2
        .collect(Collectors.toList()); //line 3
    }

Explanation:

  • line 1:
    • convert list to a stream
  • line 2:
    • filter the list by the Predicate
  • line 3:
    • collect to result to a new list

The test code:

public static void main(String[] args) {
    List<String> s = Arrays.asList("a","bc","asdf","232323");

    System.out.println("after filter");
    List<String> result = filterListWithStream(s,temp->temp.length()>3);
    consumeCollection(result,temp-> System.out.println(temp));

    System.out.println("\nbefore filter:");
    consumeCollection(s,temp-> System.out.println(temp));
}

And we got this:

after filter
asdf
232323

before filter:
a
bc
asdf
232323

2.4 Filter list with Predicate and apache commons collections example1

Apache commons collections supply a useful CollectionUtils.We can use like this:

Add dependency:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-collections4</artifactId>
    <version>4.1</version>
</dependency>

The CollectionUtils has a filter method we can use.

public static boolean filter(Iterable collection, Predicate<? super T> predicate) Filter the collection by applying a Predicate to each element. If the predicate returns false, remove the element. If the input collection or predicate is null, there is no change made.

The example code:

public static <T> boolean filterListWithCollectionUtils(List<T> originList,Predicate<T>
            thePredicate) {
        return CollectionUtils.
        	filter(originList, 
        		t->thePredicate.test(t));//line 1
    }

Explanation:

  • This method return a boolean result, indicates the filter is successful or not
  • The originList would be affected by the filter operation
  • line 1
    • Because apache commons collections CollectionUtils use its own Predicate class, so we must transform the java Predicate to apache Predicate, here we use a lambda expression

The test code:

public static void main(String[] args) {
    List<String> s = Arrays.asList("a","bc","asdf","232323");

    System.out.println("after filter");
    List<String> result = new ArrayList<>(s);
    filterListWithCollectionUtils(result,temp->temp.length()>3);
    consumeCollection(result,temp-> System.out.println(temp));

    System.out.println("\nbefore filter:");
    consumeCollection(s,temp-> System.out.println(temp));
}

And we got this:

after filter
asdf
232323

before filter:
a
bc
asdf
232323

2.5 Filter list with Predicate and apache commons-collections example2

If you want the origin list to be retained(not modified), you should use the CollectionUtils.select method

public static Collection select(Iterable<? extends O> inputCollection,Predicate<? super O> predicate) Selects all elements from input collection which match the given predicate into an output collection.A null predicate matches no elements.

The example code:

public static <T> Collection<T> filterListWithCollectionUtilsNoModify(List<T> originList, Predicate<T>
        thePredicate) {
    return CollectionUtils.select(originList,t->thePredicate.test(t));
}

4. summary

In this post we demo various ways to filter a list with Predicate function.You can find the whole code examples on github.

You can find detail documents about the java lambda here: