我正在处理一个项目,许多类需要适当的典型实现equals
和hashCode
:每个类都有一组在构造时初始化的“深度”不可变对象(在某些情况下可以接受null
),用于哈希和比较。
为了减少样板代码的数量,我考虑编写一个抽象类,提供这种行为的常见实现。
public abstract class AbstractHashable {
/** List of fields used for comparison. */
private final Object[] fields;
/** Precomputed hash. */
private final int hash;
/**
* Constructor to be invoked by subclasses.
* @param fields list of fields used for comparison between objects of this
* class, they must be in constant number for each class
*/
protected AbstractHashable(Object... fields) {
this.fields = fields;
hash = 31 * getClass().hashCode() + Objects.hash(fields);
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null || !getClass().equals(obj.getClass())) {
return false;
}
AbstractHashable other = (AbstractHashable) obj;
if (fields.length != other.fields.length) {
throw new UnsupportedOperationException(
"objects of same class must have the same number of fields");
}
for (int i=0; i<fields.length; i++) {
if (!fields[i].equals(other.fields[i])) {
return false;
}
}
return true;
}
@Override
public int hashCode() {
return hash;
}
}
这是打算这样使用的:
public class SomeObject extends AbstractHashable {
// both Foo and Bar have no mutable state
private final Foo foo;
private final Bar bar;
public SomeObject(Foo foo, Bar bar) {
super(foo, bar);
this.foo = Objects.requireNonNull(foo);
this.bar = bar; // null supported
}
// other methods, no equals or hashCode needed
}
这基本上是与此处提出的方案有所不同,但与之相似。
这对我来说是一种简单而好的方法,可以减少冗余,并仍然具有equals
和hashCode
的高效实现。然而,由于我不记得曾经见过类似的东西(除了上面链接的答案),在将其应用到整个项目之前,我想特别询问是否有反对这种方法的观点(或者可能适用的改进方法)。
equals
和hashCode
的重用更重要吗? - Chetan Kinger