/* * @(#)Arrays.java 1.59 04/04/01 * * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package java.util; import java.lang.reflect.*; /** * This class contains various methods for manipulating arrays (such as * sorting and searching). This class also contains a static factory * that allows arrays to be viewed as lists. * *
The methods in this class all throw a NullPointerException if * the specified array reference is null, except where noted. * *
The documentation for the methods contained in this class includes * briefs description of the implementations. Such descriptions should * be regarded as implementation notes, rather than parts of the * specification. Implementors should feel free to substitute other * algorithms, so long as the specification itself is adhered to. (For * example, the algorithm used by sort(Object[]) does not have to be * a mergesort, but it does have to be stable.) * *
This class is a member of the * * Java Collections Framework. * * @author Josh Bloch * @author Neal Gafter * @version 1.59, 04/01/04 * @see Comparable * @see Comparator * @since 1.2 */ public class Arrays { // Suppresses default constructor, ensuring non-instantiability. private Arrays() { } // Sorting /** * Sorts the specified array of longs into ascending numerical order. * The sorting algorithm is a tuned quicksort, adapted from Jon * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function", * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November * 1993). This algorithm offers n*log(n) performance on many data sets * that cause other quicksorts to degrade to quadratic performance. * * @param a the array to be sorted. */ public static void sort(long[] a) { sort1(a, 0, a.length); } /** * Sorts the specified range of the specified array of longs into * ascending numerical order. The range to be sorted extends from index * fromIndex, inclusive, to index toIndex, exclusive. * (If fromIndex==toIndex, the range to be sorted is empty.) * *
The sorting algorithm is a tuned quicksort, adapted from Jon * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function", * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November * 1993). This algorithm offers n*log(n) performance on many data sets * that cause other quicksorts to degrade to quadratic performance. * * @param a the array to be sorted. * @param fromIndex the index of the first element (inclusive) to be * sorted. * @param toIndex the index of the last element (exclusive) to be sorted. * @throws IllegalArgumentException if fromIndex > toIndex * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 or * toIndex > a.length */ public static void sort(long[] a, int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); sort1(a, fromIndex, toIndex-fromIndex); } /** * Sorts the specified array of ints into ascending numerical order. * The sorting algorithm is a tuned quicksort, adapted from Jon * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function", * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November * 1993). This algorithm offers n*log(n) performance on many data sets * that cause other quicksorts to degrade to quadratic performance. * * @param a the array to be sorted. */ public static void sort(int[] a) { sort1(a, 0, a.length); } /** * Sorts the specified range of the specified array of ints into * ascending numerical order. The range to be sorted extends from index * fromIndex, inclusive, to index toIndex, exclusive. * (If fromIndex==toIndex, the range to be sorted is empty.)
* * The sorting algorithm is a tuned quicksort, adapted from Jon * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function", * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November * 1993). This algorithm offers n*log(n) performance on many data sets * that cause other quicksorts to degrade to quadratic performance. * * @param a the array to be sorted. * @param fromIndex the index of the first element (inclusive) to be * sorted. * @param toIndex the index of the last element (exclusive) to be sorted. * @throws IllegalArgumentException if fromIndex > toIndex * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 or * toIndex > a.length */ public static void sort(int[] a, int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); sort1(a, fromIndex, toIndex-fromIndex); } /** * Sorts the specified array of shorts into ascending numerical order. * The sorting algorithm is a tuned quicksort, adapted from Jon * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function", * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November * 1993). This algorithm offers n*log(n) performance on many data sets * that cause other quicksorts to degrade to quadratic performance. * * @param a the array to be sorted. */ public static void sort(short[] a) { sort1(a, 0, a.length); } /** * Sorts the specified range of the specified array of shorts into * ascending numerical order. The range to be sorted extends from index * fromIndex, inclusive, to index toIndex, exclusive. * (If fromIndex==toIndex, the range to be sorted is empty.)
* * The sorting algorithm is a tuned quicksort, adapted from Jon * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function", * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November * 1993). This algorithm offers n*log(n) performance on many data sets * that cause other quicksorts to degrade to quadratic performance. * * @param a the array to be sorted. * @param fromIndex the index of the first element (inclusive) to be * sorted. * @param toIndex the index of the last element (exclusive) to be sorted. * @throws IllegalArgumentException if fromIndex > toIndex * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 or * toIndex > a.length */ public static void sort(short[] a, int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); sort1(a, fromIndex, toIndex-fromIndex); } /** * Sorts the specified array of chars into ascending numerical order. * The sorting algorithm is a tuned quicksort, adapted from Jon * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function", * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November * 1993). This algorithm offers n*log(n) performance on many data sets * that cause other quicksorts to degrade to quadratic performance. * * @param a the array to be sorted. */ public static void sort(char[] a) { sort1(a, 0, a.length); } /** * Sorts the specified range of the specified array of chars into * ascending numerical order. The range to be sorted extends from index * fromIndex, inclusive, to index toIndex, exclusive. * (If fromIndex==toIndex, the range to be sorted is empty.)
* * The sorting algorithm is a tuned quicksort, adapted from Jon * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function", * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November * 1993). This algorithm offers n*log(n) performance on many data sets * that cause other quicksorts to degrade to quadratic performance. * * @param a the array to be sorted. * @param fromIndex the index of the first element (inclusive) to be * sorted. * @param toIndex the index of the last element (exclusive) to be sorted. * @throws IllegalArgumentException if fromIndex > toIndex * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 or * toIndex > a.length */ public static void sort(char[] a, int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); sort1(a, fromIndex, toIndex-fromIndex); } /** * Sorts the specified array of bytes into ascending numerical order. * The sorting algorithm is a tuned quicksort, adapted from Jon * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function", * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November * 1993). This algorithm offers n*log(n) performance on many data sets * that cause other quicksorts to degrade to quadratic performance. * * @param a the array to be sorted. */ public static void sort(byte[] a) { sort1(a, 0, a.length); } /** * Sorts the specified range of the specified array of bytes into * ascending numerical order. The range to be sorted extends from index * fromIndex, inclusive, to index toIndex, exclusive. * (If fromIndex==toIndex, the range to be sorted is empty.)
* * The sorting algorithm is a tuned quicksort, adapted from Jon * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function", * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November * 1993). This algorithm offers n*log(n) performance on many data sets * that cause other quicksorts to degrade to quadratic performance. * * @param a the array to be sorted. * @param fromIndex the index of the first element (inclusive) to be * sorted. * @param toIndex the index of the last element (exclusive) to be sorted. * @throws IllegalArgumentException if fromIndex > toIndex * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 or * toIndex > a.length */ public static void sort(byte[] a, int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); sort1(a, fromIndex, toIndex-fromIndex); } /** * Sorts the specified array of doubles into ascending numerical order. *
* The <
relation does not provide a total order on
* all floating-point values; although they are distinct numbers
* -0.0 == 0.0
is true
and a NaN value
* compares neither less than, greater than, nor equal to any
* floating-point value, even itself. To allow the sort to
* proceed, instead of using the <
relation to
* determine ascending numerical order, this method uses the total
* order imposed by {@link Double#compareTo}. This ordering
* differs from the <
relation in that
* -0.0
is treated as less than 0.0
and
* NaN is considered greater than any other floating-point value.
* For the purposes of sorting, all NaN values are considered
* equivalent and equal.
*
* The sorting algorithm is a tuned quicksort, adapted from Jon * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function", * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November * 1993). This algorithm offers n*log(n) performance on many data sets * that cause other quicksorts to degrade to quadratic performance. * * @param a the array to be sorted. */ public static void sort(double[] a) { sort2(a, 0, a.length); } /** * Sorts the specified range of the specified array of doubles into * ascending numerical order. The range to be sorted extends from index * fromIndex, inclusive, to index toIndex, exclusive. * (If fromIndex==toIndex, the range to be sorted is empty.) *
* The <
relation does not provide a total order on
* all floating-point values; although they are distinct numbers
* -0.0 == 0.0
is true
and a NaN value
* compares neither less than, greater than, nor equal to any
* floating-point value, even itself. To allow the sort to
* proceed, instead of using the <
relation to
* determine ascending numerical order, this method uses the total
* order imposed by {@link Double#compareTo}. This ordering
* differs from the <
relation in that
* -0.0
is treated as less than 0.0
and
* NaN is considered greater than any other floating-point value.
* For the purposes of sorting, all NaN values are considered
* equivalent and equal.
*
* The sorting algorithm is a tuned quicksort, adapted from Jon * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function", * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November * 1993). This algorithm offers n*log(n) performance on many data sets * that cause other quicksorts to degrade to quadratic performance. * * @param a the array to be sorted. * @param fromIndex the index of the first element (inclusive) to be * sorted. * @param toIndex the index of the last element (exclusive) to be sorted. * @throws IllegalArgumentException if fromIndex > toIndex * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 or * toIndex > a.length */ public static void sort(double[] a, int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); sort2(a, fromIndex, toIndex); } /** * Sorts the specified array of floats into ascending numerical order. *
* The <
relation does not provide a total order on
* all floating-point values; although they are distinct numbers
* -0.0f == 0.0f
is true
and a NaN value
* compares neither less than, greater than, nor equal to any
* floating-point value, even itself. To allow the sort to
* proceed, instead of using the <
relation to
* determine ascending numerical order, this method uses the total
* order imposed by {@link Float#compareTo}. This ordering
* differs from the <
relation in that
* -0.0f
is treated as less than 0.0f
and
* NaN is considered greater than any other floating-point value.
* For the purposes of sorting, all NaN values are considered
* equivalent and equal.
*
* The sorting algorithm is a tuned quicksort, adapted from Jon * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function", * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November * 1993). This algorithm offers n*log(n) performance on many data sets * that cause other quicksorts to degrade to quadratic performance. * * @param a the array to be sorted. */ public static void sort(float[] a) { sort2(a, 0, a.length); } /** * Sorts the specified range of the specified array of floats into * ascending numerical order. The range to be sorted extends from index * fromIndex, inclusive, to index toIndex, exclusive. * (If fromIndex==toIndex, the range to be sorted is empty.) *
* The <
relation does not provide a total order on
* all floating-point values; although they are distinct numbers
* -0.0f == 0.0f
is true
and a NaN value
* compares neither less than, greater than, nor equal to any
* floating-point value, even itself. To allow the sort to
* proceed, instead of using the <
relation to
* determine ascending numerical order, this method uses the total
* order imposed by {@link Float#compareTo}. This ordering
* differs from the <
relation in that
* -0.0f
is treated as less than 0.0f
and
* NaN is considered greater than any other floating-point value.
* For the purposes of sorting, all NaN values are considered
* equivalent and equal.
*
* The sorting algorithm is a tuned quicksort, adapted from Jon
* L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
* Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
* 1993). This algorithm offers n*log(n) performance on many data sets
* that cause other quicksorts to degrade to quadratic performance.
*
* @param a the array to be sorted.
* @param fromIndex the index of the first element (inclusive) to be
* sorted.
* @param toIndex the index of the last element (exclusive) to be sorted.
* @throws IllegalArgumentException if fromIndex > toIndex
* @throws ArrayIndexOutOfBoundsException if fromIndex < 0 or
* toIndex > a.length
*/
public static void sort(float[] a, int fromIndex, int toIndex) {
rangeCheck(a.length, fromIndex, toIndex);
sort2(a, fromIndex, toIndex);
}
private static void sort2(double a[], int fromIndex, int toIndex) {
final long NEG_ZERO_BITS = Double.doubleToLongBits(-0.0d);
/*
* The sort is done in three phases to avoid the expense of using
* NaN and -0.0 aware comparisons during the main sort.
*/
/*
* Preprocessing phase: Move any NaN's to end of array, count the
* number of -0.0's, and turn them into 0.0's.
*/
int numNegZeros = 0;
int i = fromIndex, n = toIndex;
while(i < n) {
if (a[i] != a[i]) {
double swap = a[i];
a[i] = a[--n];
a[n] = swap;
} else {
if (a[i]==0 && Double.doubleToLongBits(a[i])==NEG_ZERO_BITS) {
a[i] = 0.0d;
numNegZeros++;
}
i++;
}
}
// Main sort phase: quicksort everything but the NaN's
sort1(a, fromIndex, n-fromIndex);
// Postprocessing phase: change 0.0's to -0.0's as required
if (numNegZeros != 0) {
int j = binarySearch(a, 0.0d, fromIndex, n-1); // posn of ANY zero
do {
j--;
} while (j>=0 && a[j]==0.0d);
// j is now one less than the index of the FIRST zero
for (int k=0; k
*
* This sort is guaranteed to be stable: equal elements will
* not be reordered as a result of the sort.
*
* The sorting algorithm is a modified mergesort (in which the merge is
* omitted if the highest element in the low sublist is less than the
* lowest element in the high sublist). This algorithm offers guaranteed
* n*log(n) performance.
*
* @param a the array to be sorted.
* @throws ClassCastException if the array contains elements that are not
* mutually comparable (for example, strings and integers).
* @see Comparable
*/
public static void sort(Object[] a) {
Object[] aux = (Object[])a.clone();
mergeSort(aux, a, 0, a.length, 0);
}
/**
* Sorts the specified range of the specified array of objects into
* ascending order, according to the natural ordering of its
* elements. The range to be sorted extends from index
* fromIndex, inclusive, to index toIndex, exclusive.
* (If fromIndex==toIndex, the range to be sorted is empty.) All
* elements in this range must implement the Comparable
* interface. Furthermore, all elements in this range must be mutually
* comparable (that is, e1.compareTo(e2) must not throw a
* ClassCastException for any elements e1 and
* e2 in the array).
*
* This sort is guaranteed to be stable: equal elements will
* not be reordered as a result of the sort.
*
* The sorting algorithm is a modified mergesort (in which the merge is
* omitted if the highest element in the low sublist is less than the
* lowest element in the high sublist). This algorithm offers guaranteed
* n*log(n) performance.
*
* @param a the array to be sorted.
* @param fromIndex the index of the first element (inclusive) to be
* sorted.
* @param toIndex the index of the last element (exclusive) to be sorted.
* @throws IllegalArgumentException if fromIndex > toIndex
* @throws ArrayIndexOutOfBoundsException if fromIndex < 0 or
* toIndex > a.length
* @throws ClassCastException if the array contains elements that are
* not mutually comparable (for example, strings and
* integers).
* @see Comparable
*/
public static void sort(Object[] a, int fromIndex, int toIndex) {
rangeCheck(a.length, fromIndex, toIndex);
Object[] aux = cloneSubarray(a, fromIndex, toIndex);
mergeSort(aux, a, fromIndex, toIndex, -fromIndex);
}
/**
* Tuning parameter: list size at or below which insertion sort will be
* used in preference to mergesort or quicksort.
*/
private static final int INSERTIONSORT_THRESHOLD = 7;
/**
* Clones an array within the specified bounds.
* This method assumes that a is an array.
*/
private static
*
* This sort is guaranteed to be stable: equal elements will
* not be reordered as a result of the sort.
*
* The sorting algorithm is a modified mergesort (in which the merge is
* omitted if the highest element in the low sublist is less than the
* lowest element in the high sublist). This algorithm offers guaranteed
* n*log(n) performance.
*
* @param a the array to be sorted.
* @param c the comparator to determine the order of the array. A
* null value indicates that the elements' natural
* ordering should be used.
* @throws ClassCastException if the array contains elements that are
* not mutually comparable using the specified comparator.
* @see Comparator
*/
public static
*
* This sort is guaranteed to be stable: equal elements will
* not be reordered as a result of the sort.
*
* The sorting algorithm is a modified mergesort (in which the merge is
* omitted if the highest element in the low sublist is less than the
* lowest element in the high sublist). This algorithm offers guaranteed
* n*log(n) performance.
*
* @param a the array to be sorted.
* @param fromIndex the index of the first element (inclusive) to be
* sorted.
* @param toIndex the index of the last element (exclusive) to be sorted.
* @param c the comparator to determine the order of the array. A
* null value indicates that the elements' natural
* ordering should be used.
* @throws ClassCastException if the array contains elements that are not
* mutually comparable using the specified comparator.
* @throws IllegalArgumentException if fromIndex > toIndex
* @throws ArrayIndexOutOfBoundsException if fromIndex < 0 or
* toIndex > a.length
* @see Comparator
*/
public static
*
* @param a one array to be tested for equality.
* @param a2 the other array to be tested for equality.
* @return true if the two arrays are equal.
*/
public static boolean equals(long[] a, long[] a2) {
if (a==a2)
return true;
if (a==null || a2==null)
return false;
int length = a.length;
if (a2.length != length)
return false;
for (int i=0; i
*
* @param a one array to be tested for equality.
* @param a2 the other array to be tested for equality.
* @return true if the two arrays are equal.
*/
public static boolean equals(int[] a, int[] a2) {
if (a==a2)
return true;
if (a==null || a2==null)
return false;
int length = a.length;
if (a2.length != length)
return false;
for (int i=0; i
*
* @param a one array to be tested for equality.
* @param a2 the other array to be tested for equality.
* @return true if the two arrays are equal.
*/
public static boolean equals(short[] a, short a2[]) {
if (a==a2)
return true;
if (a==null || a2==null)
return false;
int length = a.length;
if (a2.length != length)
return false;
for (int i=0; i
*
* @param a one array to be tested for equality.
* @param a2 the other array to be tested for equality.
* @return true if the two arrays are equal.
*/
public static boolean equals(char[] a, char[] a2) {
if (a==a2)
return true;
if (a==null || a2==null)
return false;
int length = a.length;
if (a2.length != length)
return false;
for (int i=0; i
*
* @param a one array to be tested for equality.
* @param a2 the other array to be tested for equality.
* @return true if the two arrays are equal.
*/
public static boolean equals(byte[] a, byte[] a2) {
if (a==a2)
return true;
if (a==null || a2==null)
return false;
int length = a.length;
if (a2.length != length)
return false;
for (int i=0; i
*
* @param a one array to be tested for equality.
* @param a2 the other array to be tested for equality.
* @return true if the two arrays are equal.
*/
public static boolean equals(boolean[] a, boolean[] a2) {
if (a==a2)
return true;
if (a==null || a2==null)
return false;
int length = a.length;
if (a2.length != length)
return false;
for (int i=0; i
*
* Two doubles d1 and d2 are considered equal if:
*
*
* Two floats f1 and f2 are considered equal if:
*
*
* @param a one array to be tested for equality.
* @param a2 the other array to be tested for equality.
* @return true if the two arrays are equal.
*/
public static boolean equals(Object[] a, Object[] a2) {
if (a==a2)
return true;
if (a==null || a2==null)
return false;
int length = a.length;
if (a2.length != length)
return false;
for (int i=0; i This method also provides a convenient way to create a fixed-size
* list initialized to contain several elements:
* The value returned by this method is the same value that would be
* obtained by invoking the {@link List#hashCode() hashCode}
* method on a {@link List} containing a sequence of {@link Long}
* instances representing the elements of a in the same order.
* If a is null, this method returns 0.
*
* @param a the array whose hash value to compute
* @return a content-based hash code for a
* @since 1.5
*/
public static int hashCode(long a[]) {
if (a == null)
return 0;
int result = 1;
for (long element : a) {
int elementHash = (int)(element ^ (element >>> 32));
result = 31 * result + elementHash;
}
return result;
}
/**
* Returns a hash code based on the contents of the specified array.
* For any two non-null int arrays a and b
* such that Arrays.equals(a, b), it is also the case that
* Arrays.hashCode(a) == Arrays.hashCode(b).
*
* The value returned by this method is the same value that would be
* obtained by invoking the {@link List#hashCode() hashCode}
* method on a {@link List} containing a sequence of {@link Integer}
* instances representing the elements of a in the same order.
* If a is null, this method returns 0.
*
* @param a the array whose hash value to compute
* @return a content-based hash code for a
* @since 1.5
*/
public static int hashCode(int a[]) {
if (a == null)
return 0;
int result = 1;
for (int element : a)
result = 31 * result + element;
return result;
}
/**
* Returns a hash code based on the contents of the specified array.
* For any two short arrays a and b
* such that Arrays.equals(a, b), it is also the case that
* Arrays.hashCode(a) == Arrays.hashCode(b).
*
* The value returned by this method is the same value that would be
* obtained by invoking the {@link List#hashCode() hashCode}
* method on a {@link List} containing a sequence of {@link Short}
* instances representing the elements of a in the same order.
* If a is null, this method returns 0.
*
* @param a the array whose hash value to compute
* @return a content-based hash code for a
* @since 1.5
*/
public static int hashCode(short a[]) {
if (a == null)
return 0;
int result = 1;
for (short element : a)
result = 31 * result + element;
return result;
}
/**
* Returns a hash code based on the contents of the specified array.
* For any two char arrays a and b
* such that Arrays.equals(a, b), it is also the case that
* Arrays.hashCode(a) == Arrays.hashCode(b).
*
* The value returned by this method is the same value that would be
* obtained by invoking the {@link List#hashCode() hashCode}
* method on a {@link List} containing a sequence of {@link Character}
* instances representing the elements of a in the same order.
* If a is null, this method returns 0.
*
* @param a the array whose hash value to compute
* @return a content-based hash code for a
* @since 1.5
*/
public static int hashCode(char a[]) {
if (a == null)
return 0;
int result = 1;
for (char element : a)
result = 31 * result + element;
return result;
}
/**
* Returns a hash code based on the contents of the specified array.
* For any two byte arrays a and b
* such that Arrays.equals(a, b), it is also the case that
* Arrays.hashCode(a) == Arrays.hashCode(b).
*
* The value returned by this method is the same value that would be
* obtained by invoking the {@link List#hashCode() hashCode}
* method on a {@link List} containing a sequence of {@link Byte}
* instances representing the elements of a in the same order.
* If a is null, this method returns 0.
*
* @param a the array whose hash value to compute
* @return a content-based hash code for a
* @since 1.5
*/
public static int hashCode(byte a[]) {
if (a == null)
return 0;
int result = 1;
for (byte element : a)
result = 31 * result + element;
return result;
}
/**
* Returns a hash code based on the contents of the specified array.
* For any two boolean arrays a and b
* such that Arrays.equals(a, b), it is also the case that
* Arrays.hashCode(a) == Arrays.hashCode(b).
*
* The value returned by this method is the same value that would be
* obtained by invoking the {@link List#hashCode() hashCode}
* method on a {@link List} containing a sequence of {@link Boolean}
* instances representing the elements of a in the same order.
* If a is null, this method returns 0.
*
* @param a the array whose hash value to compute
* @return a content-based hash code for a
* @since 1.5
*/
public static int hashCode(boolean a[]) {
if (a == null)
return 0;
int result = 1;
for (boolean element : a)
result = 31 * result + (element ? 1231 : 1237);
return result;
}
/**
* Returns a hash code based on the contents of the specified array.
* For any two float arrays a and b
* such that Arrays.equals(a, b), it is also the case that
* Arrays.hashCode(a) == Arrays.hashCode(b).
*
* The value returned by this method is the same value that would be
* obtained by invoking the {@link List#hashCode() hashCode}
* method on a {@link List} containing a sequence of {@link Float}
* instances representing the elements of a in the same order.
* If a is null, this method returns 0.
*
* @param a the array whose hash value to compute
* @return a content-based hash code for a
* @since 1.5
*/
public static int hashCode(float a[]) {
if (a == null)
return 0;
int result = 1;
for (float element : a)
result = 31 * result + Float.floatToIntBits(element);
return result;
}
/**
* Returns a hash code based on the contents of the specified array.
* For any two double arrays a and b
* such that Arrays.equals(a, b), it is also the case that
* Arrays.hashCode(a) == Arrays.hashCode(b).
*
* The value returned by this method is the same value that would be
* obtained by invoking the {@link List#hashCode() hashCode}
* method on a {@link List} containing a sequence of {@link Double}
* instances representing the elements of a in the same order.
* If a is null, this method returns 0.
*
* @param a the array whose hash value to compute
* @return a content-based hash code for a
* @since 1.5
*/
public static int hashCode(double a[]) {
if (a == null)
return 0;
int result = 1;
for (double element : a) {
long bits = Double.doubleToLongBits(element);
result = 31 * result + (int)(bits ^ (bits >>> 32));
}
return result;
}
/**
* Returns a hash code based on the contents of the specified array. If
* the array contains other arrays as elements, the hash code is based on
* their identities rather than their contents. It is therefore
* acceptable to invoke this method on an array that contains itself as an
* element, either directly or indirectly through one or more levels of
* arrays.
*
* For any two arrays a and b such that
* Arrays.equals(a, b), it is also the case that
* Arrays.hashCode(a) == Arrays.hashCode(b).
*
* The value returned by this method is equal to the value that would
* be returned by Arrays.asList(a).hashCode(), unless a
* is null, in which case 0 is returned.
*
* @param a the array whose content-based hash code to compute
* @return a content-based hash code for a
* @see #deepHashCode(Object[])
* @since 1.5
*/
public static int hashCode(Object a[]) {
if (a == null)
return 0;
int result = 1;
for (Object element : a)
result = 31 * result + (element == null ? 0 : element.hashCode());
return result;
}
/**
* Returns a hash code based on the "deep contents" of the specified
* array. If the array contains other arrays as elements, the
* hash code is based on their contents and so on, ad infinitum.
* It is therefore unacceptable to invoke this method on an array that
* contains itself as an element, either directly or indirectly through
* one or more levels of arrays. The behavior of such an invocation is
* undefined.
*
* For any two arrays a and b such that
* Arrays.deepEquals(a, b), it is also the case that
* Arrays.deepHashCode(a) == Arrays.deepHashCode(b).
*
* The computation of the value returned by this method is similar to
* that of the value returned by {@link List#hashCode()} on a list
* containing the same elements as a in the same order, with one
* difference: If an element e of a is itself an array,
* its hash code is computed not by calling e.hashCode(), but as
* by calling the appropriate overloading of Arrays.hashCode(e)
* if e is an array of a primitive type, or as by calling
* Arrays.deepHashCode(e) recursively if e is an array
* of a reference type. If a is null, this method
* returns 0.
*
* @param a the array whose deep-content-based hash code to compute
* @return a deep-content-based hash code for a
* @see #hashCode(Object[])
* @since 1.5
*/
public static int deepHashCode(Object a[]) {
if (a == null)
return 0;
int result = 1;
for (Object element : a) {
int elementHash = 0;
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();
result = 31 * result + elementHash;
}
return result;
}
/**
* Returns true if the two specified arrays are deeply
* equal to one another. Unlike the @link{#equals{Object[],Object[])
* method, this method is appropriate for use with nested arrays of
* arbitrary depth.
*
* Two array references are considered deeply equal if both
* are null, or if they refer to arrays that contain the same
* number of elements and all corresponding pairs of elements in the two
* arrays are deeply equal.
*
* Two possibly null elements e1 and e2 are
* deeply equal if any of the following conditions hold:
* If either of the specified arrays contain themselves as elements
* either directly or indirectly through one or more levels of arrays,
* the behavior of this method is undefined.
*
* @param a1 one array to be tested for equality
* @param a2 the other array to be tested for equality
* @return true if the two arrays are equal
* @see #equals(Object[],Object[])
* @since 1.5
*/
public static boolean deepEquals(Object[] a1, Object[] a2) {
if (a1 == a2)
return true;
if (a1 == null || a2==null)
return false;
int length = a1.length;
if (a2.length != length)
return false;
for (int i = 0; i < length; i++) {
Object e1 = a1[i];
Object e2 = a2[i];
if (e1 == e2)
continue;
if (e1 == null)
return false;
// Figure out whether the two elements are equal
boolean eq;
if (e1 instanceof Object[] && e2 instanceof Object[])
eq = deepEquals ((Object[]) e1, (Object[]) e2);
else if (e1 instanceof byte[] && e2 instanceof byte[])
eq = equals((byte[]) e1, (byte[]) e2);
else if (e1 instanceof short[] && e2 instanceof short[])
eq = equals((short[]) e1, (short[]) e2);
else if (e1 instanceof int[] && e2 instanceof int[])
eq = equals((int[]) e1, (int[]) e2);
else if (e1 instanceof long[] && e2 instanceof long[])
eq = equals((long[]) e1, (long[]) e2);
else if (e1 instanceof char[] && e2 instanceof char[])
eq = equals((char[]) e1, (char[]) e2);
else if (e1 instanceof float[] && e2 instanceof float[])
eq = equals((float[]) e1, (float[]) e2);
else if (e1 instanceof double[] && e2 instanceof double[])
eq = equals((double[]) e1, (double[]) e2);
else if (e1 instanceof boolean[] && e2 instanceof boolean[])
eq = equals((boolean[]) e1, (boolean[]) e2);
else
eq = e1.equals(e2);
if (!eq)
return false;
}
return true;
}
/**
* Returns a string representation of the contents of the specified array.
* The string representation consists of a list of the array's elements,
* enclosed in square brackets ("[]"). Adjacent elements are
* separated by the characters ", " (a comma followed by a
* space). Elements are converted to strings as by
* String.valueOf(long). Returns "null" if a
* is null.
*
* @param a the array whose string representation to return
* @return a string representation of a
* @since 1.5
*/
public static String toString(long[] a) {
if (a == null)
return "null";
if (a.length == 0)
return "[]";
StringBuilder buf = new StringBuilder();
buf.append('[');
buf.append(a[0]);
for (int i = 1; i < a.length; i++) {
buf.append(", ");
buf.append(a[i]);
}
buf.append("]");
return buf.toString();
}
/**
* Returns a string representation of the contents of the specified array.
* The string representation consists of a list of the array's elements,
* enclosed in square brackets ("[]"). Adjacent elements are
* separated by the characters ", " (a comma followed by a
* space). Elements are converted to strings as by
* String.valueOf(int). Returns "null" if a is
* null.
*
* @param a the array whose string representation to return
* @return a string representation of a
* @since 1.5
*/
public static String toString(int[] a) {
if (a == null)
return "null";
if (a.length == 0)
return "[]";
StringBuilder buf = new StringBuilder();
buf.append('[');
buf.append(a[0]);
for (int i = 1; i < a.length; i++) {
buf.append(", ");
buf.append(a[i]);
}
buf.append("]");
return buf.toString();
}
/**
* Returns a string representation of the contents of the specified array.
* The string representation consists of a list of the array's elements,
* enclosed in square brackets ("[]"). Adjacent elements are
* separated by the characters ", " (a comma followed by a
* space). Elements are converted to strings as by
* String.valueOf(short). Returns "null" if a
* is null.
*
* @param a the array whose string representation to return
* @return a string representation of a
* @since 1.5
*/
public static String toString(short[] a) {
if (a == null)
return "null";
if (a.length == 0)
return "[]";
StringBuilder buf = new StringBuilder();
buf.append('[');
buf.append(a[0]);
for (int i = 1; i < a.length; i++) {
buf.append(", ");
buf.append(a[i]);
}
buf.append("]");
return buf.toString();
}
/**
* Returns a string representation of the contents of the specified array.
* The string representation consists of a list of the array's elements,
* enclosed in square brackets ("[]"). Adjacent elements are
* separated by the characters ", " (a comma followed by a
* space). Elements are converted to strings as by
* String.valueOf(char). Returns "null" if a
* is null.
*
* @param a the array whose string representation to return
* @return a string representation of a
* @since 1.5
*/
public static String toString(char[] a) {
if (a == null)
return "null";
if (a.length == 0)
return "[]";
StringBuilder buf = new StringBuilder();
buf.append('[');
buf.append(a[0]);
for (int i = 1; i < a.length; i++) {
buf.append(", ");
buf.append(a[i]);
}
buf.append("]");
return buf.toString();
}
/**
* Returns a string representation of the contents of the specified array.
* The string representation consists of a list of the array's elements,
* enclosed in square brackets ("[]"). Adjacent elements
* are separated by the characters ", " (a comma followed
* by a space). Elements are converted to strings as by
* String.valueOf(byte). Returns "null" if
* a is null.
*
* @param a the array whose string representation to return
* @return a string representation of a
* @since 1.5
*/
public static String toString(byte[] a) {
if (a == null)
return "null";
if (a.length == 0)
return "[]";
StringBuilder buf = new StringBuilder();
buf.append('[');
buf.append(a[0]);
for (int i = 1; i < a.length; i++) {
buf.append(", ");
buf.append(a[i]);
}
buf.append("]");
return buf.toString();
}
/**
* Returns a string representation of the contents of the specified array.
* The string representation consists of a list of the array's elements,
* enclosed in square brackets ("[]"). Adjacent elements are
* separated by the characters ", " (a comma followed by a
* space). Elements are converted to strings as by
* String.valueOf(boolean). Returns "null" if
* a is null.
*
* @param a the array whose string representation to return
* @return a string representation of a
* @since 1.5
*/
public static String toString(boolean[] a) {
if (a == null)
return "null";
if (a.length == 0)
return "[]";
StringBuilder buf = new StringBuilder();
buf.append('[');
buf.append(a[0]);
for (int i = 1; i < a.length; i++) {
buf.append(", ");
buf.append(a[i]);
}
buf.append("]");
return buf.toString();
}
/**
* Returns a string representation of the contents of the specified array.
* The string representation consists of a list of the array's elements,
* enclosed in square brackets ("[]"). Adjacent elements are
* separated by the characters ", " (a comma followed by a
* space). Elements are converted to strings as by
* String.valueOf(float). Returns "null" if a
* is null.
*
* @param a the array whose string representation to return
* @return a string representation of a
* @since 1.5
*/
public static String toString(float[] a) {
if (a == null)
return "null";
if (a.length == 0)
return "[]";
StringBuilder buf = new StringBuilder();
buf.append('[');
buf.append(a[0]);
for (int i = 1; i < a.length; i++) {
buf.append(", ");
buf.append(a[i]);
}
buf.append("]");
return buf.toString();
}
/**
* Returns a string representation of the contents of the specified array.
* The string representation consists of a list of the array's elements,
* enclosed in square brackets ("[]"). Adjacent elements are
* separated by the characters ", " (a comma followed by a
* space). Elements are converted to strings as by
* String.valueOf(double). Returns "null" if a
* is null.
*
* @param a the array whose string representation to return
* @return a string representation of a
* @since 1.5
*/
public static String toString(double[] a) {
if (a == null)
return "null";
if (a.length == 0)
return "[]";
StringBuilder buf = new StringBuilder();
buf.append('[');
buf.append(a[0]);
for (int i = 1; i < a.length; i++) {
buf.append(", ");
buf.append(a[i]);
}
buf.append("]");
return buf.toString();
}
/**
* Returns a string representation of the contents of the specified array.
* If the array contains other arrays as elements, they are converted to
* strings by the {@link Object#toString} method inherited from
* Object, which describes their identities rather than
* their contents.
*
* The value returned by this method is equal to the value that would
* be returned by Arrays.asList(a).toString(), unless a
* is null, in which case "null" is returned.
*
* @param a the array whose string representation to return
* @return a string representation of a
* @see #deepToString(Object[])
* @since 1.5
*/
public static String toString(Object[] a) {
if (a == null)
return "null";
if (a.length == 0)
return "[]";
StringBuilder buf = new StringBuilder();
for (int i = 0; i < a.length; i++) {
if (i == 0)
buf.append('[');
else
buf.append(", ");
buf.append(String.valueOf(a[i]));
}
buf.append("]");
return buf.toString();
}
/**
* Returns a string representation of the "deep contents" of the specified
* array. If the array contains other arrays as elements, the string
* representation contains their contents and so on. This method is
* designed for converting multidimensional arrays to strings.
*
* The string representation consists of a list of the array's
* elements, enclosed in square brackets ("[]"). Adjacent
* elements are separated by the characters ", " (a comma
* followed by a space). Elements are converted to strings as by
* String.valueOf(Object), unless they are themselves
* arrays.
*
* If an element e is an array of a primitive type, it is
* converted to a string as by invoking the appropriate overloading of
* Arrays.toString(e). If an element e is an array of a
* reference type, it is converted to a string as by invoking
* this method recursively.
*
* To avoid infinite recursion, if the specified array contains itself
* as an element, or contains an indirect reference to itself through one
* or more levels of arrays, the self-reference is converted to the string
* "[...]". For example, an array containing only a reference
* to itself would be rendered as "[[...]]".
*
* This method returns "null" if the specified array
* is null.
*
* @param a the array whose string representation to return
* @return a string representation of a
* @see #toString(Object[])
* @since 1.5
*/
public static String deepToString(Object[] a) {
if (a == null)
return "null";
int bufLen = 20 * a.length;
if (a.length != 0 && bufLen <= 0)
bufLen = Integer.MAX_VALUE;
StringBuilder buf = new StringBuilder(bufLen);
deepToString(a, buf, new HashSet());
return buf.toString();
}
private static void deepToString(Object[] a, StringBuilder buf,
Set new Double(d1).equals(new Double(d2))
* (Unlike the == operator, this method considers
* NaN equals to itself, and 0.0d unequal to -0.0d.)
*
* @param a one array to be tested for equality.
* @param a2 the other array to be tested for equality.
* @return true if the two arrays are equal.
* @see Double#equals(Object)
*/
public static boolean equals(double[] a, double[] a2) {
if (a==a2)
return true;
if (a==null || a2==null)
return false;
int length = a.length;
if (a2.length != length)
return false;
for (int i=0; i new Float(f1).equals(new Float(f2))
* (Unlike the == operator, this method considers
* NaN equals to itself, and 0.0f unequal to -0.0f.)
*
* @param a one array to be tested for equality.
* @param a2 the other array to be tested for equality.
* @return true if the two arrays are equal.
* @see Float#equals(Object)
*/
public static boolean equals(float[] a, float[] a2) {
if (a==a2)
return true;
if (a==null || a2==null)
return false;
int length = a.length;
if (a2.length != length)
return false;
for (int i=0; i
* List
*
* @param a the array by which the list will be backed.
* @return a list view of the specified array.
* @see Collection#toArray()
*/
public static
*
* Note that this definition permits null elements at any depth.
*
*