javacollectionsjava-collections-api

contains() method in List not working as expected


the api of contains() method says

"Returns true if this list contains the specified element. More formally, returns true if and only if this list contains at least one element e such that (o==null ? e==null : o.equals(e)). "

I overrode the equals() method in my class but contains() still returns me false when i check

my code

class Animal implements Comparable<Animal>{
    int legs;
    Animal(int legs){this.legs=legs;}
    public int compareTo(Animal otherAnimal){
        return this.legs-otherAnimal.legs;
    }
    public String toString(){return this.getClass().getName();}

    public boolean equals(Animal otherAnimal){
        return (this.legs==otherAnimal.legs) && 
                (this.getClass().getName().equals(otherAnimal.getClass().getName()));
    }

    public int hashCode(){
        byte[] byteVal = this.getClass().getName().getBytes();
        int sum=0;
        for(int i=0, n=byteVal.length; i<n ; i++)
            sum+=byteVal[i];
        sum+=this.legs;
        return sum;
    }

}
class Spider extends Animal{
    Spider(int legs){super(legs);}
}
class Dog extends Animal{
    Dog(int legs){super(legs);}
}
class Man extends Animal{
    Man(int legs){super(legs);}
}

pardon the bad concept behind classes but i was just testing understanding of my concepts.

now when I try this, it prints false even though equals is overriden

List<Animal> li=new ArrayList<Animal>();
Animal a1=new Dog(4);
li.add(a1);
li.add(new Man(2));
li.add(new Spider(6));

List<Animal> li2=new ArrayList<Animal>();
Collections.addAll(li2,new Dog(4),new Man(2),new Spider(6));
System.out.println(li2.size());
System.out.println(li.contains(li2.get(0))); //should return true but returns false

Solution

  • You overloaded equals instead of overriding it. To override Object's equals method, you must use the same signature, which means the argument must be of Object type.

    Change to:

    @Override
    public boolean equals(Object other){
        if (!(other instanceof Animal))
            return false;
        Animal otherAnimal = (Animal) other;
        return (this.legs==otherAnimal.legs) && 
               (this.getClass().getName().equals(otherAnimal.getClass().getName()));
    }