简体   繁体   中英

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

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()));
}

As JLS-8.4.8.1 specify

An instance method m1, declared in class C, overrides another instance method m2, declared in class A , if all of the following are true:

C is a subclass of A.

The signature of m1 is a subsignature  of the signature of m2.

Either:

m2 is public, protected, or declared with default access in the same package as C, or

m1 overrides a method m3 (m3 distinct from m1, m3 distinct from m2), such that m3 overrides m2.

Signature Must be same to override which in your case is ignored !!!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM