Why does Objects.hash () return different values ​​for a single input?

I ran the following script (java) and this gave me a weird result. Can anyone help explain?

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})); } } } 

The result of the log (they differ from each other):

 //... 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 //... 

---- Background ----

I wanted to use my own Generator key for @Cacheable annotation (Spring and ehCache).

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

In this case, I believe that the cache is always skipped.

Then I have to change to this:

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

thanks

+6
source share
1 answer

This is because hashCode for int[] not overridden. There is no reason two instances of int[] should have the same hashCode , even if the entries match.

Try the following:

 System.out.println(new int[] {1, 2}.hashCode()); System.out.println(new int[] {1, 2}.hashCode()); 

You will almost certainly see two different integers.

A good way to use Objects.hash with arrays is to pass Arrays.hashCode(array) instead of the actual array. In your case, you can do:

 Objects.hash("getDemoCache", "1", Arrays.hashCode(new int[]{1, 2})) 
+8
source

Source: https://habr.com/ru/post/986254/


All Articles