Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java List.contains(Object with field value equal to x)

People also ask

How do you check if a list of objects contains a value in Java?

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.

Does list contain equals in Java?

From Java Doc, the contains() method returns true if and only if this set contains an element e such that (o==null ? e==null : o. equals(e)). So the contains() method actually use equals() method to check equality.

How do you check if an object is present in a list in Java?

contains() method can be used to check if a Java ArrayList contains a given item or not. This method has a single parameter i.e. the item whose presence in the ArrayList is tested. Also it returns true if the item is present in the ArrayList and false if the item is not present.

How do you check if an array of objects contains a value in Java?

We can use Arrays class to get the list representation of the array. Then use the contains() method to check if the array contains the value.


Streams

If you are using Java 8, perhaps you could try something like this:

public boolean containsName(final List<MyObject> list, final String name){
    return list.stream().filter(o -> o.getName().equals(name)).findFirst().isPresent();
}

Or alternatively, you could try something like this:

public boolean containsName(final List<MyObject> list, final String name){
    return list.stream().map(MyObject::getName).filter(name::equals).findFirst().isPresent();
}

This method will return true if the List<MyObject> contains a MyObject with the name name. If you want to perform an operation on each of the MyObjects that getName().equals(name), then you could try something like this:

public void perform(final List<MyObject> list, final String name){
    list.stream().filter(o -> o.getName().equals(name)).forEach(
            o -> {
                //...
            }
    );
}

Where o represents a MyObject instance.

Alternatively, as the comments suggest (Thanks MK10), you could use the Stream#anyMatch method:

public boolean containsName(final List<MyObject> list, final String name){
    return list.stream().anyMatch(o -> o.getName().equals(name));
}

You have two choices.

1. The first choice, which is preferable, is to override the `equals()` method in your Object class.

Let's say, for example, you have this Object class:

public class MyObject {
    private String name;
    private String location;
    //getters and setters
}

Now let's say you only care about the MyObject's name, that it should be unique so if two `MyObject`s have the same name they should be considered equal. In that case, you would want to override the `equals()` method (and also the `hashcode()` method) so that it compares the names to determine equality.

Once you've done this, you can check to see if a Collection contains a MyObject with the name "foo" by like so:

MyObject object = new MyObject();
object.setName("foo");
collection.contains(object);

However, this might not be an option for you if:

  • You are using both the name and location to check for equality, but you only want to check if a Collection has any `MyObject`s with a certain location. In this case, you've already overridden `equals()`.
  • `MyObject` is part of an API that you don't have liberty to change.

If either of these are the case, you'll want option 2:

2. Write your own utility method:

public static boolean containsLocation(Collection<MyObject> c, String location) {
    for(MyObject o : c) {
        if(o != null && o.getLocation.equals(location)) {
            return true;
        }
    }
    return false;
}

Alternatively, you could extend ArrayList (or some other collection) and then add your own method to it:

public boolean containsLocation(String location) {
    for(MyObject o : this) {
        if(o != null && o.getLocation.equals(location)) {
                return true;
            }
        }
        return false;
    }

Unfortunately there's not a better way around it.


This is how to do it using Java 8+ :

boolean isJohnAlive = list.stream().anyMatch(o -> o.getName().equals("John"));

Google Guava

If you're using Guava, you can take a functional approach and do the following

FluentIterable.from(list).find(new Predicate<MyObject>() {
   public boolean apply(MyObject input) {
      return "John".equals(input.getName());
   }
}).Any();

which looks a little verbose. However the predicate is an object and you can provide different variants for different searches. Note how the library itself separates the iteration of the collection and the function you wish to apply. You don't have to override equals() for a particular behaviour.

As noted below, the java.util.Stream framework built into Java 8 and later provides something similar.


Collection.contains() is implemented by calling equals() on each object until one returns true.

So one way to implement this is to override equals() but of course, you can only have one equals.

Frameworks like Guava therefore use predicates for this. With Iterables.find(list, predicate), you can search for arbitrary fields by putting the test into the predicate.

Other languages built on top of the VM have this built in. In Groovy, for example, you simply write:

def result = list.find{ it.name == 'John' }

Java 8 made all our lives easier, too:

List<Foo> result = list.stream()
    .filter(it -> "John".equals(it.getName())
    .collect(Collectors.toList());

If you care about things like this, I suggest the book "Beyond Java". It contains many examples for the numerous shortcomings of Java and how other languages do better.


Binary Search

You can use Collections.binarySearch to search an element in your list (assuming the list is sorted):

Collections.binarySearch(list, new YourObject("a1", "b",
                "c"), new Comparator<YourObject>() {

            @Override
            public int compare(YourObject o1, YourObject o2) {
                return o1.getName().compareTo(o2.getName());
            }
        });

which will return a negative number if the object is not present in the collection or else it will return the index of the object. With this you can search for objects with different searching strategies.


Map

You could create a Hashmap<String, Object> using one of the values as a key, and then seeing if yourHashMap.keySet().contains(yourValue) returns true.