I ran the follow script(java), and it gave me the weird result. Does anyone can help to 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}));
}
}
}
Log Result(they are different 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 used my own keyGenrator for @Cacheable annotation(Spring & 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 find the cache are always missed.
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;
}
Thank you
If multiple objects return the same value from hashCode(), it means that they would be stored in the same bucket. If many objects are stored in the same bucket it means that on average it requires more comparison operations to look up a given object.
1) If two objects are equal (i.e. the equals() method returns true), they must have the same hashcode. 2) If the hashCode() method is called multiple times on the same object, it must return the same result every time. 3) Two different objects can have the same hash code.
Whenever two different objects have the same hash code, we call this a collision. A collision is nothing critical, it just means that there is more than one object in a single bucket, so a HashMap lookup has to look again to find the right object.
Whenever it(hashcode) 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.
It's because hashCode
for int[]
is not overridden. There is no reason why two instances of int[]
should have the same hashCode
, even if the entries are the same.
Try this:
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 could do:
Objects.hash("getDemoCache", "1", Arrays.hashCode(new int[]{1, 2}))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With