.contains() 方法不调用 Overridden equals 方法

2022-09-01 08:20:58

我遇到了一个问题,我制作了Foo对象的ArrayList,我覆盖了equals方法,并且我无法获取reclus方法来调用equals方法。我尝试过一起覆盖相等和哈希码,但它仍然不起作用。我确信有一个合乎逻辑的解释来解释为什么会这样,但我目前无法自己弄清楚。我只想要一种方法来查看列表是否包含指定的id。

下面是一些代码:

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

输出:假假假假


答案 1

这是因为您的不对称equals()

new Foo("ID1").equals("ID1");

"ID1".equals(new Foo("ID1"));

不是真的。这违反了 equals() 协定

equals 方法在非空对象引用上实现等价关系:

  • [...]

  • 它是对称的:对于任何非空引用值 和 ,当且仅当返回 时应返回 true。xyx.equals(y)y.equals(x)true

它也不是自反的

  • 它是自反的:对于任何非空引用值,应返回 true。xx.equals(x)
Foo foo = new Foo("ID1");
foo.equals(foo)  //false!

@mbockus提供了以下各项的正确实现:equals()

public boolean equals(Object o){
  if(o instanceof Foo){
    Foo toCompare = (Foo) o;
    return this.id.equals(toCompare.id);
  }
  return false;
}

但现在您必须将 的实例传递给 :Foocontains()

System.out.println(fooList.contains(new Foo("ID1")));
System.out.println(fooList.contains(new Foo("ID2")));
System.out.println(fooList.contains(new Foo("ID5")));

最后,您应该实现以提供一致的结果(如果两个对象相等,则它们必须相等):hashCode()hashCode()

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

答案 2

您的 equals 方法需要更改,同时覆盖 hashCode() 函数。目前,您正在检查要比较的对象是否是 String 的实例,当您需要检查 Foo 对象时。

public boolean equals(Object o){
    if(o instanceof Foo){
        Foo toCompare = (Foo) o;
        return this.id.equals(toCompare.id);
    }
    return false;
}

如果您使用的是 Eclipse,我建议让 Eclipse 生成 hashCode 和 equals,方法是转到 Source -> Generate hashcode() 和 equals()...