This example will demonstrate how to filter a collection using java, java 8, guava and apache commons. In the snippets, we have created a NFLTeam class which we will filter all teams that have won a super bowl. A alternate example shows how to filter a list of objects by field in groovy.
An alternate /java/examples/filter-a-collection/
Setup
class NFLTeam {
private String name;
private boolean hasWonSuperBowl;
public NFLTeam(String name, boolean hasWonSuperBowl) {
super();
this.name = name;
this.hasWonSuperBowl = hasWonSuperBowl;
}
@Override
public String toString() {
return Objects.toStringHelper(NFLTeam.class)
.add("name", name)
.add("wonsuperbow", hasWonSuperBowl)
.toString();
}
public String getName() {
return name;
}
public boolean hasWonSuperBowl() {
return hasWonSuperBowl;
}
}
Straight up Java
Until Java 8, the jdk lacks a mechanism for filtering collections. The only way is to iterate over the collection and then apply criteria. In the snippet below, we will use a enhanced for loop and check if the NFLTeam has won a superbowl.
@Test
public void filter_items_in_list_with_java () {
List<NFLTeam> nflTeams = Lists.newArrayList();
nflTeams.add(new NFLTeam("Green Bay Packers", true));
nflTeams.add(new NFLTeam("Chicago Bears", true));
nflTeams.add(new NFLTeam("Detroit Lions", false));
Collection<NFLTeam> superBowlWinners = new ArrayList<NFLTeam>();
for (NFLTeam team : nflTeams) {
if (team.hasWonSuperBowl) {
superBowlWinners.add(team);
}
}
logger.info(superBowlWinners);
assertTrue(superBowlWinners.size() == 2);
}
Output
[NFLTeam{name=Green Bay Packers, wonsuperbow=true}, NFLTeam{name=Chicago Bears, wonsuperbow=true}]
Java 8
Java 8 introduced the stream api which allows you to write powerful code in just a few lines. Streams.filter is an intermediate operation that will return a stream consisting of the elements that match the specified predicate. In the snippet below, through a lambda expression we will create a java predicate that will filter all the NFLTeams that have won a superbowl.
@Test
public void filter_items_in_list_with_java8_lambda () {
List<NFLTeam> nflTeams = Lists.newArrayList();
nflTeams.add(new NFLTeam("Green Bay Packers", true));
nflTeams.add(new NFLTeam("Chicago Bears", true));
nflTeams.add(new NFLTeam("Detroit Lions", false));
List<NFLTeam> superBowlWinners = nflTeams
.stream()
.filter(p -> p.hasWonSuperBowl)
.collect(Collectors.toList());
assertTrue(superBowlWinners.size() == 2);
}
Output
[NFLTeam{name=Green Bay Packers, wonsuperbow=true}, NFLTeam{name=Chicago Bears, wonsuperbow=true}]
Google Guava
Guava Collections2 utility class contains a filter method that encapsulates the looping shown in the straight up java example above. In the snippet below we will create a guava predicate that will return true if the NFLTeam has won a superbowl. Then we will pass the predicate to Collections2.filter which will return the elements that satisfy the predicate.
@Test
public void filter_items_in_list_with_guava () {
List<NFLTeam> nflTeams = Lists.newArrayList();
nflTeams.add(new NFLTeam("Green Bay Packers", true));
nflTeams.add(new NFLTeam("Chicago Bears", true));
nflTeams.add(new NFLTeam("Detroit Lions", false));
Collection<NFLTeam> superBowlWinners = Collections2.filter(nflTeams, new Predicate<NFLTeam> () {
public boolean apply(NFLTeam nflTeam) {
return nflTeam.hasWonSuperBowl;
}
});
logger.info(superBowlWinners);
assertTrue(superBowlWinners.size() == 2);
}
Output
[NFLTeam{name=Green Bay Packers, wonsuperbow=true}, NFLTeam{name=Chicago Bears, wonsuperbow=true}]
Apache Commons
Similar to guava and java predicate, apache commons has a predicate class as well. Below we will call CollectionsUtils.filter passing it a predicate that will return true if the NFLTeam has won a super bowl and it will remove the elements where it doesn't match this criteria.
@Test
public void filter_items_in_list_with_apache_commons () {
List<NFLTeam> nflTeams = Lists.newArrayList();
nflTeams.add(new NFLTeam("Green Bay Packers", true));
nflTeams.add(new NFLTeam("Chicago Bears", true));
nflTeams.add(new NFLTeam("Detroit Lions", false));
CollectionUtils.filter(nflTeams, new org.apache.commons.collections.Predicate() {
public boolean evaluate(Object nflTeam) {
return ((NFLTeam) nflTeam).hasWonSuperBowl;
}
});
logger.info(nflTeams);
assertTrue(nflTeams.size() == 2);
}
Output
[NFLTeam{name=Green Bay Packers, wonsuperbow=true}, NFLTeam{name=Chicago Bears, wonsuperbow=true}]