如何在Java中正确实现equals

如何在Java中正确实现equals,java,equals,hashcode,Java,Equals,Hashcode,我需要在某些类A中实现equals方法。类A有一个枚举类型的Order集合,我想要实现的行为是,对于集合中具有完全相同枚举值(在集合的完全相同位置)的类A的两个实例,equals返回true 由于我是java新手,我在这方面遇到了问题,我不知道如何正确地实现equals或hashcode方法,因此任何帮助都是好的:)覆盖的equals方法将如下所示 public boolean equals(Object o) { if ((o instanceof yourtype) &&am

我需要在某些类A中实现equals方法。类A有一个枚举类型的Order集合,我想要实现的行为是,对于集合中具有完全相同枚举值(在集合的完全相同位置)的类A的两个实例,equals返回true


由于我是java新手,我在这方面遇到了问题,我不知道如何正确地实现equals或hashcode方法,因此任何帮助都是好的:)

覆盖的equals方法将如下所示

public boolean equals(Object o) {
    if ((o instanceof yourtype) && 
        (((yourtype)o).getPropertyToTest() == this.propertyToTest)) {
        return true;
    }
    else {
        return false;
    }
}
public int hashCode() { return anIntRepresentingTheHashCode} 
重写的hashCode方法如下所示

public boolean equals(Object o) {
    if ((o instanceof yourtype) && 
        (((yourtype)o).getPropertyToTest() == this.propertyToTest)) {
        return true;
    }
    else {
        return false;
    }
}
public int hashCode() { return anIntRepresentingTheHashCode} 
从中提取,equals方法必须满足以下条件:

自反的-x.equals(x)是真的

对称-如果x等于(y),那么y等于(x)

可传递的-如果x等于(y)和y等于(z),那么x等于(z)

一致性-如果x.equals(y)为真,则除非修改对象,否则它始终为真

null-x.equals(null)为false

此外,如果两个对象基于equals方法相等,则它们必须具有相同的哈希代码

事实并非如此。如果两个对象不相等,那么它们可能有相同的哈希代码,也可能没有相同的哈希代码。如果您使用eclipse(netbeans和大多数java IDE具有类似的功能),您只需进入“源”菜单,选择“生成哈希代码()和等于()。然后选择要考虑的字段(在本例中为枚举值列表)

这就是说,假设您已经有了enum,下面是eclipse为我生成的代码。不是说hashcode通常包括素数,还有乘法和加法。这会给您一些不错的值分布

public class Foo {
   private List<FooEnum> enumValues;

   @Override
   public int hashCode() {
       final int prime = 31;
       int result = 1;
       result = prime * result
               + ((enumValues == null) ? 0 : enumValues.hashCode());
       return result;
   }

   @Override
   public boolean equals(Object obj) {
       if (this == obj)
           return true;
       if (obj == null)
           return false;
       if (getClass() != obj.getClass())
           return false;
       Foo other = (Foo) obj;
       if (enumValues == null) {
           if (other.enumValues != null)
               return false;
       }
       else if (!enumValues.equals(other.enumValues))
           return false;
       return true;
   }


}
公共类Foo{
私有列表枚举值;
@凌驾
公共int hashCode(){
最终整数素数=31;
int结果=1;
结果=素数*结果
+((enumValues==null)?0:enumValues.hashCode();
返回结果;
}
@凌驾
公共布尔等于(对象obj){
if(this==obj)
返回true;
if(obj==null)
返回false;
如果(getClass()!=obj.getClass())
返回false;
Foo其他=(Foo)obj;
如果(枚举值==null){
if(other.enumValues!=null)
返回false;
}
如果(!enumValues.equals(其他.enumValues))
返回false;
返回true;
}
}
使用它还保留了java文档中的自然顺序,并且它仅针对枚举进行了优化

迭代器方法返回的迭代器按元素的自然顺序(声明枚举常量的顺序)遍历元素。返回的迭代器弱一致性:它永远不会抛出ConcurrentModificationException,并且它可能会也可能不会显示在迭代过程中对集合进行的任何修改的效果

您可以如下使用
EnumSet

import java.util.EnumSet;

public enum Direction {
LEFT,
RIGHT,
ABOVE,
BELOW;

private static EnumSet<Direction> someDirection = EnumSet.of(Direction.LEFT,Direction.RIGHT) ;
}
import java.util.EnumSet;
公共枚举方向{
左边
正确的,
在上面
在下面
私有静态EnumSet someDirection=EnumSet.of(Direction.LEFT,Direction.RIGHT);
}
现在,因为您使用的是
EnumSet
equals,所以将从
AbstractSet
提供默认的Hashcode方法,它是
EnumSet
的父类
因此,您不必关心它们。

遵循本教程……仅当
propertyToTest
是一个基元时。如果它是一个引用对象,最好使用
.equals()
也比较它们。@X-Zero这是一个有效点。假设我们正在比较的属性是字符串类型。检查的实例后,可以说o.getProperty().equals(this.property)。请记住,测试多个属性也是合法的。您可以执行类似于o.getProperty1()==this.property 1和&o.getProperty2的操作()==this.property2…等