Searching a List in Java

Easily search a java list using java 8 predicate functions.

“Make improvements, not excuses. Seek respect, not attention.”
― Roy T. Bennett, The Light in the Heart

1. Introduction

Searching, sorting and iterating are some of the fundamental operations required when using a list. Searching refers to finding one or more objects in the list that match a given condition. In this article, we look at some methods for searching a list in java.

2. Using contains()

The simplest method to search for an object within a List (or any Collection) is to use the method contains(). It returns true when an object is found in the list that matches the target according to the equals() method.

List fruits = Arrays.asList("apple", "orange", "grape",
                    "banana", "melon");
System.out.println("t1: " + fruits);
String trg = "grape";
System.out.println("found \"" + trg + "\": " + fruits.contains(trg));
trg = "pear";
System.out.println("found \"" + trg + "\": " + fruits.contains(trg));
# prints
t1: [apple, orange, grape, banana, melon]
found "grape": true
found "pear": false

3. Finding the Location

While contains() just tells you whether the object is present in the list, you can use indexOf() to find the location of the object in the list. The method returns the index of the object if found, -1 otherwise.

List fruits = Arrays.asList("apple", "orange", "grape",
                    "banana", "melon");
System.out.println("t2: " + fruits);
String trg = "grape";
System.out.println("index of \"" + trg + "\": " + fruits.indexOf(trg));
trg = "pear";
System.out.println("index of \"" + trg + "\": " + fruits.indexOf(trg));
# prints
t2: [apple, orange, grape, banana, melon]
index of "grape": 2
index of "pear": -1

Note that indexOf() returns the index of the first object in the list that matches. Use lastIndexOf() to search from the end of the list. The following code illustrates the difference.

List fruits = Arrays.asList("apple", "orange", "grape",
                    "banana", "apple", "melon");
System.out.println("t3: " + fruits);
String trg = "apple";
System.out.println("index of \"" + trg + "\": " + fruits.indexOf(trg));
System.out.println("last index \"" + trg + "\": " + fruits.lastIndexOf(trg));
# prints
t3: [apple, orange, grape, banana, apple, melon]
index of "apple": 0
last index "apple": 4

4. Search Using Lambdas

The method indexOf() presented above returns the location of the first match only. Likewise, lastIndexOf() returns the location of the last match only. What if you want all the matching objects in the list? Here is one way to do that using java 8 streams.

Declare a Predicate function:

Predicate f1 = x -> x.equals("apple");

Stream the list, apply a filter and collect the result which is a list of strings matching the predicate.

List fruits = Arrays.asList("apple", "orange", "grape",
                    "banana", "apple", "melon");
System.out.println("t1: " + fruits);
List res = fruits
    .stream()
    .filter(f1)
    .collect(Collectors.toList());
System.out.println("t2: " + res);
# prints
t1: [apple, orange, grape, banana, apple, melon]
t2: [apple, apple]

Unlike the above examples with contains() and indexOf(), you can select items from the list based on whatever condition you want. Here is an example for selecting strings from a list with a sub-string match.

Predicate f1 = x -> x.contains("ap");
...
# prints
[apple, grape, apple]

Using lambdas offer a lot of flexibility in combining conditions for search. Here we combine two conditions with an and().

Predicate f1 = x -> x.contains("o");
Predicate f2 = x -> x.length() > 5;
System.out.println("t9: " + fruits
           .stream()
           .filter(f2)
           .collect(Collectors.toList()));
System.out.println("t10: " + fruits
           .stream()
           .filter(f1.and(f2))
           .collect(Collectors.toList()));
# prints
t9: [orange, banana]
t10: [orange]

Review

In this article, we learnt about some ways to search a list in java. The methods indexOf() and lastIndexOf() tells you the location of the first or last match. For more flexible search conditions, you can use java 8 streams with a Predicate function.