如何在Java中正确实现equals

时间:2012-08-17 14:56:13

标签: java equals hashcode

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

由于我是java的新手,我遇到了这个问题,我不知道如何正确实现equals或hashcode方法,所以任何帮助都会很好:)

3 个答案:

答案 0 :(得分:1)

如果您正在使用eclipse(netbeans具有与大多数Java IDE类似的功能),您只需进入“Source”菜单,然后选择“Generate hashcode()和equals()”。然后选择要考虑的字段(在您的情况下是枚举值列表。

话虽如此,假设你已经拥有枚举,这里是eclipse为我生成的代码。不是哈希码通常涉及素数,以及乘法和加法。这往往会给你一些不错的价值分配。

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


}

答案 1 :(得分:0)

重写的equals方法将如下所示

public boolean equals(Object o) {
    if ((o instanceof yourtype) && 
        (((yourtype)o).getPropertyToTest() == this.propertyToTest)) {
        return true;
    }
    else {
        return false;
    }
}

重写的hashCode方法将如下所示

public int hashCode() { return anIntRepresentingTheHashCode} 

javadocs拉出,您的等于方法必须符合以下条件:

  

反身 - x.equals(x)为真

     

对称 - 如果x.equals(y)则y.equals(x)

     

传递 - 如果x.equals(y)和y.equals(z)则x.equals(z)

     

一致 - 如果x.equals(y)为true,那么除非对象被修改,否则它总是为真

     

null - x.equals(null)为false

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

反之则不然。如果两个对象不相等,则它们可能具有相同的哈希码,也可能不具有相同的哈希码

答案 2 :(得分:0)

使用EnumSet它也保留了自然顺序,根据java文档,它仅针对枚举进行了优化。

  

iteratormethod返回的迭代器以自然顺序遍历元素(枚举常量的声明顺序)。返回的迭代器是弱一致的:它永远不会抛出ConcurrentModificationException,它可能会也可能不会显示迭代进行过程中对集合所做的任何修改的影响。

您可以使用EnumSet,如下所示

import java.util.EnumSet;

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

private static EnumSet<Direction> someDirection = EnumSet.of(Direction.LEFT,Direction.RIGHT) ;
}

现在,因为您使用的是EnumSet等号,Hashcode方法将默认来自AbstractSet EnumSet的父类 所以你不必关心它们。