0

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并构造了 final hash。结果取决于typevalue包含在每个bmyIterable。我注意到的是,这个值会随着程序的不同运行而变化,这会产生一个问题,因为程序正在创建重复的对象。

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

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

注意:我知道我的实现将根据b inA.hashCode()的顺序返回不同的哈希值,这是不希望的。我正在修复它,以便顺序不重要。myIterable

4

2 回答 2

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

于 2013-07-15T18:50:28.067 回答
1

能做什么和能做什么是有区别的。

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

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

这在 Java 世界中简直是胡说八道,因为没有集合会监视其组成部分是否改变了它们自身的相等性(某些集合的要求,例如映射)。

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

于 2013-07-15T18:59:45.143 回答