diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleKey.java b/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleKey.java index 760a7f7dbe9..df8055ded47 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleKey.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleKey.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,7 @@ import org.springframework.util.Assert; * * @author Phillip Webb * @author Juergen Hoeller + * @author Brian Clozel * @since 4.0 * @see SimpleKeyGenerator */ @@ -56,7 +57,7 @@ public class SimpleKey implements Serializable { Assert.notNull(elements, "Elements must not be null"); this.params = elements.clone(); // Pre-calculate hashCode field - this.hashCode = Arrays.deepHashCode(this.params); + this.hashCode = calculateHash(this.params); } @@ -79,7 +80,18 @@ public class SimpleKey implements Serializable { private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { ois.defaultReadObject(); // Re-calculate hashCode field on deserialization - this.hashCode = Arrays.deepHashCode(this.params); + this.hashCode = calculateHash(this.params); + } + + /** + * Calculate the hash of the key using its elements and + * mix the result with the finalising function of MurmurHash3. + */ + private static int calculateHash(@Nullable Object[] params) { + int hash = Arrays.deepHashCode(params); + hash = (hash ^ (hash >>> 16)) * 0x85ebca6b; + hash = (hash ^ (hash >>> 13)) * 0xc2b2ae35; + return hash ^ (hash >>> 16); } }