8202398: Optimize Arrays.deepHashCode
authormartin
Wed, 02 May 2018 11:21:27 -0700
changeset 49955 ea246151be08
parent 49954 deefa2120bc4
child 49956 a87f2e7a527c
8202398: Optimize Arrays.deepHashCode Reviewed-by: psandoz
src/java.base/share/classes/java/util/Arrays.java
--- a/src/java.base/share/classes/java/util/Arrays.java	Wed May 02 11:20:20 2018 -0700
+++ b/src/java.base/share/classes/java/util/Arrays.java	Wed May 02 11:21:27 2018 -0700
@@ -4723,27 +4723,16 @@
         int result = 1;
 
         for (Object element : a) {
-            int elementHash = 0;
-            if (element instanceof Object[])
+            final int elementHash;
+            final Class<?> cl;
+            if (element == null)
+                elementHash = 0;
+            else if ((cl = element.getClass().getComponentType()) == null)
+                elementHash = element.hashCode();
+            else if (element instanceof Object[])
                 elementHash = deepHashCode((Object[]) element);
-            else if (element instanceof byte[])
-                elementHash = hashCode((byte[]) element);
-            else if (element instanceof short[])
-                elementHash = hashCode((short[]) element);
-            else if (element instanceof int[])
-                elementHash = hashCode((int[]) element);
-            else if (element instanceof long[])
-                elementHash = hashCode((long[]) element);
-            else if (element instanceof char[])
-                elementHash = hashCode((char[]) element);
-            else if (element instanceof float[])
-                elementHash = hashCode((float[]) element);
-            else if (element instanceof double[])
-                elementHash = hashCode((double[]) element);
-            else if (element instanceof boolean[])
-                elementHash = hashCode((boolean[]) element);
-            else if (element != null)
-                elementHash = element.hashCode();
+            else
+                elementHash = primitiveArrayHashCode(element, cl);
 
             result = 31 * result + elementHash;
         }
@@ -4751,6 +4740,20 @@
         return result;
     }
 
+    private static int primitiveArrayHashCode(Object a, Class<?> cl) {
+        return
+            (cl == byte.class)    ? hashCode((byte[]) a)    :
+            (cl == int.class)     ? hashCode((int[]) a)     :
+            (cl == long.class)    ? hashCode((long[]) a)    :
+            (cl == char.class)    ? hashCode((char[]) a)    :
+            (cl == short.class)   ? hashCode((short[]) a)   :
+            (cl == boolean.class) ? hashCode((boolean[]) a) :
+            (cl == double.class)  ? hashCode((double[]) a)  :
+            // If new primitive types are ever added, this method must be
+            // expanded or we will fail here with ClassCastException.
+            hashCode((float[]) a);
+    }
+
     /**
      * Returns {@code true} if the two specified arrays are <i>deeply
      * equal</i> to one another.  Unlike the {@link #equals(Object[],Object[])}