Filtering a list in Java

In this article we show how to filter a list in Java.

This article shows seven different ways to filter a list. We use five different libraries, including Apache Commons, Google Guava, JOQuery, Eclipse Collections, and Spring core.

In all seven examples, we are going to filter a list of persons. A Person is a Java class with three attributes: age, name, and sex.

Filtering a list with plain Java

In the first example, we use plain Java to filter a list.

Person.java
package com.zetcode;

enum Gender {
    MALE, FEMALE
};

public class Person {

    private int age;
    private String name;
    private Gender sex;

    public Person(int age, String name, Gender sex) {
        this.age = age;
        this.name = name;
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Gender getSex() {
        return sex;
    }

    public void setSex(Gender sex) {
        this.sex = sex;
    }
    
    @Override
    public String toString() {
        return "Person{" + "age=" + age + ", "
                + "name=" + name + ", sex=" + sex + '}';
    }    
}

We have this Person bean. We are going to filter a list having these beans. The toString() method gives a string representation of the bean. This is going to be helpful when we print the filtered list of elements.

FilterListEx.java
package com.zetcode;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class FilterListEx {

    public static void main(String[] args) {

        Person p1 = new Person(34, "Michael", Gender.MALE);
        Person p2 = new Person(17, "Jane", Gender.FEMALE);
        Person p3 = new Person(28, "John", Gender.MALE);
        Person p4 = new Person(47, "Peter", Gender.MALE);
        Person p5 = new Person(27, "Lucy", Gender.FEMALE);
        
        List<Person> persons = Arrays.asList(p1, p2, p3, p4, p5);
        
        List<Person> result = new ArrayList<>();
        
        for (Person person: persons) {
            if (person.getAge() > 30) {
                result.add(person);
            }
        }
        
        System.out.println(result);
    }
}

The example filters a list of persons. The result list contains persons who are younger than thirty years.

for (Person person: persons) {
    if (person.getAge() > 30) {
        result.add(person);
    }
}

A for loop is used to go through the list of persons and create a new one having persons below thirty.

[Person{age=34, name=Michael, sex=MALE}, Person{age=47, name=Peter, sex=MALE}]

This is the output of the example.

Filtering a list with Apache CollectionUtils

In the second example, we filter data with the Apache CollectionUtils. It provides utility methods and decorators for Collection instances.

<dependency>
    <groupId>commons-collections</groupId>
    <artifactId>commons-collections</artifactId>
    <version>3.2.2</version>
</dependency>

<dependency>
    <groupId>commons-lang</groupId>
    <artifactId>commons-lang</artifactId>
    <version>2.6</version>
</dependency>

We use these Maven dependencies. The commons-lang is used for the ToStringBuilder, which is used in the toString() method.

Person.java
package com.zetcode;

import org.apache.commons.lang.builder.ToStringBuilder;

enum Gender {
    MALE, FEMALE
};

public class Person {

    private int age;
    private String name;
    private Gender sex;

    public Person(int age, String name, Gender sex) {
        this.age = age;
        this.name = name;
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Gender getSex() {
        return sex;
    }

    public void setSex(Gender sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return new ToStringBuilder(Person.class).
                append("Age", age).
                append("Name", name).
                append("Sex", sex).
                toString();
    }
}

The Person bean is improved with the ToStringBuilder() inside the toString() method.

FilterListEx2.java
package com.zetcode;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;

public class FilterListEx2 {

    public static void main(String[] args) {

        Person p1 = new Person(34, "Michael", Gender.MALE);
        Person p2 = new Person(17, "Jane", Gender.FEMALE);
        Person p3 = new Person(28, "John", Gender.MALE);
        Person p4 = new Person(47, "Peter", Gender.MALE);
        Person p5 = new Person(27, "Lucy", Gender.FEMALE);

        List<Person> persons = Arrays.asList(p1, p2, p3, p4, p5);

        List<Person> result = new ArrayList<>();
        result.addAll(persons);

        CollectionUtils.filter(result, new Predicate() {

            @Override
            public boolean evaluate(Object o) {
                return ((Person) o).getAge() < 30;
            }

        });
        
        System.out.println(result);
    }
}

The example filters a list of person beans using the Apache CollectionUtils from the Apache Commons library.

List<Person> result = new ArrayList<>();
result.addAll(persons);

A new copy of the list is created.

CollectionUtils.filter(result, new Predicate() {

    @Override
    public boolean evaluate(Object o) {
        return ((Person) o).getAge() < 30;
    }

});

The CollectionUtils.filter() filters the collection by applying a predicate to each element. If the predicate returns false, the element is removed.

Filtering a list with Google Guava

In the third example, we filter a list using Google Guava. Google Guava is an open-source set of common libraries for Java.

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>19.0</version>
</dependency>

For the Guava library, we use this dependency.

Person.java
package com.zetcode;

import com.google.common.base.MoreObjects;

enum Gender {
    MALE, FEMALE
};

public class Person {

