Will
Will

Reputation: 33

Check if a list of objects contains another object in Java

Why does ts.contains(t) return false and how can I fix it? Have a look at my code, please:

class MyList {
    private String x;

    public MyList (String x) {
        this .x = x;
    }

    public String toString () {
        return x;
    }   

    public static void main ( String [] args ) {
        List<MyList> ts = new ArrayList<MyList>();
        ts.add (new MyList ("one"));
        ts.add (new MyList ("two"));
        ts.add (new MyList ("three"));

        MyList t = new MyList("one");
        System.out.println ("Is t in ts? " + ts.contains(t));
    }
}

Thank you all for the help. Both SamzSakerz and michaeak answers work correctly.

Upvotes: 1

Views: 4941

Answers (5)

Wendel
Wendel

Reputation: 2977

I used Spring Collection Utils in my Java 6 legacy code:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import java.util.List;

import static java.util.Arrays.asList;
import static org.springframework.util.CollectionUtils.containsAny;

@RunWith(JUnit4.class)
public class JavaTest {
    
     @Test
     public void listContainsAny() {
         List<String> list = asList("one", "two", "three");
         assert containsAny(list, asList("one", "three"));
         assert containsAny(list, asList("two", "four"));
         assert !containsAny(list, asList("five", "six"));
     }
 }

Upvotes: 0

michaeak
michaeak

Reputation: 1679

Just implement the equals() method:

class MyList {
    private String x;

    public MyList (String x) {
        this .x = x;
    }

    @Override
    public String toString () {
        return x;
    }   


    public static void main ( String [] args ) {
        List<MyList> ts = new ArrayList<MyList>();
        ts.add (new MyList ("one"));
        ts.add (new MyList ("two"));
        ts.add (new MyList ("three"));

        MyList t = new MyList("one");
        System.out.println ("Is t in ts? " + ts.contains(t));
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((x == null) ? 0 : x.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        MyList other = (MyList) obj;
        if (x == null) {
            if (other.x != null) {
                return false;
            }
        } else if (!x.equals(other.x)) {
            return false;
        }
        return true;
    }
}

Output Is t in ts? true

The equals() Method is defined for the class Object which is the top class for every class. The contains() Method contractually checks, if the requested object a is contained in the list (i.e. same object is contained in a list) or if an equal object b (i.e. a.equals(b) is true) is contained in the list.

For List.contains(obj) the hashCode method is not required to be implemented, however, it is recommended to implement hashCode() whenever you implement equals() and make sure to depend on the same attributes in both methods.

Upvotes: 5

MC Emperor
MC Emperor

Reputation: 23047

You have to override the equals and hashCode methods.

contains relies on equals, and the default implementation of equals is that its identity is compared. Then equals only returns true if it is the very same object.

In order to implement the equals method, you have to decide when two objects are considered equal. In your case, I assume that if the object's only field s is equal to the other, then you want them to be considered equal.

More:

Upvotes: 3

SamHoque
SamHoque

Reputation: 3154

Like others have pointed you need to override equals and hashcode we can do this in 1 line.

@Override
public int hashCode() {
    return toString().hashCode();
}

@Override
public boolean equals(Object obj) {
    return this == obj || obj != null && getClass() == obj.getClass() && toString().equals(obj.toString());
}

and now the output we get is

Is t in ts? true

Here is the full code:

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

class MyList {
    private String x;

    public MyList(String x) {
        this.x = x;
    }

    public static void main(String[] args) {
        List<MyList> ts = new ArrayList<MyList>();
        ts.add(new MyList("one"));
        ts.add(new MyList("two"));
        ts.add(new MyList("three"));

        MyList t = new MyList("one");
        System.out.println("Is t in ts? " + ts.contains(t));
    }

    @Override
    public String toString() {
        return x;
    }

    @Override
    public int hashCode() {
        return toString().hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        return this == obj || obj != null && getClass() == obj.getClass() && toString().equals(obj.toString());
    }
}

Upvotes: 1

talex
talex

Reputation: 20542

You can check that list have object with specific property using

        System.out.println("Is t in ts? " + ts.stream().anyMatch(x -> x.x.equals("one")));

Upvotes: 2

Related Questions