为什么Objects.hash()为同一输入返回不同的值?

Sal*_*Egg 9 java hashcode

我运行了跟随脚本(java),它给了我奇怪的结果.有没有人可以帮忙解释一下?

import java.util.Objects;
import org.apache.log4j.Logger;

public class CacheTester {

private static final Logger log = Logger.getLogger(CacheTester.class);

    @Test
    public void hashCodeTest() {
        for (int i = 0; i < 50; i++) {
            // if I remove the third parameter, it works fine
            log.info(Objects.hash("getDemoCache", "1", new int[]{1, 2}));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

日志结果(它们彼此不同):

//...
2015-04-29 17:43:20 INFO  CacheTester:42 - 1431904540
2015-04-29 17:43:20 INFO  CacheTester:42 - 1859187447
2015-04-29 17:43:20 INFO  CacheTester:42 - -2146933580
2015-04-29 17:43:20 INFO  CacheTester:42 - -2074242201
2015-04-29 17:43:20 INFO  CacheTester:42 - 1363170000
2015-04-29 17:43:20 INFO  CacheTester:42 - 1040980265
2015-04-29 17:43:20 INFO  CacheTester:42 - 1639331053
2015-04-29 17:43:20 INFO  CacheTester:42 - 570765746
2015-04-29 17:43:20 INFO  CacheTester:42 - -2023288896
2015-04-29 17:43:20 INFO  CacheTester:42 - -1892732019
2015-04-29 17:43:20 INFO  CacheTester:42 - 1464306601
2015-04-29 17:43:20 INFO  CacheTester:42 - 921799986
2015-04-29 17:43:20 INFO  CacheTester:42 - 1037804977
//...
Run Code Online (Sandbox Code Playgroud)

- - 背景 - -

我想使用自己的keyGenrator进行@Cacheable注释(Spring&ehCache).

public Object generate(Object target, Method method, Object... params) {
    int key = Objects.hashCode(method.getName(), params);
    log.info("key = " + key);
    return key;
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我发现总是错过缓存.

然后我必须改为:

public Object generate(Object target, Method method, Object... params) {
    int result = method.getName().hashCode() : 0;
    result = 31 * result + Objects.hashCode(params);
    return result;
}
Run Code Online (Sandbox Code Playgroud)

谢谢

Pau*_*ton 10

这是因为hashCode对于int[]未覆盖.即使条目int[]相同hashCode,也没有理由为什么两个实例应该具有相同的实例.

试试这个:

System.out.println(new int[] {1, 2}.hashCode());
System.out.println(new int[] {1, 2}.hashCode());
Run Code Online (Sandbox Code Playgroud)

你几乎肯定会看到两个不同的整数.

使用Objects.hash数组的一个好方法是传递Arrays.hashCode(array)而不是实际的数组.在你的情况下,你可以这样做:

Objects.hash("getDemoCache", "1", Arrays.hashCode(new int[]{1, 2}))
Run Code Online (Sandbox Code Playgroud)