< prev index next >

src/java.base/share/classes/java/util/Arrays.java

Print this page
8202398: Optimize Arrays.deepHashCode
Reviewed-by: psandoz


4706      * difference: If an element {@code e} of {@code a} is itself an array,
4707      * its hash code is computed not by calling {@code e.hashCode()}, but as
4708      * by calling the appropriate overloading of {@code Arrays.hashCode(e)}
4709      * if {@code e} is an array of a primitive type, or as by calling
4710      * {@code Arrays.deepHashCode(e)} recursively if {@code e} is an array
4711      * of a reference type.  If {@code a} is {@code null}, this method
4712      * returns 0.
4713      *
4714      * @param a the array whose deep-content-based hash code to compute
4715      * @return a deep-content-based hash code for {@code a}
4716      * @see #hashCode(Object[])
4717      * @since 1.5
4718      */
4719     public static int deepHashCode(Object a[]) {
4720         if (a == null)
4721             return 0;
4722 
4723         int result = 1;
4724 
4725         for (Object element : a) {
4726             int elementHash = 0;
4727             if (element instanceof Object[])
4728                 elementHash = deepHashCode((Object[]) element);
4729             else if (element instanceof byte[])
4730                 elementHash = hashCode((byte[]) element);
4731             else if (element instanceof short[])
4732                 elementHash = hashCode((short[]) element);
4733             else if (element instanceof int[])
4734                 elementHash = hashCode((int[]) element);
4735             else if (element instanceof long[])
4736                 elementHash = hashCode((long[]) element);
4737             else if (element instanceof char[])
4738                 elementHash = hashCode((char[]) element);
4739             else if (element instanceof float[])
4740                 elementHash = hashCode((float[]) element);
4741             else if (element instanceof double[])
4742                 elementHash = hashCode((double[]) element);
4743             else if (element instanceof boolean[])
4744                 elementHash = hashCode((boolean[]) element);
4745             else if (element != null)
4746                 elementHash = element.hashCode();




4747 
4748             result = 31 * result + elementHash;
4749         }
4750 
4751         return result;














4752     }
4753 
4754     /**
4755      * Returns {@code true} if the two specified arrays are <i>deeply
4756      * equal</i> to one another.  Unlike the {@link #equals(Object[],Object[])}
4757      * method, this method is appropriate for use with nested arrays of
4758      * arbitrary depth.
4759      *
4760      * <p>Two array references are considered deeply equal if both
4761      * are {@code null}, or if they refer to arrays that contain the same
4762      * number of elements and all corresponding pairs of elements in the two
4763      * arrays are deeply equal.
4764      *
4765      * <p>Two possibly {@code null} elements {@code e1} and {@code e2} are
4766      * deeply equal if any of the following conditions hold:
4767      * <ul>
4768      *    <li> {@code e1} and {@code e2} are both arrays of object reference
4769      *         types, and {@code Arrays.deepEquals(e1, e2) would return true}
4770      *    <li> {@code e1} and {@code e2} are arrays of the same primitive
4771      *         type, and the appropriate overloading of




4706      * difference: If an element {@code e} of {@code a} is itself an array,
4707      * its hash code is computed not by calling {@code e.hashCode()}, but as
4708      * by calling the appropriate overloading of {@code Arrays.hashCode(e)}
4709      * if {@code e} is an array of a primitive type, or as by calling
4710      * {@code Arrays.deepHashCode(e)} recursively if {@code e} is an array
4711      * of a reference type.  If {@code a} is {@code null}, this method
4712      * returns 0.
4713      *
4714      * @param a the array whose deep-content-based hash code to compute
4715      * @return a deep-content-based hash code for {@code a}
4716      * @see #hashCode(Object[])
4717      * @since 1.5
4718      */
4719     public static int deepHashCode(Object a[]) {
4720         if (a == null)
4721             return 0;
4722 
4723         int result = 1;
4724 
4725         for (Object element : a) {
4726             final int elementHash;
4727             final Class<?> cl;
4728             if (element == null)
4729                 elementHash = 0;
4730             else if ((cl = element.getClass().getComponentType()) == null)















4731                 elementHash = element.hashCode();
4732             else if (element instanceof Object[])
4733                 elementHash = deepHashCode((Object[]) element);
4734             else
4735                 elementHash = primitiveArrayHashCode(element, cl);
4736 
4737             result = 31 * result + elementHash;
4738         }
4739 
4740         return result;
4741     }
4742 
4743     private static int primitiveArrayHashCode(Object a, Class<?> cl) {
4744         return
4745             (cl == byte.class)    ? hashCode((byte[]) a)    :
4746             (cl == int.class)     ? hashCode((int[]) a)     :
4747             (cl == long.class)    ? hashCode((long[]) a)    :
4748             (cl == char.class)    ? hashCode((char[]) a)    :
4749             (cl == short.class)   ? hashCode((short[]) a)   :
4750             (cl == boolean.class) ? hashCode((boolean[]) a) :
4751             (cl == double.class)  ? hashCode((double[]) a)  :
4752             // If new primitive types are ever added, this method must be
4753             // expanded or we will fail here with ClassCastException.
4754             hashCode((float[]) a);
4755     }
4756 
4757     /**
4758      * Returns {@code true} if the two specified arrays are <i>deeply
4759      * equal</i> to one another.  Unlike the {@link #equals(Object[],Object[])}
4760      * method, this method is appropriate for use with nested arrays of
4761      * arbitrary depth.
4762      *
4763      * <p>Two array references are considered deeply equal if both
4764      * are {@code null}, or if they refer to arrays that contain the same
4765      * number of elements and all corresponding pairs of elements in the two
4766      * arrays are deeply equal.
4767      *
4768      * <p>Two possibly {@code null} elements {@code e1} and {@code e2} are
4769      * deeply equal if any of the following conditions hold:
4770      * <ul>
4771      *    <li> {@code e1} and {@code e2} are both arrays of object reference
4772      *         types, and {@code Arrays.deepEquals(e1, e2) would return true}
4773      *    <li> {@code e1} and {@code e2} are arrays of the same primitive
4774      *         type, and the appropriate overloading of


< prev index next >