    private int age;
    private String name;
    private Gender sex;

    public Person(int age, String name, Gender sex) {
        this.age = age;
        this.name = name;
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Gender getSex() {
        return sex;
    }

    public void setSex(Gender sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {

        return MoreObjects.toStringHelper(Person.class)
                .add("Age", age)
                .add("Name", name)
                .add("Sex", sex)
                .toString();
    }
}

The MoreObjects.toStringHelper() is used to improve the toString() method.

FilterListEx3.java
package com.zetcode;

import com.google.common.base.Functions;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Lists;
import java.util.List;

public class FilterListEx3 {

    public static void main(String[] args) {

        List<Person> persons = Lists.newArrayList(
                new Person(34, "Michael", Gender.MALE),
                new Person(17, "Jane", Gender.FEMALE),
                new Person(28, "John", Gender.MALE),
                new Person(47, "Peter", Gender.MALE),
                new Person(27, "Lucy", Gender.FEMALE)
        );

        Predicate<Person> byGender = person -> person.getSex() == Gender.MALE;

        List<Person> results = FluentIterable.from(persons)
                .filter(byGender)
                .toList();

        System.out.println(results);
    }
}

The code example filters a list to contain only males.

List<Person> persons = Lists.newArrayList(
        new Person(34, "Michael", Gender.MALE),
        new Person(17, "Jane", Gender.FEMALE),
        new Person(28, "John", Gender.MALE),
        new Person(47, "Peter", Gender.MALE),
        new Person(27, "Lucy", Gender.FEMALE)
);

We use Guava's newArrayList() method to create a mutable list in one shot.

Predicate<Person> byGender = person -> person.getSex() == Gender.MALE;

This predicate returns true for males.

List<Person> results = FluentIterable.from(persons)
        .filter(byGender)
        .toList();

Using a FluentIterable, we filter the original list using the predicate and place it into a new list.

Filtering a list with Java 8 streams

In the next example, we use a Java 8 stream API to filter a list.

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.10</version>
    <scope>provided</scope>
</dependency>

In this example, we also use the Lombok library. The Lombok is used to reduce boilerplate code.

Person.java
package com.zetcode;

import lombok.AllArgsConstructor;
import lombok.Data;

enum Gender {
    MALE, FEMALE
};

@Data
@AllArgsConstructor
public class Person {

    private int age;
    private String name;
    private Gender sex;
}

Using the @Data and @AllArgsConstructor annotations, the getter and setter methods, equals() method, toString() method, hashCode() method, and constructor with all arguments are automatically created.

FilterListEx4.java
package com.zetcode;

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class FilterListEx4 {

    public static void main(String[] args) {

        Person p1 = new Person(34, "Michael", Gender.MALE);
        Person p2 = new Person(17, "Jane", Gender.FEMALE);
        Person p3 = new Person(28, "John", Gender.MALE);
        Person p4 = new Person(47, "Peter", Gender.MALE);
        Person p5 = new Person(27, "Lucy", Gender.FEMALE);

        List<Person> persons = Arrays.asList(p1, p2, p3, p4, p5);
        
        Predicate<Person> byAge = person -> person.getAge() > 30;

        List<Person> result = persons.stream().filter(byAge).collect(Collectors.<Person> toList());

        System.out.println(result);
    }
}

The Java stream API is used to filter data to contain only persons older than thirty.

Predicate<Person> byAge = person -> person.getAge() > 30;

This predicate returns elements with age greater than thirty.

List<Person> result = persons.stream().filter(byAge).collect(Collectors.<Person> toList());

The persons list is filtered with the predicate and a new result list is produced.

Filtering a list with JOQuery

JOQuery allows to use SQL style querying on Java collections. The syntax is easy to use and the library has a small footprint. We need to download the sources from https://github.com/Adipa-G/joquery and build the JAR files with Ant.

Project structure
Figure: Project structure

The figure shows the project structure in NetBeans. The project has two JARs of the JOQuery library.

The project also contains the Person.java file, which can be found in the first example of this tutorial.

FilterListEx5.java
package com.zetcode;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import joquery.CQ;
import joquery.Filter;
import joquery.core.QueryException;

public class FilterListEx5 {

    public static void main(String[] args) throws QueryException {
        
        Person p1 = new Person(34, "Michael", Gender.MALE);
        Person p2 = new Person(17, "Jane", Gender.FEMALE);
        Person p3 = new Person(28, "John", Gender.MALE);
        Person p4 = new Person(47, "Peter", Gender.MALE);
        Person p5 = new Person(27, "Lucy", Gender.FEMALE);

        List<Person> persons = Arrays.asList(p1, p2, p3, p4, p5);

        Filter<Person> query = CQ.<Person>filter()
                .from(persons)
                .where()
                .property(Person::getAge).lt().value(30);

        Collection<Person> result = query.list();
        
        System.out.println(result);
    }
}

The code example filters data to contain only persons younger than thirty.

Filtering a list with Eclipse Collections

In the following example, we are going to filter a list with Eclipse Collections.

Eclipse Collections is a collections framework for Java. It has JDK-compatible List, Set and Map implementations with a rich API, additional types not found in the JDK like Bags, Multimaps and set of utility classes that work with any JDK compatible Collections, Arrays, Maps or Strings.

<dependency>
    <groupId>org.eclipse.collections</groupId>
    <artifactId>eclipse-collections-api</artifactId>
    <version>7.1.0</version>
</dependency>

<dependency>
    <groupId>org.eclipse.collections</groupId>
    <artifactId>eclipse-collections</artifactId>
    <version>7.1.0</version>
</dependency> 

For the program, we use these two Mave dependencies.

The project also contains the Person.java file, which can be copied from the first example of this tutorial.

FilterListEx6.java
package com.zetcode;

import java.util.List;
import org.eclipse.collections.api.block.predicate.Predicate;
import org.eclipse.collections.api.list.ImmutableList;
import org.eclipse.collections.impl.factory.Lists;
import org.eclipse.collections.impl.utility.Iterate;

public class FilterListEx6 {

    public static void main(String[] args) {

        ImmutableList<Person> persons = Lists.immutable.of(
                new Person(34, "Michael", Gender.MALE),
                new Person(17, "Jane", Gender.FEMALE),
                new Person(28, "John", Gender.MALE),
                new Person(47, "Peter", Gender.MALE),
                new Person(27, "Lucy", Gender.FEMALE)
        );

        Predicate<Person> lessThan30 = new Predicate<Person>() {
            @Override
            public boolean accept(Person person) {
                return person.getAge() < 30;
            }
        };
        
        List<Person> result = (List<Person>) Iterate.select(persons, lessThan30);
        System.out.println(result);
    }
}

The code example creates a filtered list containing persons younger than thirty.

Predicate<Person> lessThan30 = new Predicate<Person>() {
    @Override
    public boolean accept(Person person) {
        return person.getAge() < 30;
    }
};

A predicate is created to accept elements whose age is lower than thirty.

List<Person> result = (List<Person>) Iterate.select(persons, lessThan30);

The Iterate.select() returns a new collection with only the elements that evaluated to true for the specified predicate.

Filtering a list with Spring's CollectionUtils

In the next example, we are going to filter a list with Spring's CollectionUtils. It contains miscellaneous collection utility methods.

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.3.2.RELEASE</version>
</dependency>

The project contains a Maven dependency for the Spring Core JAR.

We also use a Person.java file, which can be copied from the first example of this tutorial.

FilterListEx7.java
package com.zetcode;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.springframework.cglib.core.CollectionUtils;
import org.springframework.cglib.core.Predicate;

public class FilterListEx7 {

    public static void main(String[] args) {

        Person p1 = new Person(34, "Michael", Gender.MALE);
        Person p2 = new Person(17, "Jane", Gender.FEMALE);
        Person p3 = new Person(28, "John", Gender.MALE);
        Person p4 = new Person(47, "Peter", Gender.MALE);
        Person p5 = new Person(27, "Lucy", Gender.FEMALE);

        List<Person> persons = Arrays.asList(p1, p2, p3, p4, p5);
        
        List<Person> result = new ArrayList();
        result.addAll(persons);

        CollectionUtils.filter(result, p -> ((Person) p).getAge() > 30);

        System.out.println(result);
    }
}

The code example uses Spring's CollectionUtils to create a filtered list which contains persons older than thirty.

List<Person> result = new ArrayList();
result.addAll(persons);

Similar to the Apache CollectionUtils, a copy of the original list is created. The example will modify the result list in place.

CollectionUtils.filter(result, p -> ((Person) p).getAge() > 30);

The CollectionUtils.filter() method filters the result list with the given predicate.

[Person{age=34, name=Michael, sex=MALE}, Person{age=47, name=Peter, sex=MALE}]

This is the output of the example.

In this article, we have used seven different ways to filter a list in Java.

You might also be interested in the following related tutorials: Java ArrayList tutorial, Opencsv tutorial, Java tutorial, Reading text files in Java, Reading a web page in Java, or Introduction to Google Guava.