How to Check if a List Contains an Object with a Field of a Certain Value in Java


How can we check if a collection in Java contains an object with a field of a certain value?

Suppose we’re working with a collection called list.

List<CustomObject> list = new ArrayList<>();

Let’s say our CustomObject class contains a name attribute.

public class CustomObject {
  private String name;
  public CustomObject(String name) {
    this.name = name;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
}

We want to check if list contains an object CustomObject with the name attribute of Max.

CustomObject obj = new CustomObject();
obj.setName("Max");

It doesn’t seem like we can just use list.contains(obj), so what can we do?

Override the equals() method

If possible, the preferable approach is to override the equals() method in our CustomObject class.

Overriding equals(), which is used in contains(), will compare the names of each CustomObject instance to determine equality.

public class CustomObject {
  // ...constructor, getters, setters...
  @Override
  public boolean equals(Object obj) {
    if (obj == this)
      return true; // Same object in memory
    if (!(obj instanceof CustomObject))
      return false; // Not even the same class
    final CustomObject other = (CustomObject) obj;
    return name.equals(other.getName());
  } 
  @Override
  public int hashCode() {
    return name.hashCode();
  }
  // ...other class methods...
}

We need to override hashCode() as well to return consistent values (i.e. if two objects are equal, they must have equal hash codes).

We can then use contains() to check if a collection contains an object with a specific attribute value.

list.contains(obj);

If we can’t override the equals() and hashCode() functions, we can check out the second approach.

Check using the Stream API (Java 8+)

We can use the Stream API to find whether the list contains an object with a specific value for the name attribute.

list.stream().anyMatch(o -> o.getName().equals(name));

If needed, we can filter out null values in the stream.

list.stream()
    .filter(Objects::nonNull)
    .anyMatch(o -> o.getName().equals(name));

If we want to do completely null-safe comparisons, we can use Object.equals().

list.stream().anyMatch(o -> Object.equals(o.getName(), name));