问题
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