问题
So I have many custom classes are also have custom clases inside of them using composition.
My custom classes have variables that change very frequently and I add them to HashSets. So my question is when I implement hashCode - what should I do for a class that only has private fields that constantly change?
Here is an example of one custom class:
public class Cell {
protected boolean isActive;
protected boolean wasActive;
public Cell() {
this.isActive = false;
this.wasActive = false;
}
// getter and setter methods...
@Override
public int hashCode() {
// HOW SHOULD I IMPLEMENT THIS IF THIS custom object is constantly
// being added into HashSets and have it's private fields isActive
// and wasActive constantly changed.
}
// ANOTHER QUESTION Am I missing anything with this below equals implementation?
@Override
public boolean equals(Object object) {
boolean result = false;
if (object instanceof Cell) {
Cell otherCell = (Cell) object;
result = (this.isActive == otherCell.isActive && this.wasActive ==
otherCell.wasActive);
}
return result;
}
回答1:
Equals and hashCode contract in Java:
We must override hashCode() when we override equals() method, equals method in Java must follow its contract with hashCode method in Java as stated below.
- If two objects are equal by equals() method then there hashcode must be same.
- If two objects are not equal by equals() method then there hashcode could be same or different.
These are sample implementation of equals and hashcode methods for your class:
//Hashcode Implementation
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + (isActive ? 1231 : 1237);
result = prime * result + (wasActive ? 1231 : 1237);
return result;
}
//equals Implementation
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Cell other = (Cell) obj;
if (isActive != other.isActive)
return false;
if (wasActive != other.wasActive)
return false;
return true;
}
回答2:
You are SOL. Where hashCode() is used in a key in standard Java collections, it should not change. Or else you need a custom HashSet-like implementation.
Use only non-changing fields (or, if you are daring and don't mind occasional crashes, very rarely changing fields) to calculate hashCode().
(Added). In your particular example, use Object.hashCode().
(Added #2) Even if your Cell class were immutable (the two booleans didn't change) it makes a poor choice for hashing, because it only has 2 bits of range. Imagine hashing all people by whether they are male/female and blue eyes / brown eyes. A very good start, but there's only 4 categories, and there will be like 2 billion people in each one. Ideally, you'd have several other categories, like year of birth, country of birth, etc.
回答3:
Here is the example of class which has private fields.
public class Test {
private int num;
private String data;
public boolean equals(Object obj) {
if (this == obj)
return true;
if ((obj == null) || (obj.getClass() != this.getClass()))
return false;
// object must be Test at this point
Test test = (Test) obj;
return num == test.num
&& (data == test.data || (data != null && data
.equals(test.data)));
}
public int hashCode() {
int hash = 7;
hash = 31 * hash + num;
hash = 31 * hash + (null == data ? 0 : data.hashCode());
return hash;
}
}
来源:https://stackoverflow.com/questions/17801611/implementing-hashcode-and-equals-for-custom-classes