Arrays.hashCode(Object[]) versus Objects.hash(Object…)
Since JDK 1.5, the Arrays class has offered overloaded static
methods with the name “hashCode
“. Most of the overloaded methods accept an array of a particular primitive type, but the Arrays.hashCode(Object[]) method can be used to calculate an int
hash code for an array of reference types. Since its JDK 1.7 inception, the Objects class has provided a method called hash(Object…) that also returns an int
hash code for a provided array of Java objects (the ellipsis [...
] representing Java varargs is handled as an array and accepts an array). This post provides a brief comparison between Arrays.hashCode(Object)
and Objects.hash(Object...)
.
We can look at the code in OpenJDK to see how OpenJDK implements the two methods being compared here. It turns out that Arrays.hashCode(Object[])
and Objects.hash(Object...)
behave exactly the same way because Objects.hash(Object...)
completely delegates to Arrays.hashCode(Object[])
. This is shown in the next code listing extracted from the OpenJDK Objects.java
class.
public static int hash(Object... values) { return Arrays.hashCode(values); }
So, it turns out that the methods are really the same and so which to choose is mostly a matter of taste. It may appeal to some to use the Arrays
method directly given that’s what’s going to be called anyway. Others may prefer to use the Arrays
method when passing it a construct that is already known to be a Java array and to use the Objects
method for situations where the values are being passed in a comma-separated combination without explicit array syntax being required (such as the case of implementing a custom class’s hashCode()
method and passing that class’s attributes of arbitrary types for the hash code computation). When using an array of primitives of the same type, it is probably best to use the appropriate version of Arrays.hashCode
for that particular primitive.
The simple class shown in the next code listing (and available on GitHub) demonstrates the differences and similarities in output between the overloaded versions of Arrays.hashCode
and the Objects.hash(Object...)
method.
package dustin.examples.hashcodes; import java.util.Arrays; import java.util.Objects; import static java.lang.System.out; /** * Demonstration that displays output to standard output with * hash codes generated for the same underlying array data by * both {@code Arrays.hashCode(Object[])} and by * {@code Objects.hash(Object...)}. */ public class HashesComparedDemo { public static void main(final String[] arguments) { final int[] integers = ArraysCreator.createArrayOfInts(); out.println("Arrays.hashCode(Object[]) for int[]: " + Arrays.hashCode(integers)); out.println("Objects.hash(Object...) for int[]: " + Objects.hash(integers)); out.println("Objects.hashCode(Object) for int[]: " + Objects.hashCode(integers)); final Integer[] refIntegers = ArraysCreator.createArrayOfIntegers(); out.println("Arrays.hashCode(Object[]) for Integer[]: " + Arrays.hashCode(refIntegers)); out.println("Objects.hash(Object...) for Integer[]: " + Objects.hash(refIntegers)); out.println("Objects.hashCode(Object) for Integer[]: " + Objects.hashCode(refIntegers)); final String[] strings = ArraysCreator.createArrayOfStrings(); out.println("Arrays.hashCode(Object[]) for String[]: " + Arrays.hashCode(strings)); out.println("Objects.hash(Object...) for String[]: " + Objects.hash(strings)); out.println("Objects.hashCode(Object) for String[]: " + Objects.hashCode(strings)); } }
The code shown above passes three common data sets (an array of primitive int
values, an array of reference Integer
values, and an array of String
values) to the methods Arrays.hashCode
, Objects.hash(Object...)
, and the Objects.hashCode(Object) method that accepts a single Object (of which an overall array qualifies). The simple example then writes the respective hash code values generated by each method for each data set to standard output. The results of running this code are shown next.
Arrays.hashCode(Object[]) for int[]: 1722319241 Objects.hash(Object...) for int[]: 356573628 Objects.hashCode(Object) for int[]: 356573597 Arrays.hashCode(Object[]) for Integer[]: 1722319241 Objects.hash(Object...) for Integer[]: 1722319241 Objects.hashCode(Object) for Integer[]: 1735600054 Arrays.hashCode(Object[]) for String[]: 448603921 Objects.hash(Object...) for String[]: 448603921 Objects.hashCode(Object) for String[]: 21685669
As we would expect, Arrays.hashCode(Object[])
and Objects.hash(Object...)
return the same calculated hash code for the reference types Integer
and String
because they both effectively are the implementation of Arrays.hashCode(Object[])
. The array of primitive int
values leads to different results from Arrays.hashCode(int[])
than from Objects.hash(Object...)
and this is, of course, because the array of primitives is passed to an overloaded Arrays.hashCode(int[])
method specifically implemented for that primitive data type rather than to Arrays.hashCode(Object[])
.
Published on Java Code Geeks with permission by Dustin Marx, partner at our JCG program. See the original article here: Arrays.hashCode(Object[]) versus Objects.hash(Object…) Opinions expressed by Java Code Geeks contributors are their own. |