我在其中一个对象(hashCode()
)中使用重写instance of A
来为该对象生成唯一的整数ID。唯一性仅取决于instances of B
(ArrayList
)中的元素(I
)。
以下是I
:
public class I extends ArrayList<B> {
//object of this class will iterate over this array
private B[] arrayOfB;
//other methods and variable to do something
...
}
班级B
的定义
public class B {
private SomeEnum type;
private Object value; //this can be Integer, String, or some object defined by me
//getters for both private variables
...
}
班级A
的定义
public class C implements Iterable {
private I myIterable;
@Override
public int hashCode() {
int result = 17;
for(B b: myIterable) {
result = 31 * result + b.getType().hashCode();
result = 31 * result + b.getValue().hashCode();
}
return result;
}
//other methods for this class
...
}
如您所见,我迭代myIterable
中的所有对象并构建最终hash
。结果取决于type
中每个 b 中包含的value
和myIterable
。我注意到的是,这个值随着程序的不同运行而变化,这会在程序创建重复的对象时产生问题。
我可以为相关的枚举实现hashCode(),但我想知道是否还有其他方法来处理这个问题。以下是我的问题:
注意:我知道我的A.hashCode()
实现会根据myIterable
中 b 的顺序返回不同的哈希值,这是不可取的。我正在修理它,以便订单不重要。
答案 0 :(得分:2)
因此,无论顺序如何,您都会得到不同的结果(例如,这些hashCodes是单独计算的)? 来自hashCode文档http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#hashCode%28%29:
每当在执行Java应用程序期间多次在同一对象上调用它时,hashCode方法必须始终返回相同的整数,前提是不修改对象的equals比较中使用的信息。从应用程序的一次执行到同一应用程序的另一次执行,此整数不需要保持一致。
从理论上讲,这似乎是可能的。但是,我认为这将是非标准的实施。这是实际的源代码(openjdk7):
答案 1 :(得分:1)
可以做什么和什么有用之间存在差异。
您可以子类化(如您所做)并使hashCode()
根据当前字段设置返回不同的值。从某种意义上说,这实际上是一件好事。如果两个对象的值不同,那么它们应该返回不同的hashCodes。
但是,你正在做的是让一个对象改变它自己的相等性。你没有两个相等的对象,你有一个对象决定它不等于“它的旧自我”,并且可能不等于它的未来自我。
这在Java世界中只是毫无意义,因为没有任何集合会监视其成员是否有相同的变化(对某些集合的要求,例如地图)。
简而言之,hashCode()
提供了一种改变平等确定方式的方法,但不是创建不遵循平等定义的新数学属性的方法。您需要在程序执行的整个过程中保持A = A
(在某些情况下甚至更长)。