对于枚举值,hashCode()的返回值是否随运行时而变化

时间:2013-07-15 18:29:05

标签: java hashcode

我在其中一个对象(hashCode())中使用重写instance of A来为该对象生成唯一的整数ID。唯一性仅取决于instances of BArrayList)中的元素(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 中包含的valuemyIterable。我注意到的是,这个值随着程序的不同运行而变化,这会在程序创建重复的对象时产生问题。

我可以为相关的枚举实现hashCode(),但我想知道是否还有其他方法来处理这个问题。以下是我的问题:

  • 相同字符串的hashCode()可以在运行时间之间发生变化吗?
  • 相同枚举值的hashCode()可以在运行时之间发生变化吗?

注意:我知道我的A.hashCode()实现会根据myIterable b 的顺序返回不同的哈希值,这是不可取的。我正在修理它,以便订单不重要。

2 个答案:

答案 0 :(得分:2)

因此,无论顺序如何,您都会得到不同的结果(例如,这些hashCodes是单独计算的)? 来自hashCode文档http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#hashCode%28%29

  

每当在执行Java应用程序期间多次在同一对象上调用它时,hashCode方法必须始终返回相同的整数,前提是不修改对象的equals比较中使用的信息。从应用程序的一次执行到同一应用程序的另一次执行,此整数不需要保持一致。

从理论上讲,这似乎是可能的。但是,我认为这将是非标准的实施。这是实际的源代码(openjdk7):

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/lang/String.java#String.hashCode%28%29

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/lang/Enum.java#Enum.hashCode%28%29

答案 1 :(得分:1)

可以做什么和什么有用之间存在差异。

您可以子类化(如您所做)并使hashCode()根据当前字段设置返回不同的值。从某种意义上说,这实际上是一件好事。如果两个对象的值不同,那么它们应该返回不同的hashCodes。

但是,你正在做的是让一个对象改变它自己的相等性。你没有两个相等的对象,你有一个对象决定它不等于“它的旧自我”,并且可能不等于它的未来自我。

这在Java世界中只是毫无意义,因为没有任何集合会监视其成员是否有相同的变化(对某些集合的要求,例如地图)。

简而言之,hashCode()提供了一种改变平等确定方式的方法,但不是创建不遵循平等定义的新数学属性的方法。您需要在程序执行的整个过程中保持A = A(在某些情况下甚至更长)。