简体   繁体   English

列表中的contains()方法无法按预期工作

[英]contains() method in List not working as expected

the api of contains() method says contains()方法的api说

"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)). " “如果此列表包含指定的元素,则返回true。更正式地说,当且仅当此列表包含至少一个元素e使得(o == null?e == null:o.equals(e))时,返回true。

I overrode the equals() method in my class but contains() still returns me false when i check 我在类中覆盖了equals()方法,但是当我检查时contains()仍返回false

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 现在,当我尝试此操作时,即使覆盖equals,它也会打印false

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. 您重载equals而不是覆盖equals To override Object 's equals method, you must use the same signature, which means the argument must be of Object type. 要覆盖Objectequals方法,必须使用相同的签名,这意味着参数必须为Object类型。

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 按照JLS-8.4.8.1的规定

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中声明的实例方法m1覆盖在类A中声明的另一个实例方法m2:

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 !!! 签名必须相同,才能覆盖您忽略的情况!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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