I am having an issue where I make an ArrayList of Foo objects, I override the equals method, and I cannot get the contains method to call the equals method. I have tried overriding equals and hashcode together, but it still doesn't work. I'm sure there is a logical explanation to why this is, but I cannot figure it out at the moment on my own lol. I just want a way to see if the list contains the specified id.
Here's some code:
import java.util.ArrayList;
import java.util.List;
public class Foo {
private String id;
public static void main(String... args){
Foo a = new Foo("ID1");
Foo b = new Foo("ID2");
Foo c = new Foo("ID3");
List<Foo> fooList = new ArrayList<Foo>();
fooList.add(a);
fooList.add(b);
fooList.add(c);
System.out.println(fooList.contains("ID1"));
System.out.println(fooList.contains("ID2"));
System.out.println(fooList.contains("ID5"));
}
public Foo(String id){
this.id = id;
}
@Override
public boolean equals(Object o){
if(o instanceof String){
String toCompare = (String) o;
return id.equals(toCompare);
}
return false;
}
@Override
public int hashCode(){
return 1;
}
}
OUTPUT: false false false
This is because your
equals()
is not symmetric:but
is not true. This violates the
equals()
contract:It is not reflexive either:
@mbockus provides correct implementation of
equals()
:but now you must pass instance of
Foo
tocontains()
:Finally you should implement
hashCode()
to provide consistent results (if two objects are equal, they must have equalhashCode()
):Your equals method needs to be altered along with overriding the hashCode() function. Currently you're checking to see if the object you're comparing to is an instanceof String, when you need to be checking for Foo objects.
If you're using Eclipse, I would recommend having Eclipse generate the hashCode and equals for you by going to Source -> Generate hashcode() and equals()...
You should implement hashCode
even though the contains works for ArrayList without it. Your big problems are that your equals expects String, not Foo objects and that you ask for contains with Strings. If the implementation asked each eject in the list if they were equal to the string you send, then your code could work, but the implementation asks the string if it is equal to your Foo objets which it of course isn't.
Use equals
and then check contains