有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java枚举值的hashCode()返回值是否随运行时而更改

我正在我的一个对象(instance of A)中使用重写的hashCode()为该对象生成唯一的整数ID。唯一性仅取决于ArrayListI)中的元素(instances of B

以下是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。结果取决于myIterable中每个b中包含的typevalue。我注意到,该值随程序的不同运行而变化,这会在程序创建复制对象时产生问题

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

  • 相等字符串的hashCode()是否可以在运行时之间更改
  • 相同枚举值的hashCode()能否在运行时之间更改

注意:我知道A.hashCode()的实现将根据myIterableb的顺序返回不同的哈希值,这是不需要的。我正在修理它,这样秩序就不重要了


共 (2) 个答案

  1. # 1 楼答案

    可以做的和有效的是有区别的

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

    但是,您所做的是让一个对象将其相等性更改为自身。你没有两个相等的对象,你有一个对象决定它不等于“它的旧自我”,也可能不等于它的未来自我

    在Java世界中,这完全是胡说八道,因为没有一个集合会监视它的组成部分在其相等方式上的变化(这是某些集合的要求,例如映射)

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

  2. # 2 楼答案

    那么,不管顺序如何,您是否有不同的结果(例如,当单独计算这些哈希代码时)? 从hashCode文档http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#hashCode%28%29

    Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.

    从理论上看这是可能的。然而,我认为这将是非标准的实施。以下是实际的源代码(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