How to properly implement equals in Java

笑着哭i 提交于 2019-12-20 05:55:57

问题


I need to implement the equals method in some class A. Class A has an orderer collection of Enum type, and the behaviour I want to achive is that equals returns true for two instances of Class A that have exactly the same Enum values in the collection (in exactly the same positions of the collection).

As I'm new to java, I'm having problems with this, and I dont know how to properly implement equals or the hashcode methods, so any help would be good :)


回答1:


If you're using eclipse (netbeans has similar features, as do most java IDEs), you can simply got to the "Source" menu, and choose "Generate hashcode() and equals()". Then you select the fields you want to be considered (in your case the list of enum values.

That being said, assuming you already have the enum, here's the code that eclipse generated for me. Not that hashcode usually involves a prime number, as well as multiplication and addition. This tends to give you somewhat decent distribution of values.

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


}



回答2:


The overridden equals method will look like this

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

The overridden hashCode method will look like this

public int hashCode() { return anIntRepresentingTheHashCode} 

Pulling from the javadocs, your equals method must meet the following criteria:

reflexive - x.equals(x) is true

symmetric - if x.equals(y) then y.equals(x)

transitive - if x.equals(y) and y.equals(z) then x.equals(z)

consistent - if x.equals(y) is true, then it's always true unless the object is modified

null - x.equals(null) is false

Also, if two objects are equal based on the equals method, they must have identical hash codes.

The reverse is not true. If two objects are not equal, they may or may not have identical hash codes




回答3:


Use EnumSet It retains natural order as per java docs also and it is optimized for Enums only.

The iterator returned by the iteratormethod traverses the elements in their natural order (the order in which the enum constants are declared). The returned iterator is weakly consistent: it will never throw ConcurrentModificationException and it may or may not show the effects of any modifications to the set that occur while the iteration is in progress.

You can use EnumSet as below

import java.util.EnumSet;

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

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

Now because you are using EnumSet equals and Hashcode method will be provided default from AbstractSet which is parent class of EnumSet So You don't have to care about them.



来源:https://stackoverflow.com/questions/12008164/how-to-properly-implement-equals-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!