gpt4 book ai didi

java - 奇怪的 Java 哈希码(使用 Lombok)非确定性行为

转载 作者:行者123 更新时间:2023-11-30 06:13:42 25 4
gpt4 key购买 nike

我遇到了一些我无法通过 Java Hashcode(使用 Lombok)理解的行为。我有一个抽象对象 Storable,用于存储在各种 DataStores 中的内容。

public abstract class Storable implements Serializable {
...
}

@Data
@EqualsAndHashCode(of="url", callSuper=false)
@Slf4j
@ToString(of="url")
public final class Foo extends Storable {

private URL url;

public Foo(@NonNull URL url, ...) {

super();
this.url = url;
...
}

...
}

当我用 new Foo(new URL("http:///www.foo.com ")) 更新多个 Foos 并迭代它们并检查每个 foo.hashCode() 时,我得到了相同的值。但是如果我终止程序然后开始另一次运行,新运行中的 foos 具有不同的 hashCode 值,即使从数据的角度来看它们看起来相同。这种差异让我很伤心,因为我试图使用 hashCode 来识别每次运行的唯一对象。也许更奇怪的是,对于我用于测试的给定 URL,我每次都会看到相同的 4 个整数中的 1 个。

我是不是漏掉了 Java 的默认 getHashcode() 实现或 Lombok 的 @EqualsAndHashCode 实现?或者是关于 URL 的某些东西会导致它具有不同的 hashCode 值?在此先感谢您的帮助!

最佳答案

如果您使用的是 Java 7,这可能是在使用替代的 murmur 哈希码实现,它不能保证在 JVM 实例(或同一 JVM 多次运行)中产生相同的哈希码

Article that discusses the change to hashcode in Java 7

相关部分:

A couple more words about the alternative hash code:

  • it isn’t exposed publicly through the String class. You can access it using the (unofficial) sun.misc.Hashing.stringHash32 method

  • unlike the original hash code, hash32 for two strings containing the same characters but running in different JVMs (on the same machine or on different machines) isn’t guaranteed to be the same (in fact most likely it won’t be, since a “HASHING_SEED” value is included in the calculation which is initialized on JVM startup using the current time)

  • the purpose of alternative hash code is to give better performance for HashMap and related classes with String keys and to thwart hash-collision denial of service attacks

  • Its usage isn’t enabled by default. You need to set the “jdk.map.althashing.threshold” property to enable it. If you set this to a value X, then HashMap and related classes with a capacity at least X will use the alternative hashing algorithm.

A word of caution if you want to enable alternative hashing: prior to Java 7u40 (ie. all versions between Java 7u6 and Java 7u39) had a performance issue which meant that HashMap creation while alternative hashing was enabled was slower than needed to be. Thus if you want to enable alternative hashing, ensure that you have the latest Java 7 runtime.

这是在 Java 7u6 中添加的,但已在 Java 8 中删除。

这是 Java 7 杂音哈希函数的内部实现 on grep code .

这里是 Java 7 的 HashMap 实现的链接,如果映射中的键是字符串 http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/java/util/HashMap.java#HashMap.hash%28java.lang.Object%29,它会使用新的哈希码计算。

关于java - 奇怪的 Java 哈希码(使用 Lombok)非确定性行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31529248/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com