• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17 
18 package java.util;
19 
20 import java.io.Serializable;
21 import java.lang.reflect.Array;
22 
23 /**
24  * {@code Arrays} contains static methods which operate on arrays.
25  *
26  * @since 1.2
27  */
28 public class Arrays {
29     private static class ArrayList<E> extends AbstractList<E> implements
30             List<E>, Serializable, RandomAccess {
31 
32         private static final long serialVersionUID = -2764017481108945198L;
33 
34         private final E[] a;
35 
ArrayList(E[] storage)36         ArrayList(E[] storage) {
37             if (storage == null) {
38                 throw new NullPointerException("storage == null");
39             }
40             a = storage;
41         }
42 
43         @Override
contains(Object object)44         public boolean contains(Object object) {
45             if (object != null) {
46                 for (E element : a) {
47                     if (object.equals(element)) {
48                         return true;
49                     }
50                 }
51             } else {
52                 for (E element : a) {
53                     if (element == null) {
54                         return true;
55                     }
56                 }
57             }
58             return false;
59         }
60 
61         @Override
get(int location)62         public E get(int location) {
63             try {
64                 return a[location];
65             } catch (ArrayIndexOutOfBoundsException e) {
66                 throw java.util.ArrayList.throwIndexOutOfBoundsException(location, a.length);
67             }
68         }
69 
70         @Override
indexOf(Object object)71         public int indexOf(Object object) {
72             if (object != null) {
73                 for (int i = 0; i < a.length; i++) {
74                     if (object.equals(a[i])) {
75                         return i;
76                     }
77                 }
78             } else {
79                 for (int i = 0; i < a.length; i++) {
80                     if (a[i] == null) {
81                         return i;
82                     }
83                 }
84             }
85             return -1;
86         }
87 
88         @Override
lastIndexOf(Object object)89         public int lastIndexOf(Object object) {
90             if (object != null) {
91                 for (int i = a.length - 1; i >= 0; i--) {
92                     if (object.equals(a[i])) {
93                         return i;
94                     }
95                 }
96             } else {
97                 for (int i = a.length - 1; i >= 0; i--) {
98                     if (a[i] == null) {
99                         return i;
100                     }
101                 }
102             }
103             return -1;
104         }
105 
106         @Override
set(int location, E object)107         public E set(int location, E object) {
108             E result = a[location];
109             a[location] = object;
110             return result;
111         }
112 
113         @Override
size()114         public int size() {
115             return a.length;
116         }
117 
118         @Override
toArray()119         public Object[] toArray() {
120             return a.clone();
121         }
122 
123         @Override
124         @SuppressWarnings({"unchecked", "SuspiciousSystemArraycopy"})
toArray(T[] contents)125         public <T> T[] toArray(T[] contents) {
126             int size = size();
127             if (size > contents.length) {
128                 Class<?> ct = contents.getClass().getComponentType();
129                 contents = (T[]) Array.newInstance(ct, size);
130             }
131             System.arraycopy(a, 0, contents, 0, size);
132             if (size < contents.length) {
133                 contents[size] = null;
134             }
135             return contents;
136         }
137     }
138 
Arrays()139     private Arrays() {
140         /* empty */
141     }
142 
143     /**
144      * Returns a {@code List} of the objects in the specified array. The size of the
145      * {@code List} cannot be modified, i.e. adding and removing are unsupported, but
146      * the elements can be set. Setting an element modifies the underlying
147      * array.
148      *
149      * @param array
150      *            the array.
151      * @return a {@code List} of the elements of the specified array.
152      */
153     @SafeVarargs
asList(T... array)154     public static <T> List<T> asList(T... array) {
155         return new ArrayList<T>(array);
156     }
157 
158     /**
159      * Performs a binary search for {@code value} in the ascending sorted array {@code array}.
160      * Searching in an unsorted array has an undefined result. It's also undefined which element
161      * is found if there are multiple occurrences of the same element.
162      *
163      * @param array the sorted array to search.
164      * @param value the element to find.
165      * @return the non-negative index of the element, or a negative index which
166      *         is {@code -index - 1} where the element would be inserted.
167      */
binarySearch(byte[] array, byte value)168     public static int binarySearch(byte[] array, byte value) {
169         return binarySearch(array, 0, array.length, value);
170     }
171 
172     /**
173      * Performs a binary search for {@code value} in the ascending sorted array {@code array},
174      * in the range specified by fromIndex (inclusive) and toIndex (exclusive).
175      * Searching in an unsorted array has an undefined result. It's also undefined which element
176      * is found if there are multiple occurrences of the same element.
177      *
178      * @param array the sorted array to search.
179      * @param startIndex the inclusive start index.
180      * @param endIndex the exclusive start index.
181      * @param value the element to find.
182      * @return the non-negative index of the element, or a negative index which
183      *         is {@code -index - 1} where the element would be inserted.
184      * @throws IllegalArgumentException if {@code startIndex > endIndex}
185      * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length}
186      * @since 1.6
187      */
binarySearch(byte[] array, int startIndex, int endIndex, byte value)188     public static int binarySearch(byte[] array, int startIndex, int endIndex, byte value) {
189         checkBinarySearchBounds(startIndex, endIndex, array.length);
190         int lo = startIndex;
191         int hi = endIndex - 1;
192 
193         while (lo <= hi) {
194             int mid = (lo + hi) >>> 1;
195             byte midVal = array[mid];
196 
197             if (midVal < value) {
198                 lo = mid + 1;
199             } else if (midVal > value) {
200                 hi = mid - 1;
201             } else {
202                 return mid;  // value found
203             }
204         }
205         return ~lo;  // value not present
206     }
207 
208     /**
209      * Performs a binary search for {@code value} in the ascending sorted array {@code array}.
210      * Searching in an unsorted array has an undefined result. It's also undefined which element
211      * is found if there are multiple occurrences of the same element.
212      *
213      * @param array the sorted array to search.
214      * @param value the element to find.
215      * @return the non-negative index of the element, or a negative index which
216      *         is {@code -index - 1} where the element would be inserted.
217      */
binarySearch(char[] array, char value)218     public static int binarySearch(char[] array, char value) {
219         return binarySearch(array, 0, array.length, value);
220     }
221 
222     /**
223      * Performs a binary search for {@code value} in the ascending sorted array {@code array},
224      * in the range specified by fromIndex (inclusive) and toIndex (exclusive).
225      * Searching in an unsorted array has an undefined result. It's also undefined which element
226      * is found if there are multiple occurrences of the same element.
227      *
228      * @param array the sorted array to search.
229      * @param startIndex the inclusive start index.
230      * @param endIndex the exclusive start index.
231      * @param value the element to find.
232      * @return the non-negative index of the element, or a negative index which
233      *         is {@code -index - 1} where the element would be inserted.
234      * @throws IllegalArgumentException if {@code startIndex > endIndex}
235      * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length}
236      * @since 1.6
237      */
binarySearch(char[] array, int startIndex, int endIndex, char value)238     public static int binarySearch(char[] array, int startIndex, int endIndex, char value) {
239         checkBinarySearchBounds(startIndex, endIndex, array.length);
240         int lo = startIndex;
241         int hi = endIndex - 1;
242 
243         while (lo <= hi) {
244             int mid = (lo + hi) >>> 1;
245             char midVal = array[mid];
246 
247             if (midVal < value) {
248                 lo = mid + 1;
249             } else if (midVal > value) {
250                 hi = mid - 1;
251             } else {
252                 return mid;  // value found
253             }
254         }
255         return ~lo;  // value not present
256     }
257 
258     /**
259      * Performs a binary search for {@code value} in the ascending sorted array {@code array}.
260      * Searching in an unsorted array has an undefined result. It's also undefined which element
261      * is found if there are multiple occurrences of the same element.
262      *
263      * @param array the sorted array to search.
264      * @param value the element to find.
265      * @return the non-negative index of the element, or a negative index which
266      *         is {@code -index - 1} where the element would be inserted.
267      */
binarySearch(double[] array, double value)268     public static int binarySearch(double[] array, double value) {
269         return binarySearch(array, 0, array.length, value);
270     }
271 
272     /**
273      * Performs a binary search for {@code value} in the ascending sorted array {@code array},
274      * in the range specified by fromIndex (inclusive) and toIndex (exclusive).
275      * Searching in an unsorted array has an undefined result. It's also undefined which element
276      * is found if there are multiple occurrences of the same element.
277      *
278      * @param array the sorted array to search.
279      * @param startIndex the inclusive start index.
280      * @param endIndex the exclusive start index.
281      * @param value the element to find.
282      * @return the non-negative index of the element, or a negative index which
283      *         is {@code -index - 1} where the element would be inserted.
284      * @throws IllegalArgumentException if {@code startIndex > endIndex}
285      * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length}
286      * @since 1.6
287      */
binarySearch(double[] array, int startIndex, int endIndex, double value)288     public static int binarySearch(double[] array, int startIndex, int endIndex, double value) {
289         checkBinarySearchBounds(startIndex, endIndex, array.length);
290         int lo = startIndex;
291         int hi = endIndex - 1;
292 
293         while (lo <= hi) {
294             int mid = (lo + hi) >>> 1;
295             double midVal = array[mid];
296 
297             if (midVal < value) {
298                 lo = mid + 1;
299             } else if (midVal > value) {
300                 hi = mid - 1;
301             } else if (midVal != 0 && midVal == value) {
302                 return mid;  // value found
303             } else { // Either midVal and value are == 0 or at least one is NaN
304                 long midValBits = Double.doubleToLongBits(midVal);
305                 long valueBits  = Double.doubleToLongBits(value);
306 
307                 if (midValBits < valueBits) {
308                     lo = mid + 1; // (-0.0, 0.0) or (not NaN, NaN); midVal < val
309                 } else if (midValBits > valueBits) {
310                     hi = mid - 1; // (0.0, -0.0) or (NaN, not NaN); midVal > val
311                 } else {
312                     return mid; // bit patterns are equal; value found
313                 }
314             }
315         }
316         return ~lo;  // value not present
317     }
318 
319     /**
320      * Performs a binary search for {@code value} in the ascending sorted array {@code array}.
321      * Searching in an unsorted array has an undefined result. It's also undefined which element
322      * is found if there are multiple occurrences of the same element.
323      *
324      * @param array the sorted array to search.
325      * @param value the element to find.
326      * @return the non-negative index of the element, or a negative index which
327      *         is {@code -index - 1} where the element would be inserted.
328      */
binarySearch(float[] array, float value)329     public static int binarySearch(float[] array, float value) {
330         return binarySearch(array, 0, array.length, value);
331     }
332 
333     /**
334      * Performs a binary search for {@code value} in the ascending sorted array {@code array},
335      * in the range specified by fromIndex (inclusive) and toIndex (exclusive).
336      * Searching in an unsorted array has an undefined result. It's also undefined which element
337      * is found if there are multiple occurrences of the same element.
338      *
339      * @param array the sorted array to search.
340      * @param startIndex the inclusive start index.
341      * @param endIndex the exclusive start index.
342      * @param value the element to find.
343      * @return the non-negative index of the element, or a negative index which
344      *         is {@code -index - 1} where the element would be inserted.
345      * @throws IllegalArgumentException if {@code startIndex > endIndex}
346      * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length}
347      * @since 1.6
348      */
binarySearch(float[] array, int startIndex, int endIndex, float value)349     public static int binarySearch(float[] array, int startIndex, int endIndex, float value) {
350         checkBinarySearchBounds(startIndex, endIndex, array.length);
351         int lo = startIndex;
352         int hi = endIndex - 1;
353 
354         while (lo <= hi) {
355             int mid = (lo + hi) >>> 1;
356             float midVal = array[mid];
357 
358             if (midVal < value) {
359                 lo = mid + 1;
360             } else if (midVal > value) {
361                 hi = mid - 1;
362             } else if (midVal != 0 && midVal == value) {
363                 return mid;  // value found
364             } else { // Either midVal and value are == 0 or at least one is NaN
365                 int midValBits = Float.floatToIntBits(midVal);
366                 int valueBits  = Float.floatToIntBits(value);
367 
368                 if (midValBits < valueBits) {
369                     lo = mid + 1; // (-0.0, 0.0) or (not NaN, NaN); midVal < val
370                 } else if (midValBits > valueBits) {
371                     hi = mid - 1; // (0.0, -0.0) or (NaN, not NaN); midVal > val
372                 } else {
373                     return mid; // bit patterns are equal; value found
374                 }
375             }
376         }
377         return ~lo;  // value not present
378     }
379 
380     /**
381      * Performs a binary search for {@code value} in the ascending sorted array {@code array}.
382      * Searching in an unsorted array has an undefined result. It's also undefined which element
383      * is found if there are multiple occurrences of the same element.
384      *
385      * @param array the sorted array to search.
386      * @param value the element to find.
387      * @return the non-negative index of the element, or a negative index which
388      *         is {@code -index - 1} where the element would be inserted.
389      */
binarySearch(int[] array, int value)390     public static int binarySearch(int[] array, int value) {
391         return binarySearch(array, 0, array.length, value);
392     }
393 
394     /**
395      * Performs a binary search for {@code value} in the ascending sorted array {@code array},
396      * in the range specified by fromIndex (inclusive) and toIndex (exclusive).
397      * Searching in an unsorted array has an undefined result. It's also undefined which element
398      * is found if there are multiple occurrences of the same element.
399      *
400      * @param array the sorted array to search.
401      * @param startIndex the inclusive start index.
402      * @param endIndex the exclusive start index.
403      * @param value the element to find.
404      * @return the non-negative index of the element, or a negative index which
405      *         is {@code -index - 1} where the element would be inserted.
406      * @throws IllegalArgumentException if {@code startIndex > endIndex}
407      * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length}
408      * @since 1.6
409      */
binarySearch(int[] array, int startIndex, int endIndex, int value)410     public static int binarySearch(int[] array, int startIndex, int endIndex, int value) {
411         checkBinarySearchBounds(startIndex, endIndex, array.length);
412         int lo = startIndex;
413         int hi = endIndex - 1;
414 
415         while (lo <= hi) {
416             int mid = (lo + hi) >>> 1;
417             int midVal = array[mid];
418 
419             if (midVal < value) {
420                 lo = mid + 1;
421             } else if (midVal > value) {
422                 hi = mid - 1;
423             } else {
424                 return mid;  // value found
425             }
426         }
427         return ~lo;  // value not present
428     }
429 
430     /**
431      * Performs a binary search for {@code value} in the ascending sorted array {@code array}.
432      * Searching in an unsorted array has an undefined result. It's also undefined which element
433      * is found if there are multiple occurrences of the same element.
434      *
435      * @param array the sorted array to search.
436      * @param value the element to find.
437      * @return the non-negative index of the element, or a negative index which
438      *         is {@code -index - 1} where the element would be inserted.
439      */
binarySearch(long[] array, long value)440     public static int binarySearch(long[] array, long value) {
441         return binarySearch(array, 0, array.length, value);
442     }
443 
444     /**
445      * Performs a binary search for {@code value} in the ascending sorted array {@code array},
446      * in the range specified by fromIndex (inclusive) and toIndex (exclusive).
447      * Searching in an unsorted array has an undefined result. It's also undefined which element
448      * is found if there are multiple occurrences of the same element.
449      *
450      * @param array the sorted array to search.
451      * @param startIndex the inclusive start index.
452      * @param endIndex the exclusive start index.
453      * @param value the element to find.
454      * @return the non-negative index of the element, or a negative index which
455      *         is {@code -index - 1} where the element would be inserted.
456      * @throws IllegalArgumentException if {@code startIndex > endIndex}
457      * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length}
458      * @since 1.6
459      */
binarySearch(long[] array, int startIndex, int endIndex, long value)460     public static int binarySearch(long[] array, int startIndex, int endIndex, long value) {
461         checkBinarySearchBounds(startIndex, endIndex, array.length);
462         int lo = startIndex;
463         int hi = endIndex - 1;
464 
465         while (lo <= hi) {
466             int mid = (lo + hi) >>> 1;
467             long midVal = array[mid];
468 
469             if (midVal < value) {
470                 lo = mid + 1;
471             } else if (midVal > value) {
472                 hi = mid - 1;
473             } else {
474                 return mid;  // value found
475             }
476          }
477          return ~lo;  // value not present
478     }
479 
480     /**
481      * Performs a binary search for {@code value} in the ascending sorted array {@code array}.
482      * Searching in an unsorted array has an undefined result. It's also undefined which element
483      * is found if there are multiple occurrences of the same element.
484      *
485      * @param array the sorted array to search.
486      * @param value the element to find.
487      * @return the non-negative index of the element, or a negative index which
488      *         is {@code -index - 1} where the element would be inserted.
489      * @throws ClassCastException
490      *         if an element in the array or the search element does not
491      *         implement {@code Comparable}, or cannot be compared to each other.
492      */
binarySearch(Object[] array, Object value)493     public static int binarySearch(Object[] array, Object value) {
494         return binarySearch(array, 0, array.length, value);
495     }
496 
497     /**
498      * Performs a binary search for {@code value} in the ascending sorted array {@code array},
499      * in the range specified by fromIndex (inclusive) and toIndex (exclusive).
500      * Searching in an unsorted array has an undefined result. It's also undefined which element
501      * is found if there are multiple occurrences of the same element.
502      *
503      * @param array the sorted array to search.
504      * @param startIndex the inclusive start index.
505      * @param endIndex the exclusive start index.
506      * @param value the element to find.
507      * @return the non-negative index of the element, or a negative index which
508      *         is {@code -index - 1} where the element would be inserted.
509      * @throws ClassCastException
510      *         if an element in the array or the search element does not
511      *         implement {@code Comparable}, or cannot be compared to each other.
512      * @throws IllegalArgumentException if {@code startIndex > endIndex}
513      * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length}
514      * @since 1.6
515      */
binarySearch(Object[] array, int startIndex, int endIndex, Object value)516     public static int binarySearch(Object[] array, int startIndex, int endIndex, Object value) {
517         checkBinarySearchBounds(startIndex, endIndex, array.length);
518         int lo = startIndex;
519         int hi = endIndex - 1;
520 
521         while (lo <= hi) {
522             int mid = (lo + hi) >>> 1;
523             @SuppressWarnings("unchecked")
524             int midValCmp = ((Comparable) array[mid]).compareTo(value);
525 
526             if (midValCmp < 0) {
527                 lo = mid + 1;
528             } else if (midValCmp > 0) {
529                 hi = mid - 1;
530             } else {
531                 return mid;  // value found
532             }
533         }
534         return ~lo;  // value not present
535     }
536 
537     /**
538      * Performs a binary search for {@code value} in the ascending sorted array {@code array},
539      * using {@code comparator} to compare elements.
540      * Searching in an unsorted array has an undefined result. It's also undefined which element
541      * is found if there are multiple occurrences of the same element.
542      *
543      * @param array the sorted array to search.
544      * @param value the element to find.
545      * @param comparator the {@code Comparator} used to compare the elements.
546      * @return the non-negative index of the element, or a negative index which
547      *         is {@code -index - 1} where the element would be inserted.
548      * @throws ClassCastException
549      *         if an element in the array or the search element does not
550      *         implement {@code Comparable}, or cannot be compared to each other.
551      */
binarySearch(T[] array, T value, Comparator<? super T> comparator)552     public static <T> int binarySearch(T[] array, T value, Comparator<? super T> comparator) {
553         return binarySearch(array, 0, array.length, value, comparator);
554     }
555 
556     /**
557      * Performs a binary search for {@code value} in the ascending sorted array {@code array},
558      * in the range specified by fromIndex (inclusive) and toIndex (exclusive),
559      * using {@code comparator} to compare elements.
560      * Searching in an unsorted array has an undefined result. It's also undefined which element
561      * is found if there are multiple occurrences of the same element.
562      *
563      * @param array the sorted array to search.
564      * @param startIndex the inclusive start index.
565      * @param endIndex the exclusive start index.
566      * @param value the element to find.
567      * @param comparator the {@code Comparator} used to compare the elements.
568      * @return the non-negative index of the element, or a negative index which
569      *         is {@code -index - 1} where the element would be inserted.
570      * @throws ClassCastException
571      *         if an element in the array or the search element does not
572      *         implement {@code Comparable}, or cannot be compared to each other.
573      * @throws IllegalArgumentException if {@code startIndex > endIndex}
574      * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length}
575      * @since 1.6
576      */
binarySearch(T[] array, int startIndex, int endIndex, T value, Comparator<? super T> comparator)577     public static <T> int binarySearch(T[] array, int startIndex, int endIndex, T value,
578             Comparator<? super T> comparator) {
579         if (comparator == null) {
580             return binarySearch(array, startIndex, endIndex, value);
581         }
582 
583         checkBinarySearchBounds(startIndex, endIndex, array.length);
584         int lo = startIndex;
585         int hi = endIndex - 1;
586 
587         while (lo <= hi) {
588             int mid = (lo + hi) >>> 1;
589             int midValCmp = comparator.compare(array[mid], value);
590 
591             if (midValCmp < 0) {
592                 lo = mid + 1;
593             } else if (midValCmp > 0) {
594                 hi = mid - 1;
595             } else {
596                 return mid;  // value found
597             }
598         }
599         return ~lo;  // value not present
600     }
601 
602     /**
603      * Performs a binary search for {@code value} in the ascending sorted array {@code array}.
604      * Searching in an unsorted array has an undefined result. It's also undefined which element
605      * is found if there are multiple occurrences of the same element.
606      *
607      * @param array the sorted array to search.
608      * @param value the element to find.
609      * @return the non-negative index of the element, or a negative index which
610      *         is {@code -index - 1} where the element would be inserted.
611      */
binarySearch(short[] array, short value)612     public static int binarySearch(short[] array, short value) {
613         return binarySearch(array, 0, array.length, value);
614     }
615 
616     /**
617      * Performs a binary search for {@code value} in the ascending sorted array {@code array},
618      * in the range specified by fromIndex (inclusive) and toIndex (exclusive).
619      * Searching in an unsorted array has an undefined result. It's also undefined which element
620      * is found if there are multiple occurrences of the same element.
621      *
622      * @param array the sorted array to search.
623      * @param startIndex the inclusive start index.
624      * @param endIndex the exclusive start index.
625      * @param value the element to find.
626      * @return the non-negative index of the element, or a negative index which
627      *         is {@code -index - 1} where the element would be inserted.
628      * @throws IllegalArgumentException if {@code startIndex > endIndex}
629      * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length}
630      * @since 1.6
631      */
binarySearch(short[] array, int startIndex, int endIndex, short value)632     public static int binarySearch(short[] array, int startIndex, int endIndex, short value) {
633         checkBinarySearchBounds(startIndex, endIndex, array.length);
634         int lo = startIndex;
635         int hi = endIndex - 1;
636 
637         while (lo <= hi) {
638             int mid = (lo + hi) >>> 1;
639             short midVal = array[mid];
640 
641             if (midVal < value) {
642                 lo = mid + 1;
643             } else if (midVal > value) {
644                 hi = mid - 1;
645             } else {
646                 return mid;  // value found
647             }
648         }
649         return ~lo;  // value not present
650     }
651 
checkBinarySearchBounds(int startIndex, int endIndex, int length)652     private static void checkBinarySearchBounds(int startIndex, int endIndex, int length) {
653         if (startIndex > endIndex) {
654             throw new IllegalArgumentException();
655         }
656         if (startIndex < 0 || endIndex > length) {
657             throw new ArrayIndexOutOfBoundsException();
658         }
659     }
660 
661     /**
662      * Fills the specified array with the specified element.
663      *
664      * @param array
665      *            the {@code byte} array to fill.
666      * @param value
667      *            the {@code byte} element.
668      */
fill(byte[] array, byte value)669     public static void fill(byte[] array, byte value) {
670         for (int i = 0; i < array.length; i++) {
671             array[i] = value;
672         }
673     }
674 
675     /**
676      * Fills the specified range in the array with the specified element.
677      *
678      * @param array
679      *            the {@code byte} array to fill.
680      * @param start
681      *            the first index to fill.
682      * @param end
683      *            the last + 1 index to fill.
684      * @param value
685      *            the {@code byte} element.
686      * @throws IllegalArgumentException
687      *                if {@code start > end}.
688      * @throws ArrayIndexOutOfBoundsException
689      *                if {@code start < 0} or {@code end > array.length}.
690      */
fill(byte[] array, int start, int end, byte value)691     public static void fill(byte[] array, int start, int end, byte value) {
692         Arrays.checkStartAndEnd(array.length, start, end);
693         for (int i = start; i < end; i++) {
694             array[i] = value;
695         }
696     }
697 
698     /**
699      * Fills the specified array with the specified element.
700      *
701      * @param array
702      *            the {@code short} array to fill.
703      * @param value
704      *            the {@code short} element.
705      */
fill(short[] array, short value)706     public static void fill(short[] array, short value) {
707         for (int i = 0; i < array.length; i++) {
708             array[i] = value;
709         }
710     }
711 
712     /**
713      * Fills the specified range in the array with the specified element.
714      *
715      * @param array
716      *            the {@code short} array to fill.
717      * @param start
718      *            the first index to fill.
719      * @param end
720      *            the last + 1 index to fill.
721      * @param value
722      *            the {@code short} element.
723      * @throws IllegalArgumentException
724      *                if {@code start > end}.
725      * @throws ArrayIndexOutOfBoundsException
726      *                if {@code start < 0} or {@code end > array.length}.
727      */
fill(short[] array, int start, int end, short value)728     public static void fill(short[] array, int start, int end, short value) {
729         Arrays.checkStartAndEnd(array.length, start, end);
730         for (int i = start; i < end; i++) {
731             array[i] = value;
732         }
733     }
734 
735     /**
736      * Fills the specified array with the specified element.
737      *
738      * @param array
739      *            the {@code char} array to fill.
740      * @param value
741      *            the {@code char} element.
742      */
fill(char[] array, char value)743     public static void fill(char[] array, char value) {
744         for (int i = 0; i < array.length; i++) {
745             array[i] = value;
746         }
747     }
748 
749     /**
750      * Fills the specified range in the array with the specified element.
751      *
752      * @param array
753      *            the {@code char} array to fill.
754      * @param start
755      *            the first index to fill.
756      * @param end
757      *            the last + 1 index to fill.
758      * @param value
759      *            the {@code char} element.
760      * @throws IllegalArgumentException
761      *                if {@code start > end}.
762      * @throws ArrayIndexOutOfBoundsException
763      *                if {@code start < 0} or {@code end > array.length}.
764      */
fill(char[] array, int start, int end, char value)765     public static void fill(char[] array, int start, int end, char value) {
766         Arrays.checkStartAndEnd(array.length, start, end);
767         for (int i = start; i < end; i++) {
768             array[i] = value;
769         }
770     }
771 
772     /**
773      * Fills the specified array with the specified element.
774      *
775      * @param array
776      *            the {@code int} array to fill.
777      * @param value
778      *            the {@code int} element.
779      */
fill(int[] array, int value)780     public static void fill(int[] array, int value) {
781         for (int i = 0; i < array.length; i++) {
782             array[i] = value;
783         }
784     }
785 
786     /**
787      * Fills the specified range in the array with the specified element.
788      *
789      * @param array
790      *            the {@code int} array to fill.
791      * @param start
792      *            the first index to fill.
793      * @param end
794      *            the last + 1 index to fill.
795      * @param value
796      *            the {@code int} element.
797      * @throws IllegalArgumentException
798      *                if {@code start > end}.
799      * @throws ArrayIndexOutOfBoundsException
800      *                if {@code start < 0} or {@code end > array.length}.
801      */
fill(int[] array, int start, int end, int value)802     public static void fill(int[] array, int start, int end, int value) {
803         Arrays.checkStartAndEnd(array.length, start, end);
804         for (int i = start; i < end; i++) {
805             array[i] = value;
806         }
807     }
808 
809     /**
810      * Fills the specified array with the specified element.
811      *
812      * @param array
813      *            the {@code long} array to fill.
814      * @param value
815      *            the {@code long} element.
816      */
fill(long[] array, long value)817     public static void fill(long[] array, long value) {
818         for (int i = 0; i < array.length; i++) {
819             array[i] = value;
820         }
821     }
822 
823     /**
824      * Fills the specified range in the array with the specified element.
825      *
826      * @param array
827      *            the {@code long} array to fill.
828      * @param start
829      *            the first index to fill.
830      * @param end
831      *            the last + 1 index to fill.
832      * @param value
833      *            the {@code long} element.
834      * @throws IllegalArgumentException
835      *                if {@code start > end}.
836      * @throws ArrayIndexOutOfBoundsException
837      *                if {@code start < 0} or {@code end > array.length}.
838      */
fill(long[] array, int start, int end, long value)839     public static void fill(long[] array, int start, int end, long value) {
840         Arrays.checkStartAndEnd(array.length, start, end);
841         for (int i = start; i < end; i++) {
842             array[i] = value;
843         }
844     }
845 
846     /**
847      * Fills the specified array with the specified element.
848      *
849      * @param array
850      *            the {@code float} array to fill.
851      * @param value
852      *            the {@code float} element.
853      */
fill(float[] array, float value)854     public static void fill(float[] array, float value) {
855         for (int i = 0; i < array.length; i++) {
856             array[i] = value;
857         }
858     }
859 
860     /**
861      * Fills the specified range in the array with the specified element.
862      *
863      * @param array
864      *            the {@code float} array to fill.
865      * @param start
866      *            the first index to fill.
867      * @param end
868      *            the last + 1 index to fill.
869      * @param value
870      *            the {@code float} element.
871      * @throws IllegalArgumentException
872      *                if {@code start > end}.
873      * @throws ArrayIndexOutOfBoundsException
874      *                if {@code start < 0} or {@code end > array.length}.
875      */
fill(float[] array, int start, int end, float value)876     public static void fill(float[] array, int start, int end, float value) {
877         Arrays.checkStartAndEnd(array.length, start, end);
878         for (int i = start; i < end; i++) {
879             array[i] = value;
880         }
881     }
882 
883     /**
884      * Fills the specified array with the specified element.
885      *
886      * @param array
887      *            the {@code double} array to fill.
888      * @param value
889      *            the {@code double} element.
890      */
fill(double[] array, double value)891     public static void fill(double[] array, double value) {
892         for (int i = 0; i < array.length; i++) {
893             array[i] = value;
894         }
895     }
896 
897     /**
898      * Fills the specified range in the array with the specified element.
899      *
900      * @param array
901      *            the {@code double} array to fill.
902      * @param start
903      *            the first index to fill.
904      * @param end
905      *            the last + 1 index to fill.
906      * @param value
907      *            the {@code double} element.
908      * @throws IllegalArgumentException
909      *                if {@code start > end}.
910      * @throws ArrayIndexOutOfBoundsException
911      *                if {@code start < 0} or {@code end > array.length}.
912      */
fill(double[] array, int start, int end, double value)913     public static void fill(double[] array, int start, int end, double value) {
914         Arrays.checkStartAndEnd(array.length, start, end);
915         for (int i = start; i < end; i++) {
916             array[i] = value;
917         }
918     }
919 
920     /**
921      * Fills the specified array with the specified element.
922      *
923      * @param array
924      *            the {@code boolean} array to fill.
925      * @param value
926      *            the {@code boolean} element.
927      */
fill(boolean[] array, boolean value)928     public static void fill(boolean[] array, boolean value) {
929         for (int i = 0; i < array.length; i++) {
930             array[i] = value;
931         }
932     }
933 
934     /**
935      * Fills the specified range in the array with the specified element.
936      *
937      * @param array
938      *            the {@code boolean} array to fill.
939      * @param start
940      *            the first index to fill.
941      * @param end
942      *            the last + 1 index to fill.
943      * @param value
944      *            the {@code boolean} element.
945      * @throws IllegalArgumentException
946      *                if {@code start > end}.
947      * @throws ArrayIndexOutOfBoundsException
948      *                if {@code start < 0} or {@code end > array.length}.
949      */
fill(boolean[] array, int start, int end, boolean value)950     public static void fill(boolean[] array, int start, int end, boolean value) {
951         Arrays.checkStartAndEnd(array.length, start, end);
952         for (int i = start; i < end; i++) {
953             array[i] = value;
954         }
955     }
956 
957     /**
958      * Fills the specified array with the specified element.
959      *
960      * @param array
961      *            the {@code Object} array to fill.
962      * @param value
963      *            the {@code Object} element.
964      */
fill(Object[] array, Object value)965     public static void fill(Object[] array, Object value) {
966         for (int i = 0; i < array.length; i++) {
967             array[i] = value;
968         }
969     }
970 
971     /**
972      * Fills the specified range in the array with the specified element.
973      *
974      * @param array
975      *            the {@code Object} array to fill.
976      * @param start
977      *            the first index to fill.
978      * @param end
979      *            the last + 1 index to fill.
980      * @param value
981      *            the {@code Object} element.
982      * @throws IllegalArgumentException
983      *                if {@code start > end}.
984      * @throws ArrayIndexOutOfBoundsException
985      *                if {@code start < 0} or {@code end > array.length}.
986      */
fill(Object[] array, int start, int end, Object value)987     public static void fill(Object[] array, int start, int end, Object value) {
988         Arrays.checkStartAndEnd(array.length, start, end);
989         for (int i = start; i < end; i++) {
990             array[i] = value;
991         }
992     }
993 
994     /**
995      * Returns a hash code based on the contents of the given array. For any two
996      * {@code boolean} arrays {@code a} and {@code b}, if
997      * {@code Arrays.equals(a, b)} returns {@code true}, it means
998      * that the return value of {@code Arrays.hashCode(a)} equals {@code Arrays.hashCode(b)}.
999      * <p>
1000      * The value returned by this method is the same value as the
1001      * {@link List#hashCode()} method which is invoked on a {@link List}
1002      * containing a sequence of {@link Boolean} instances representing the
1003      * elements of array in the same order. If the array is {@code null}, the return
1004      * value is 0.
1005      *
1006      * @param array
1007      *            the array whose hash code to compute.
1008      * @return the hash code for {@code array}.
1009      */
hashCode(boolean[] array)1010     public static int hashCode(boolean[] array) {
1011         if (array == null) {
1012             return 0;
1013         }
1014         int hashCode = 1;
1015         for (boolean element : array) {
1016             // 1231, 1237 are hash code values for boolean value
1017             hashCode = 31 * hashCode + (element ? 1231 : 1237);
1018         }
1019         return hashCode;
1020     }
1021 
1022     /**
1023      * Returns a hash code based on the contents of the given array. For any two
1024      * not-null {@code int} arrays {@code a} and {@code b}, if
1025      * {@code Arrays.equals(a, b)} returns {@code true}, it means
1026      * that the return value of {@code Arrays.hashCode(a)} equals {@code Arrays.hashCode(b)}.
1027      * <p>
1028      * The value returned by this method is the same value as the
1029      * {@link List#hashCode()} method which is invoked on a {@link List}
1030      * containing a sequence of {@link Integer} instances representing the
1031      * elements of array in the same order. If the array is {@code null}, the return
1032      * value is 0.
1033      *
1034      * @param array
1035      *            the array whose hash code to compute.
1036      * @return the hash code for {@code array}.
1037      */
hashCode(int[] array)1038     public static int hashCode(int[] array) {
1039         if (array == null) {
1040             return 0;
1041         }
1042         int hashCode = 1;
1043         for (int element : array) {
1044             // the hash code value for integer value is integer value itself
1045             hashCode = 31 * hashCode + element;
1046         }
1047         return hashCode;
1048     }
1049 
1050     /**
1051      * Returns a hash code based on the contents of the given array. For any two
1052      * {@code short} arrays {@code a} and {@code b}, if
1053      * {@code Arrays.equals(a, b)} returns {@code true}, it means
1054      * that the return value of {@code Arrays.hashCode(a)} equals {@code Arrays.hashCode(b)}.
1055      * <p>
1056      * The value returned by this method is the same value as the
1057      * {@link List#hashCode()} method which is invoked on a {@link List}
1058      * containing a sequence of {@link Short} instances representing the
1059      * elements of array in the same order. If the array is {@code null}, the return
1060      * value is 0.
1061      *
1062      * @param array
1063      *            the array whose hash code to compute.
1064      * @return the hash code for {@code array}.
1065      */
hashCode(short[] array)1066     public static int hashCode(short[] array) {
1067         if (array == null) {
1068             return 0;
1069         }
1070         int hashCode = 1;
1071         for (short element : array) {
1072             // the hash code value for short value is its integer value
1073             hashCode = 31 * hashCode + element;
1074         }
1075         return hashCode;
1076     }
1077 
1078     /**
1079      * Returns a hash code based on the contents of the given array. For any two
1080      * {@code char} arrays {@code a} and {@code b}, if
1081      * {@code Arrays.equals(a, b)} returns {@code true}, it means
1082      * that the return value of {@code Arrays.hashCode(a)} equals {@code Arrays.hashCode(b)}.
1083      * <p>
1084      * The value returned by this method is the same value as the
1085      * {@link List#hashCode()} method which is invoked on a {@link List}
1086      * containing a sequence of {@link Character} instances representing the
1087      * elements of array in the same order. If the array is {@code null}, the return
1088      * value is 0.
1089      *
1090      * @param array
1091      *            the array whose hash code to compute.
1092      * @return the hash code for {@code array}.
1093      */
hashCode(char[] array)1094     public static int hashCode(char[] array) {
1095         if (array == null) {
1096             return 0;
1097         }
1098         int hashCode = 1;
1099         for (char element : array) {
1100             // the hash code value for char value is its integer value
1101             hashCode = 31 * hashCode + element;
1102         }
1103         return hashCode;
1104     }
1105 
1106     /**
1107      * Returns a hash code based on the contents of the given array. For any two
1108      * {@code byte} arrays {@code a} and {@code b}, if
1109      * {@code Arrays.equals(a, b)} returns {@code true}, it means
1110      * that the return value of {@code Arrays.hashCode(a)} equals {@code Arrays.hashCode(b)}.
1111      * <p>
1112      * The value returned by this method is the same value as the
1113      * {@link List#hashCode()} method which is invoked on a {@link List}
1114      * containing a sequence of {@link Byte} instances representing the
1115      * elements of array in the same order. If the array is {@code null}, the return
1116      * value is 0.
1117      *
1118      * @param array
1119      *            the array whose hash code to compute.
1120      * @return the hash code for {@code array}.
1121      */
hashCode(byte[] array)1122     public static int hashCode(byte[] array) {
1123         if (array == null) {
1124             return 0;
1125         }
1126         int hashCode = 1;
1127         for (byte element : array) {
1128             // the hash code value for byte value is its integer value
1129             hashCode = 31 * hashCode + element;
1130         }
1131         return hashCode;
1132     }
1133 
1134     /**
1135      * Returns a hash code based on the contents of the given array. For any two
1136      * {@code long} arrays {@code a} and {@code b}, if
1137      * {@code Arrays.equals(a, b)} returns {@code true}, it means
1138      * that the return value of {@code Arrays.hashCode(a)} equals {@code Arrays.hashCode(b)}.
1139      * <p>
1140      * The value returned by this method is the same value as the
1141      * {@link List#hashCode()} method which is invoked on a {@link List}
1142      * containing a sequence of {@link Long} instances representing the
1143      * elements of array in the same order. If the array is {@code null}, the return
1144      * value is 0.
1145      *
1146      * @param array
1147      *            the array whose hash code to compute.
1148      * @return the hash code for {@code array}.
1149      */
hashCode(long[] array)1150     public static int hashCode(long[] array) {
1151         if (array == null) {
1152             return 0;
1153         }
1154         int hashCode = 1;
1155         for (long elementValue : array) {
1156             /*
1157              * the hash code value for long value is (int) (value ^ (value >>>
1158              * 32))
1159              */
1160             hashCode = 31 * hashCode
1161                     + (int) (elementValue ^ (elementValue >>> 32));
1162         }
1163         return hashCode;
1164     }
1165 
1166     /**
1167      * Returns a hash code based on the contents of the given array. For any two
1168      * {@code float} arrays {@code a} and {@code b}, if
1169      * {@code Arrays.equals(a, b)} returns {@code true}, it means
1170      * that the return value of {@code Arrays.hashCode(a)} equals {@code Arrays.hashCode(b)}.
1171      * <p>
1172      * The value returned by this method is the same value as the
1173      * {@link List#hashCode()} method which is invoked on a {@link List}
1174      * containing a sequence of {@link Float} instances representing the
1175      * elements of array in the same order. If the array is {@code null}, the return
1176      * value is 0.
1177      *
1178      * @param array
1179      *            the array whose hash code to compute.
1180      * @return the hash code for {@code array}.
1181      */
hashCode(float[] array)1182     public static int hashCode(float[] array) {
1183         if (array == null) {
1184             return 0;
1185         }
1186         int hashCode = 1;
1187         for (float element : array) {
1188             /*
1189              * the hash code value for float value is
1190              * Float.floatToIntBits(value)
1191              */
1192             hashCode = 31 * hashCode + Float.floatToIntBits(element);
1193         }
1194         return hashCode;
1195     }
1196 
1197     /**
1198      * Returns a hash code based on the contents of the given array. For any two
1199      * {@code double} arrays {@code a} and {@code b}, if
1200      * {@code Arrays.equals(a, b)} returns {@code true}, it means
1201      * that the return value of {@code Arrays.hashCode(a)} equals {@code Arrays.hashCode(b)}.
1202      * <p>
1203      * The value returned by this method is the same value as the
1204      * {@link List#hashCode()} method which is invoked on a {@link List}
1205      * containing a sequence of {@link Double} instances representing the
1206      * elements of array in the same order. If the array is {@code null}, the return
1207      * value is 0.
1208      *
1209      * @param array
1210      *            the array whose hash code to compute.
1211      * @return the hash code for {@code array}.
1212      */
hashCode(double[] array)1213     public static int hashCode(double[] array) {
1214         if (array == null) {
1215             return 0;
1216         }
1217         int hashCode = 1;
1218 
1219         for (double element : array) {
1220             long v = Double.doubleToLongBits(element);
1221             /*
1222              * the hash code value for double value is (int) (v ^ (v >>> 32))
1223              * where v = Double.doubleToLongBits(value)
1224              */
1225             hashCode = 31 * hashCode + (int) (v ^ (v >>> 32));
1226         }
1227         return hashCode;
1228     }
1229 
1230     /**
1231      * Returns a hash code based on the contents of the given array. If the
1232      * array contains other arrays as its elements, the hash code is based on
1233      * their identities not their contents. So it is acceptable to invoke this
1234      * method on an array that contains itself as an element, either directly or
1235      * indirectly.
1236      * <p>
1237      * For any two arrays {@code a} and {@code b}, if
1238      * {@code Arrays.equals(a, b)} returns {@code true}, it means
1239      * that the return value of {@code Arrays.hashCode(a)} equals
1240      * {@code Arrays.hashCode(b)}.
1241      * <p>
1242      * The value returned by this method is the same value as the method
1243      * Arrays.asList(array).hashCode(). If the array is {@code null}, the return value
1244      * is 0.
1245      *
1246      * @param array
1247      *            the array whose hash code to compute.
1248      * @return the hash code for {@code array}.
1249      */
hashCode(Object[] array)1250     public static int hashCode(Object[] array) {
1251         if (array == null) {
1252             return 0;
1253         }
1254         int hashCode = 1;
1255         for (Object element : array) {
1256             int elementHashCode;
1257 
1258             if (element == null) {
1259                 elementHashCode = 0;
1260             } else {
1261                 elementHashCode = (element).hashCode();
1262             }
1263             hashCode = 31 * hashCode + elementHashCode;
1264         }
1265         return hashCode;
1266     }
1267 
1268     /**
1269      * Returns a hash code based on the "deep contents" of the given array. If
1270      * the array contains other arrays as its elements, the hash code is based
1271      * on their contents not their identities. So it is not acceptable to invoke
1272      * this method on an array that contains itself as an element, either
1273      * directly or indirectly.
1274      * <p>
1275      * For any two arrays {@code a} and {@code b}, if
1276      * {@code Arrays.deepEquals(a, b)} returns {@code true}, it
1277      * means that the return value of {@code Arrays.deepHashCode(a)} equals
1278      * {@code Arrays.deepHashCode(b)}.
1279      * <p>
1280      * The computation of the value returned by this method is similar to that
1281      * of the value returned by {@link List#hashCode()} invoked on a
1282      * {@link List} containing a sequence of instances representing the
1283      * elements of array in the same order. The difference is: If an element e
1284      * of array is itself an array, its hash code is computed by calling the
1285      * appropriate overloading of {@code Arrays.hashCode(e)} if e is an array of a
1286      * primitive type, or by calling {@code Arrays.deepHashCode(e)} recursively if e is
1287      * an array of a reference type. The value returned by this method is the
1288      * same value as the method {@code Arrays.asList(array).hashCode()}. If the array is
1289      * {@code null}, the return value is 0.
1290      *
1291      * @param array
1292      *            the array whose hash code to compute.
1293      * @return the hash code for {@code array}.
1294      */
deepHashCode(Object[] array)1295     public static int deepHashCode(Object[] array) {
1296         if (array == null) {
1297             return 0;
1298         }
1299         int hashCode = 1;
1300         for (Object element : array) {
1301             int elementHashCode = deepHashCodeElement(element);
1302             hashCode = 31 * hashCode + elementHashCode;
1303         }
1304         return hashCode;
1305     }
1306 
deepHashCodeElement(Object element)1307     private static int deepHashCodeElement(Object element) {
1308         Class<?> cl;
1309         if (element == null) {
1310             return 0;
1311         }
1312 
1313         cl = element.getClass().getComponentType();
1314 
1315         if (cl == null) {
1316             return element.hashCode();
1317         }
1318 
1319         /*
1320          * element is an array
1321          */
1322         if (!cl.isPrimitive()) {
1323             return deepHashCode((Object[]) element);
1324         }
1325         if (cl.equals(int.class)) {
1326             return hashCode((int[]) element);
1327         }
1328         if (cl.equals(char.class)) {
1329             return hashCode((char[]) element);
1330         }
1331         if (cl.equals(boolean.class)) {
1332             return hashCode((boolean[]) element);
1333         }
1334         if (cl.equals(byte.class)) {
1335             return hashCode((byte[]) element);
1336         }
1337         if (cl.equals(long.class)) {
1338             return hashCode((long[]) element);
1339         }
1340         if (cl.equals(float.class)) {
1341             return hashCode((float[]) element);
1342         }
1343         if (cl.equals(double.class)) {
1344             return hashCode((double[]) element);
1345         }
1346         return hashCode((short[]) element);
1347     }
1348 
1349     /**
1350      * Compares the two arrays.
1351      *
1352      * @param array1
1353      *            the first {@code byte} array.
1354      * @param array2
1355      *            the second {@code byte} array.
1356      * @return {@code true} if both arrays are {@code null} or if the arrays have the
1357      *         same length and the elements at each index in the two arrays are
1358      *         equal, {@code false} otherwise.
1359      */
equals(byte[] array1, byte[] array2)1360     public static boolean equals(byte[] array1, byte[] array2) {
1361         if (array1 == array2) {
1362             return true;
1363         }
1364         if (array1 == null || array2 == null || array1.length != array2.length) {
1365             return false;
1366         }
1367         for (int i = 0; i < array1.length; i++) {
1368             if (array1[i] != array2[i]) {
1369                 return false;
1370             }
1371         }
1372         return true;
1373     }
1374 
1375     /**
1376      * Compares the two arrays.
1377      *
1378      * @param array1
1379      *            the first {@code short} array.
1380      * @param array2
1381      *            the second {@code short} array.
1382      * @return {@code true} if both arrays are {@code null} or if the arrays have the
1383      *         same length and the elements at each index in the two arrays are
1384      *         equal, {@code false} otherwise.
1385      */
equals(short[] array1, short[] array2)1386     public static boolean equals(short[] array1, short[] array2) {
1387         if (array1 == array2) {
1388             return true;
1389         }
1390         if (array1 == null || array2 == null || array1.length != array2.length) {
1391             return false;
1392         }
1393         for (int i = 0; i < array1.length; i++) {
1394             if (array1[i] != array2[i]) {
1395                 return false;
1396             }
1397         }
1398         return true;
1399     }
1400 
1401     /**
1402      * Compares the two arrays.
1403      *
1404      * @param array1
1405      *            the first {@code char} array.
1406      * @param array2
1407      *            the second {@code char} array.
1408      * @return {@code true} if both arrays are {@code null} or if the arrays have the
1409      *         same length and the elements at each index in the two arrays are
1410      *         equal, {@code false} otherwise.
1411      */
equals(char[] array1, char[] array2)1412     public static boolean equals(char[] array1, char[] array2) {
1413         if (array1 == array2) {
1414             return true;
1415         }
1416         if (array1 == null || array2 == null || array1.length != array2.length) {
1417             return false;
1418         }
1419         for (int i = 0; i < array1.length; i++) {
1420             if (array1[i] != array2[i]) {
1421                 return false;
1422             }
1423         }
1424         return true;
1425     }
1426 
1427     /**
1428      * Compares the two arrays.
1429      *
1430      * @param array1
1431      *            the first {@code int} array.
1432      * @param array2
1433      *            the second {@code int} array.
1434      * @return {@code true} if both arrays are {@code null} or if the arrays have the
1435      *         same length and the elements at each index in the two arrays are
1436      *         equal, {@code false} otherwise.
1437      */
equals(int[] array1, int[] array2)1438     public static boolean equals(int[] array1, int[] array2) {
1439         if (array1 == array2) {
1440             return true;
1441         }
1442         if (array1 == null || array2 == null || array1.length != array2.length) {
1443             return false;
1444         }
1445         for (int i = 0; i < array1.length; i++) {
1446             if (array1[i] != array2[i]) {
1447                 return false;
1448             }
1449         }
1450         return true;
1451     }
1452 
1453     /**
1454      * Compares the two arrays.
1455      *
1456      * @param array1
1457      *            the first {@code long} array.
1458      * @param array2
1459      *            the second {@code long} array.
1460      * @return {@code true} if both arrays are {@code null} or if the arrays have the
1461      *         same length and the elements at each index in the two arrays are
1462      *         equal, {@code false} otherwise.
1463      */
equals(long[] array1, long[] array2)1464     public static boolean equals(long[] array1, long[] array2) {
1465         if (array1 == array2) {
1466             return true;
1467         }
1468         if (array1 == null || array2 == null || array1.length != array2.length) {
1469             return false;
1470         }
1471         for (int i = 0; i < array1.length; i++) {
1472             if (array1[i] != array2[i]) {
1473                 return false;
1474             }
1475         }
1476         return true;
1477     }
1478 
1479     /**
1480      * Compares the two arrays. The values are compared in the same manner as
1481      * {@code Float.equals()}.
1482      *
1483      * @param array1
1484      *            the first {@code float} array.
1485      * @param array2
1486      *            the second {@code float} array.
1487      * @return {@code true} if both arrays are {@code null} or if the arrays have the
1488      *         same length and the elements at each index in the two arrays are
1489      *         equal, {@code false} otherwise.
1490      * @see Float#equals(Object)
1491      */
equals(float[] array1, float[] array2)1492     public static boolean equals(float[] array1, float[] array2) {
1493         if (array1 == array2) {
1494             return true;
1495         }
1496         if (array1 == null || array2 == null || array1.length != array2.length) {
1497             return false;
1498         }
1499         for (int i = 0; i < array1.length; i++) {
1500             if (Float.floatToIntBits(array1[i]) != Float
1501                     .floatToIntBits(array2[i])) {
1502                 return false;
1503             }
1504         }
1505         return true;
1506     }
1507 
1508     /**
1509      * Compares the two arrays. The values are compared in the same manner as
1510      * {@code Double.equals()}.
1511      *
1512      * @param array1
1513      *            the first {@code double} array.
1514      * @param array2
1515      *            the second {@code double} array.
1516      * @return {@code true} if both arrays are {@code null} or if the arrays have the
1517      *         same length and the elements at each index in the two arrays are
1518      *         equal, {@code false} otherwise.
1519      * @see Double#equals(Object)
1520      */
equals(double[] array1, double[] array2)1521     public static boolean equals(double[] array1, double[] array2) {
1522         if (array1 == array2) {
1523             return true;
1524         }
1525         if (array1 == null || array2 == null || array1.length != array2.length) {
1526             return false;
1527         }
1528         for (int i = 0; i < array1.length; i++) {
1529             if (Double.doubleToLongBits(array1[i]) != Double
1530                     .doubleToLongBits(array2[i])) {
1531                 return false;
1532             }
1533         }
1534         return true;
1535     }
1536 
1537     /**
1538      * Compares the two arrays.
1539      *
1540      * @param array1
1541      *            the first {@code boolean} array.
1542      * @param array2
1543      *            the second {@code boolean} array.
1544      * @return {@code true} if both arrays are {@code null} or if the arrays have the
1545      *         same length and the elements at each index in the two arrays are
1546      *         equal, {@code false} otherwise.
1547      */
equals(boolean[] array1, boolean[] array2)1548     public static boolean equals(boolean[] array1, boolean[] array2) {
1549         if (array1 == array2) {
1550             return true;
1551         }
1552         if (array1 == null || array2 == null || array1.length != array2.length) {
1553             return false;
1554         }
1555         for (int i = 0; i < array1.length; i++) {
1556             if (array1[i] != array2[i]) {
1557                 return false;
1558             }
1559         }
1560         return true;
1561     }
1562 
1563     /**
1564      * Compares the two arrays.
1565      *
1566      * @param array1
1567      *            the first {@code Object} array.
1568      * @param array2
1569      *            the second {@code Object} array.
1570      * @return {@code true} if both arrays are {@code null} or if the arrays have the
1571      *         same length and the elements at each index in the two arrays are
1572      *         equal according to {@code equals()}, {@code false} otherwise.
1573      */
equals(Object[] array1, Object[] array2)1574     public static boolean equals(Object[] array1, Object[] array2) {
1575         if (array1 == array2) {
1576             return true;
1577         }
1578         if (array1 == null || array2 == null || array1.length != array2.length) {
1579             return false;
1580         }
1581         for (int i = 0; i < array1.length; i++) {
1582             Object e1 = array1[i], e2 = array2[i];
1583             if (!(e1 == null ? e2 == null : e1.equals(e2))) {
1584                 return false;
1585             }
1586         }
1587         return true;
1588     }
1589 
1590     /**
1591      * Returns {@code true} if the two given arrays are deeply equal to one another.
1592      * Unlike the method {@code equals(Object[] array1, Object[] array2)}, this method
1593      * is appropriate for use for nested arrays of arbitrary depth.
1594      * <p>
1595      * Two array references are considered deeply equal if they are both {@code null},
1596      * or if they refer to arrays that have the same length and the elements at
1597      * each index in the two arrays are equal.
1598      * <p>
1599      * Two {@code null} elements {@code element1} and {@code element2} are possibly deeply equal if any
1600      * of the following conditions satisfied:
1601      * <p>
1602      * {@code element1} and {@code element2} are both arrays of object reference types, and
1603      * {@code Arrays.deepEquals(element1, element2)} would return {@code true}.
1604      * <p>
1605      * {@code element1} and {@code element2} are arrays of the same primitive type, and the
1606      * appropriate overloading of {@code Arrays.equals(element1, element2)} would return
1607      * {@code true}.
1608      * <p>
1609      * {@code element1 == element2}
1610      * <p>
1611      * {@code element1.equals(element2)} would return {@code true}.
1612      * <p>
1613      * Note that this definition permits {@code null} elements at any depth.
1614      * <p>
1615      * If either of the given arrays contain themselves as elements, the
1616      * behavior of this method is uncertain.
1617      *
1618      * @param array1
1619      *            the first {@code Object} array.
1620      * @param array2
1621      *            the second {@code Object} array.
1622      * @return {@code true} if both arrays are {@code null} or if the arrays have the
1623      *         same length and the elements at each index in the two arrays are
1624      *         equal according to {@code equals()}, {@code false} otherwise.
1625      */
deepEquals(Object[] array1, Object[] array2)1626     public static boolean deepEquals(Object[] array1, Object[] array2) {
1627         if (array1 == array2) {
1628             return true;
1629         }
1630         if (array1 == null || array2 == null || array1.length != array2.length) {
1631             return false;
1632         }
1633         for (int i = 0; i < array1.length; i++) {
1634             Object e1 = array1[i], e2 = array2[i];
1635 
1636             if (!deepEqualsElements(e1, e2)) {
1637                 return false;
1638             }
1639         }
1640         return true;
1641     }
1642 
deepEqualsElements(Object e1, Object e2)1643     private static boolean deepEqualsElements(Object e1, Object e2) {
1644         Class<?> cl1, cl2;
1645 
1646         if (e1 == e2) {
1647             return true;
1648         }
1649 
1650         if (e1 == null || e2 == null) {
1651             return false;
1652         }
1653 
1654         cl1 = e1.getClass().getComponentType();
1655         cl2 = e2.getClass().getComponentType();
1656 
1657         if (cl1 != cl2) {
1658             return false;
1659         }
1660 
1661         if (cl1 == null) {
1662             return e1.equals(e2);
1663         }
1664 
1665         /*
1666          * compare as arrays
1667          */
1668         if (!cl1.isPrimitive()) {
1669             return deepEquals((Object[]) e1, (Object[]) e2);
1670         }
1671 
1672         if (cl1.equals(int.class)) {
1673             return equals((int[]) e1, (int[]) e2);
1674         }
1675         if (cl1.equals(char.class)) {
1676             return equals((char[]) e1, (char[]) e2);
1677         }
1678         if (cl1.equals(boolean.class)) {
1679             return equals((boolean[]) e1, (boolean[]) e2);
1680         }
1681         if (cl1.equals(byte.class)) {
1682             return equals((byte[]) e1, (byte[]) e2);
1683         }
1684         if (cl1.equals(long.class)) {
1685             return equals((long[]) e1, (long[]) e2);
1686         }
1687         if (cl1.equals(float.class)) {
1688             return equals((float[]) e1, (float[]) e2);
1689         }
1690         if (cl1.equals(double.class)) {
1691             return equals((double[]) e1, (double[]) e2);
1692         }
1693         return equals((short[]) e1, (short[]) e2);
1694     }
1695 
1696     /**
1697      * Sorts the specified array in ascending numerical order.
1698      *
1699      * @param array
1700      *            the {@code byte} array to be sorted.
1701      */
sort(byte[] array)1702     public static void sort(byte[] array) {
1703         DualPivotQuicksort.sort(array);
1704     }
1705 
1706     /**
1707      * Sorts the specified range in the array in ascending numerical order.
1708      *
1709      * @param array
1710      *            the {@code byte} array to be sorted.
1711      * @param start
1712      *            the start index to sort.
1713      * @param end
1714      *            the last + 1 index to sort.
1715      * @throws IllegalArgumentException
1716      *                if {@code start > end}.
1717      * @throws ArrayIndexOutOfBoundsException
1718      *                if {@code start < 0} or {@code end > array.length}.
1719      */
sort(byte[] array, int start, int end)1720     public static void sort(byte[] array, int start, int end) {
1721         DualPivotQuicksort.sort(array, start, end);
1722     }
1723 
1724     /**
1725      * Checks that the range described by {@code offset} and {@code count} doesn't exceed
1726      * {@code arrayLength}.
1727      *
1728      * @hide
1729      */
checkOffsetAndCount(int arrayLength, int offset, int count)1730     public static void checkOffsetAndCount(int arrayLength, int offset, int count) {
1731         if ((offset | count) < 0 || offset > arrayLength || arrayLength - offset < count) {
1732             throw new ArrayIndexOutOfBoundsException(arrayLength, offset,
1733                     count);
1734         }
1735     }
1736 
1737     /**
1738      * Checks that the range described by {@code start} and {@code end} doesn't exceed
1739      * {@code len}.
1740      *
1741      * @hide
1742      */
checkStartAndEnd(int len, int start, int end)1743     public static void checkStartAndEnd(int len, int start, int end) {
1744         if (start < 0 || end > len) {
1745             throw new ArrayIndexOutOfBoundsException("start < 0 || end > len."
1746                     + " start=" + start + ", end=" + end + ", len=" + len);
1747         }
1748         if (start > end) {
1749             throw new IllegalArgumentException("start > end: " + start + " > " + end);
1750         }
1751     }
1752 
1753     /**
1754      * Sorts the specified array in ascending numerical order.
1755      *
1756      * @param array
1757      *            the {@code char} array to be sorted.
1758      */
sort(char[] array)1759     public static void sort(char[] array) {
1760         DualPivotQuicksort.sort(array);
1761     }
1762 
1763     /**
1764      * Sorts the specified range in the array in ascending numerical order.
1765      *
1766      * @param array
1767      *            the {@code char} array to be sorted.
1768      * @param start
1769      *            the start index to sort.
1770      * @param end
1771      *            the last + 1 index to sort.
1772      * @throws IllegalArgumentException
1773      *                if {@code start > end}.
1774      * @throws ArrayIndexOutOfBoundsException
1775      *                if {@code start < 0} or {@code end > array.length}.
1776      */
sort(char[] array, int start, int end)1777     public static void sort(char[] array, int start, int end) {
1778         DualPivotQuicksort.sort(array, start, end);
1779     }
1780 
1781     /**
1782      * Sorts the specified array in ascending numerical order.
1783      *
1784      * @param array
1785      *            the {@code double} array to be sorted.
1786      * @see #sort(double[], int, int)
1787      */
sort(double[] array)1788     public static void sort(double[] array) {
1789         DualPivotQuicksort.sort(array);
1790     }
1791 
1792     /**
1793      * Sorts the specified range in the array in ascending numerical order. The
1794      * values are sorted according to the order imposed by {@code Double.compareTo()}.
1795      *
1796      * @param array
1797      *            the {@code double} array to be sorted.
1798      * @param start
1799      *            the start index to sort.
1800      * @param end
1801      *            the last + 1 index to sort.
1802      * @throws IllegalArgumentException
1803      *                if {@code start > end}.
1804      * @throws ArrayIndexOutOfBoundsException
1805      *                if {@code start < 0} or {@code end > array.length}.
1806      * @see Double#compareTo(Double)
1807      */
sort(double[] array, int start, int end)1808     public static void sort(double[] array, int start, int end) {
1809         DualPivotQuicksort.sort(array, start, end);
1810     }
1811 
1812     /**
1813      * Sorts the specified array in ascending numerical order.
1814      *
1815      * @param array
1816      *            the {@code float} array to be sorted.
1817      * @see #sort(float[], int, int)
1818      */
sort(float[] array)1819     public static void sort(float[] array) {
1820         DualPivotQuicksort.sort(array);
1821     }
1822 
1823     /**
1824      * Sorts the specified range in the array in ascending numerical order. The
1825      * values are sorted according to the order imposed by {@code Float.compareTo()}.
1826      *
1827      * @param array
1828      *            the {@code float} array to be sorted.
1829      * @param start
1830      *            the start index to sort.
1831      * @param end
1832      *            the last + 1 index to sort.
1833      * @throws IllegalArgumentException
1834      *                if {@code start > end}.
1835      * @throws ArrayIndexOutOfBoundsException
1836      *                if {@code start < 0} or {@code end > array.length}.
1837      * @see Float#compareTo(Float)
1838      */
sort(float[] array, int start, int end)1839     public static void sort(float[] array, int start, int end) {
1840         DualPivotQuicksort.sort(array, start, end);
1841     }
1842 
1843     /**
1844      * Sorts the specified array in ascending numerical order.
1845      *
1846      * @param array
1847      *            the {@code int} array to be sorted.
1848      */
sort(int[] array)1849     public static void sort(int[] array) {
1850         DualPivotQuicksort.sort(array);
1851     }
1852 
1853     /**
1854      * Sorts the specified range in the array in ascending numerical order.
1855      *
1856      * @param array
1857      *            the {@code int} array to be sorted.
1858      * @param start
1859      *            the start index to sort.
1860      * @param end
1861      *            the last + 1 index to sort.
1862      * @throws IllegalArgumentException
1863      *                if {@code start > end}.
1864      * @throws ArrayIndexOutOfBoundsException
1865      *                if {@code start < 0} or {@code end > array.length}.
1866      */
sort(int[] array, int start, int end)1867     public static void sort(int[] array, int start, int end) {
1868         DualPivotQuicksort.sort(array, start, end);
1869     }
1870 
1871     /**
1872      * Sorts the specified array in ascending numerical order.
1873      *
1874      * @param array
1875      *            the {@code long} array to be sorted.
1876      */
sort(long[] array)1877     public static void sort(long[] array) {
1878         DualPivotQuicksort.sort(array);
1879     }
1880 
1881     /**
1882      * Sorts the specified range in the array in ascending numerical order.
1883      *
1884      * @param array
1885      *            the {@code long} array to be sorted.
1886      * @param start
1887      *            the start index to sort.
1888      * @param end
1889      *            the last + 1 index to sort.
1890      * @throws IllegalArgumentException
1891      *                if {@code start > end}.
1892      * @throws ArrayIndexOutOfBoundsException
1893      *                if {@code start < 0} or {@code end > array.length}.
1894      */
sort(long[] array, int start, int end)1895     public static void sort(long[] array, int start, int end) {
1896         DualPivotQuicksort.sort(array, start, end);
1897     }
1898 
1899     /**
1900      * Sorts the specified array in ascending numerical order.
1901      *
1902      * @param array
1903      *            the {@code short} array to be sorted.
1904      */
sort(short[] array)1905     public static void sort(short[] array) {
1906         DualPivotQuicksort.sort(array);
1907     }
1908 
1909     /**
1910      * Sorts the specified range in the array in ascending numerical order.
1911      *
1912      * @param array
1913      *            the {@code short} array to be sorted.
1914      * @param start
1915      *            the start index to sort.
1916      * @param end
1917      *            the last + 1 index to sort.
1918      * @throws IllegalArgumentException
1919      *                if {@code start > end}.
1920      * @throws ArrayIndexOutOfBoundsException
1921      *                if {@code start < 0} or {@code end > array.length}.
1922      */
sort(short[] array, int start, int end)1923     public static void sort(short[] array, int start, int end) {
1924         DualPivotQuicksort.sort(array, start, end);
1925     }
1926 
1927 // BEGIN android-note
1928 
1929     /*
1930      * <p>If this platform has an optimizing VM, check whether ComparableTimSort
1931      * offers any performance benefit over TimSort in conjunction with a
1932      * comparator that returns:
1933      *    {@code ((Comparable)first).compareTo(Second)}.
1934      * If not, you are better off deleting ComparableTimSort to eliminate the
1935      * code duplication.  In other words, the commented out code below
1936      * is the preferable implementation for sorting arrays of Comparables if it
1937      * offers sufficient performance.
1938      */
1939 
1940 //    /**
1941 //     * A comparator that implements the natural order of a group of
1942 //     * mutually comparable elements.  Using this comparator saves us
1943 //     * from duplicating most of the code in this file (one version for
1944 //     * Comparables, one for explicit comparators).
1945 //     */
1946 //    private static final Comparator<Object> NATURAL_ORDER = new Comparator<Object>() {
1947 //        @SuppressWarnings("unchecked")
1948 //        public int compare(Object first, Object second) {
1949 //            return ((Comparable<Object>)first).compareTo(second);
1950 //        }
1951 //    };
1952 //
1953 //    public static void sort(Object[] a) {
1954 //        sort(a, 0, a.length, NATURAL_ORDER);
1955 //    }
1956 //
1957 //    public static void sort(Object[] a, int fromIndex, int toIndex) {
1958 //        sort(a, fromIndex, toIndex, NATURAL_ORDER);
1959 //    }
1960 
1961 // END android-note
1962 
1963     /**
1964      * Sorts the specified array in ascending natural order.
1965      *
1966      * @throws ClassCastException if any element does not implement {@code Comparable},
1967      *     or if {@code compareTo} throws for any pair of elements.
1968      */
sort(Object[] array)1969     public static void sort(Object[] array) {
1970         ComparableTimSort.sort(array);
1971     }
1972 
1973     /**
1974      * Sorts the specified range in the array in ascending natural order.
1975      *
1976      * @param start
1977      *            the start index to sort.
1978      * @param end
1979      *            the last + 1 index to sort.
1980      * @throws ClassCastException if any element does not implement {@code Comparable},
1981      *     or if {@code compareTo} throws for any pair of elements.
1982      * @throws IllegalArgumentException
1983      *                if {@code start > end}.
1984      * @throws ArrayIndexOutOfBoundsException
1985      *                if {@code start < 0} or {@code end > array.length}.
1986      */
sort(Object[] array, int start, int end)1987     public static void sort(Object[] array, int start, int end) {
1988         ComparableTimSort.sort(array, start, end);
1989     }
1990 
1991     /**
1992      * Sorts the specified range in the array using the specified {@code Comparator}.
1993      * All elements must be comparable to each other without a
1994      * {@code ClassCastException} being thrown.
1995      *
1996      * @param start
1997      *            the start index to sort.
1998      * @param end
1999      *            the last + 1 index to sort.
2000      * @param comparator
2001      *            the {@code Comparator}.
2002      * @throws ClassCastException
2003      *                if elements in the array cannot be compared to each other
2004      *                using the given {@code Comparator}.
2005      * @throws IllegalArgumentException
2006      *                if {@code start > end}.
2007      * @throws ArrayIndexOutOfBoundsException
2008      *                if {@code start < 0} or {@code end > array.length}.
2009      */
sort(T[] array, int start, int end, Comparator<? super T> comparator)2010     public static <T> void sort(T[] array, int start, int end, Comparator<? super T> comparator) {
2011         TimSort.sort(array, start, end, comparator);
2012     }
2013 
2014     /**
2015      * Sorts the specified array using the specified {@code Comparator}. All elements
2016      * must be comparable to each other without a {@code ClassCastException} being thrown.
2017      *
2018      * @throws ClassCastException
2019      *                if elements in the array cannot be compared to each other
2020      *                using the {@code Comparator}.
2021      */
sort(T[] array, Comparator<? super T> comparator)2022     public static <T> void sort(T[] array, Comparator<? super T> comparator) {
2023         TimSort.sort(array, comparator);
2024     }
2025 
2026     /**
2027      * Creates a {@code String} representation of the {@code boolean[]} passed.
2028      * The result is surrounded by brackets ({@code "[]"}), each
2029      * element is converted to a {@code String} via the
2030      * {@link String#valueOf(boolean)} and separated by {@code ", "}.
2031      * If the array is {@code null}, then {@code "null"} is returned.
2032      *
2033      * @param array
2034      *            the {@code boolean} array to convert.
2035      * @return the {@code String} representation of {@code array}.
2036      * @since 1.5
2037      */
toString(boolean[] array)2038     public static String toString(boolean[] array) {
2039         if (array == null) {
2040             return "null";
2041         }
2042         if (array.length == 0) {
2043             return "[]";
2044         }
2045         StringBuilder sb = new StringBuilder(array.length * 7);
2046         sb.append('[');
2047         sb.append(array[0]);
2048         for (int i = 1; i < array.length; i++) {
2049             sb.append(", ");
2050             sb.append(array[i]);
2051         }
2052         sb.append(']');
2053         return sb.toString();
2054     }
2055 
2056     /**
2057      * Creates a {@code String} representation of the {@code byte[]} passed. The
2058      * result is surrounded by brackets ({@code "[]"}), each element
2059      * is converted to a {@code String} via the {@link String#valueOf(int)} and
2060      * separated by {@code ", "}. If the array is {@code null}, then
2061      * {@code "null"} is returned.
2062      *
2063      * @param array
2064      *            the {@code byte} array to convert.
2065      * @return the {@code String} representation of {@code array}.
2066      * @since 1.5
2067      */
toString(byte[] array)2068     public static String toString(byte[] array) {
2069         if (array == null) {
2070             return "null";
2071         }
2072         if (array.length == 0) {
2073             return "[]";
2074         }
2075         StringBuilder sb = new StringBuilder(array.length * 6);
2076         sb.append('[');
2077         sb.append(array[0]);
2078         for (int i = 1; i < array.length; i++) {
2079             sb.append(", ");
2080             sb.append(array[i]);
2081         }
2082         sb.append(']');
2083         return sb.toString();
2084     }
2085 
2086     /**
2087      * Creates a {@code String} representation of the {@code char[]} passed. The
2088      * result is surrounded by brackets ({@code "[]"}), each element
2089      * is converted to a {@code String} via the {@link String#valueOf(char)} and
2090      * separated by {@code ", "}. If the array is {@code null}, then
2091      * {@code "null"} is returned.
2092      *
2093      * @param array
2094      *            the {@code char} array to convert.
2095      * @return the {@code String} representation of {@code array}.
2096      * @since 1.5
2097      */
toString(char[] array)2098     public static String toString(char[] array) {
2099         if (array == null) {
2100             return "null";
2101         }
2102         if (array.length == 0) {
2103             return "[]";
2104         }
2105         StringBuilder sb = new StringBuilder(array.length * 3);
2106         sb.append('[');
2107         sb.append(array[0]);
2108         for (int i = 1; i < array.length; i++) {
2109             sb.append(", ");
2110             sb.append(array[i]);
2111         }
2112         sb.append(']');
2113         return sb.toString();
2114     }
2115 
2116     /**
2117      * Creates a {@code String} representation of the {@code double[]} passed.
2118      * The result is surrounded by brackets ({@code "[]"}), each
2119      * element is converted to a {@code String} via the
2120      * {@link String#valueOf(double)} and separated by {@code ", "}.
2121      * If the array is {@code null}, then {@code "null"} is returned.
2122      *
2123      * @param array
2124      *            the {@code double} array to convert.
2125      * @return the {@code String} representation of {@code array}.
2126      * @since 1.5
2127      */
toString(double[] array)2128     public static String toString(double[] array) {
2129         if (array == null) {
2130             return "null";
2131         }
2132         if (array.length == 0) {
2133             return "[]";
2134         }
2135         StringBuilder sb = new StringBuilder(array.length * 7);
2136         sb.append('[');
2137         sb.append(array[0]);
2138         for (int i = 1; i < array.length; i++) {
2139             sb.append(", ");
2140             sb.append(array[i]);
2141         }
2142         sb.append(']');
2143         return sb.toString();
2144     }
2145 
2146     /**
2147      * Creates a {@code String} representation of the {@code float[]} passed.
2148      * The result is surrounded by brackets ({@code "[]"}), each
2149      * element is converted to a {@code String} via the
2150      * {@link String#valueOf(float)} and separated by {@code ", "}.
2151      * If the array is {@code null}, then {@code "null"} is returned.
2152      *
2153      * @param array
2154      *            the {@code float} array to convert.
2155      * @return the {@code String} representation of {@code array}.
2156      * @since 1.5
2157      */
toString(float[] array)2158     public static String toString(float[] array) {
2159         if (array == null) {
2160             return "null";
2161         }
2162         if (array.length == 0) {
2163             return "[]";
2164         }
2165         StringBuilder sb = new StringBuilder(array.length * 7);
2166         sb.append('[');
2167         sb.append(array[0]);
2168         for (int i = 1; i < array.length; i++) {
2169             sb.append(", ");
2170             sb.append(array[i]);
2171         }
2172         sb.append(']');
2173         return sb.toString();
2174     }
2175 
2176     /**
2177      * Creates a {@code String} representation of the {@code int[]} passed. The
2178      * result is surrounded by brackets ({@code "[]"}), each element
2179      * is converted to a {@code String} via the {@link String#valueOf(int)} and
2180      * separated by {@code ", "}. If the array is {@code null}, then
2181      * {@code "null"} is returned.
2182      *
2183      * @param array
2184      *            the {@code int} array to convert.
2185      * @return the {@code String} representation of {@code array}.
2186      * @since 1.5
2187      */
toString(int[] array)2188     public static String toString(int[] array) {
2189         if (array == null) {
2190             return "null";
2191         }
2192         if (array.length == 0) {
2193             return "[]";
2194         }
2195         StringBuilder sb = new StringBuilder(array.length * 6);
2196         sb.append('[');
2197         sb.append(array[0]);
2198         for (int i = 1; i < array.length; i++) {
2199             sb.append(", ");
2200             sb.append(array[i]);
2201         }
2202         sb.append(']');
2203         return sb.toString();
2204     }
2205 
2206     /**
2207      * Creates a {@code String} representation of the {@code long[]} passed. The
2208      * result is surrounded by brackets ({@code "[]"}), each element
2209      * is converted to a {@code String} via the {@link String#valueOf(long)} and
2210      * separated by {@code ", "}. If the array is {@code null}, then
2211      * {@code "null"} is returned.
2212      *
2213      * @param array
2214      *            the {@code long} array to convert.
2215      * @return the {@code String} representation of {@code array}.
2216      * @since 1.5
2217      */
toString(long[] array)2218     public static String toString(long[] array) {
2219         if (array == null) {
2220             return "null";
2221         }
2222         if (array.length == 0) {
2223             return "[]";
2224         }
2225         StringBuilder sb = new StringBuilder(array.length * 6);
2226         sb.append('[');
2227         sb.append(array[0]);
2228         for (int i = 1; i < array.length; i++) {
2229             sb.append(", ");
2230             sb.append(array[i]);
2231         }
2232         sb.append(']');
2233         return sb.toString();
2234     }
2235 
2236     /**
2237      * Creates a {@code String} representation of the {@code short[]} passed.
2238      * The result is surrounded by brackets ({@code "[]"}), each
2239      * element is converted to a {@code String} via the
2240      * {@link String#valueOf(int)} and separated by {@code ", "}. If
2241      * the array is {@code null}, then {@code "null"} is returned.
2242      *
2243      * @param array
2244      *            the {@code short} array to convert.
2245      * @return the {@code String} representation of {@code array}.
2246      * @since 1.5
2247      */
toString(short[] array)2248     public static String toString(short[] array) {
2249         if (array == null) {
2250             return "null";
2251         }
2252         if (array.length == 0) {
2253             return "[]";
2254         }
2255         StringBuilder sb = new StringBuilder(array.length * 6);
2256         sb.append('[');
2257         sb.append(array[0]);
2258         for (int i = 1; i < array.length; i++) {
2259             sb.append(", ");
2260             sb.append(array[i]);
2261         }
2262         sb.append(']');
2263         return sb.toString();
2264     }
2265 
2266     /**
2267      * Creates a {@code String} representation of the {@code Object[]} passed.
2268      * The result is surrounded by brackets ({@code "[]"}), each
2269      * element is converted to a {@code String} via the
2270      * {@link String#valueOf(Object)} and separated by {@code ", "}.
2271      * If the array is {@code null}, then {@code "null"} is returned.
2272      *
2273      * @param array
2274      *            the {@code Object} array to convert.
2275      * @return the {@code String} representation of {@code array}.
2276      * @since 1.5
2277      */
toString(Object[] array)2278     public static String toString(Object[] array) {
2279         if (array == null) {
2280             return "null";
2281         }
2282         if (array.length == 0) {
2283             return "[]";
2284         }
2285         StringBuilder sb = new StringBuilder(array.length * 7);
2286         sb.append('[');
2287         sb.append(array[0]);
2288         for (int i = 1; i < array.length; i++) {
2289             sb.append(", ");
2290             sb.append(array[i]);
2291         }
2292         sb.append(']');
2293         return sb.toString();
2294     }
2295 
2296     /**
2297      * Creates a <i>"deep"</i> {@code String} representation of the
2298      * {@code Object[]} passed, such that if the array contains other arrays,
2299      * the {@code String} representation of those arrays is generated as well.
2300      * <p>
2301      * If any of the elements are primitive arrays, the generation is delegated
2302      * to the other {@code toString} methods in this class. If any element
2303      * contains a reference to the original array, then it will be represented
2304      * as {@code "[...]"}. If an element is an {@code Object[]}, then its
2305      * representation is generated by a recursive call to this method. All other
2306      * elements are converted via the {@link String#valueOf(Object)} method.
2307      *
2308      * @param array
2309      *            the {@code Object} array to convert.
2310      * @return the {@code String} representation of {@code array}.
2311      * @since 1.5
2312      */
deepToString(Object[] array)2313     public static String deepToString(Object[] array) {
2314         // Special case null to prevent NPE
2315         if (array == null) {
2316             return "null";
2317         }
2318         // delegate this to the recursive method
2319         StringBuilder buf = new StringBuilder(array.length * 9);
2320         deepToStringImpl(array, new Object[] { array }, buf);
2321         return buf.toString();
2322     }
2323 
2324     /**
2325      * Implementation method used by {@link #deepToString(Object[])}.
2326      *
2327      * @param array
2328      *            the {@code Object[]} to dive into.
2329      * @param origArrays
2330      *            the original {@code Object[]}; used to test for self
2331      *            references.
2332      * @param sb
2333      *            the {@code StringBuilder} instance to append to or
2334      *            {@code null} one hasn't been created yet.
2335      * @return the result.
2336      * @see #deepToString(Object[])
2337      */
deepToStringImpl(Object[] array, Object[] origArrays, StringBuilder sb)2338     private static void deepToStringImpl(Object[] array, Object[] origArrays,
2339             StringBuilder sb) {
2340         if (array == null) {
2341             sb.append("null");
2342             return;
2343         }
2344 
2345         sb.append('[');
2346 
2347         for (int i = 0; i < array.length; i++) {
2348             if (i != 0) {
2349                 sb.append(", ");
2350             }
2351             // establish current element
2352             Object elem = array[i];
2353             if (elem == null) {
2354                 // element is null
2355                 sb.append("null");
2356             } else {
2357                 // get the Class of the current element
2358                 Class<?> elemClass = elem.getClass();
2359                 if (elemClass.isArray()) {
2360                     // element is an array type
2361 
2362                     // get the declared Class of the array (element)
2363                     Class<?> elemElemClass = elemClass.getComponentType();
2364                     if (elemElemClass.isPrimitive()) {
2365                         // element is a primitive array
2366                         if (boolean.class.equals(elemElemClass)) {
2367                             sb.append(toString((boolean[]) elem));
2368                         } else if (byte.class.equals(elemElemClass)) {
2369                             sb.append(toString((byte[]) elem));
2370                         } else if (char.class.equals(elemElemClass)) {
2371                             sb.append(toString((char[]) elem));
2372                         } else if (double.class.equals(elemElemClass)) {
2373                             sb.append(toString((double[]) elem));
2374                         } else if (float.class.equals(elemElemClass)) {
2375                             sb.append(toString((float[]) elem));
2376                         } else if (int.class.equals(elemElemClass)) {
2377                             sb.append(toString((int[]) elem));
2378                         } else if (long.class.equals(elemElemClass)) {
2379                             sb.append(toString((long[]) elem));
2380                         } else if (short.class.equals(elemElemClass)) {
2381                             sb.append(toString((short[]) elem));
2382                         } else {
2383                             // no other possible primitives, so we assert that
2384                             throw new AssertionError();
2385                         }
2386                     } else {
2387                         // element is an Object[], so we assert that
2388                         // assert elem instanceof Object[];
2389                         if (deepToStringImplContains(origArrays, elem)) {
2390                             sb.append("[...]");
2391                         } else {
2392                             Object[] newArray = (Object[]) elem;
2393                             Object[] newOrigArrays = new Object[origArrays.length + 1];
2394                             System.arraycopy(origArrays, 0, newOrigArrays, 0,
2395                                     origArrays.length);
2396                             newOrigArrays[origArrays.length] = newArray;
2397                             // make the recursive call to this method
2398                             deepToStringImpl(newArray, newOrigArrays, sb);
2399                         }
2400                     }
2401                 } else { // element is NOT an array, just an Object
2402                     sb.append(array[i]);
2403                 }
2404             }
2405         }
2406         sb.append(']');
2407     }
2408 
2409     /**
2410      * Utility method used to assist the implementation of
2411      * {@link #deepToString(Object[])}.
2412      *
2413      * @param origArrays
2414      *            An array of Object[] references.
2415      * @param array
2416      *            An Object[] reference to look for in {@code origArrays}.
2417      * @return A value of {@code true} if {@code array} is an
2418      *         element in {@code origArrays}.
2419      */
deepToStringImplContains(Object[] origArrays, Object array)2420     private static boolean deepToStringImplContains(Object[] origArrays,
2421             Object array) {
2422         if (origArrays == null || origArrays.length == 0) {
2423             return false;
2424         }
2425         for (Object element : origArrays) {
2426             if (element == array) {
2427                 return true;
2428             }
2429         }
2430         return false;
2431     }
2432 
2433     /**
2434      * Copies {@code newLength} elements from {@code original} into a new array.
2435      * If {@code newLength} is greater than {@code original.length}, the result is padded
2436      * with the value {@code false}.
2437      *
2438      * @param original the original array
2439      * @param newLength the length of the new array
2440      * @return the new array
2441      * @throws NegativeArraySizeException if {@code newLength < 0}
2442      * @throws NullPointerException if {@code original == null}
2443      * @since 1.6
2444      */
copyOf(boolean[] original, int newLength)2445     public static boolean[] copyOf(boolean[] original, int newLength) {
2446         if (newLength < 0) {
2447             throw new NegativeArraySizeException(Integer.toString(newLength));
2448         }
2449         return copyOfRange(original, 0, newLength);
2450     }
2451 
2452     /**
2453      * Copies {@code newLength} elements from {@code original} into a new array.
2454      * If {@code newLength} is greater than {@code original.length}, the result is padded
2455      * with the value {@code (byte) 0}.
2456      *
2457      * @param original the original array
2458      * @param newLength the length of the new array
2459      * @return the new array
2460      * @throws NegativeArraySizeException if {@code newLength < 0}
2461      * @throws NullPointerException if {@code original == null}
2462      * @since 1.6
2463      */
copyOf(byte[] original, int newLength)2464     public static byte[] copyOf(byte[] original, int newLength) {
2465         if (newLength < 0) {
2466             throw new NegativeArraySizeException(Integer.toString(newLength));
2467         }
2468         return copyOfRange(original, 0, newLength);
2469     }
2470 
2471     /**
2472      * Copies {@code newLength} elements from {@code original} into a new array.
2473      * If {@code newLength} is greater than {@code original.length}, the result is padded
2474      * with the value {@code '\\u0000'}.
2475      *
2476      * @param original the original array
2477      * @param newLength the length of the new array
2478      * @return the new array
2479      * @throws NegativeArraySizeException if {@code newLength < 0}
2480      * @throws NullPointerException if {@code original == null}
2481      * @since 1.6
2482      */
copyOf(char[] original, int newLength)2483     public static char[] copyOf(char[] original, int newLength) {
2484         if (newLength < 0) {
2485             throw new NegativeArraySizeException(Integer.toString(newLength));
2486         }
2487         return copyOfRange(original, 0, newLength);
2488     }
2489 
2490     /**
2491      * Copies {@code newLength} elements from {@code original} into a new array.
2492      * If {@code newLength} is greater than {@code original.length}, the result is padded
2493      * with the value {@code 0.0d}.
2494      *
2495      * @param original the original array
2496      * @param newLength the length of the new array
2497      * @return the new array
2498      * @throws NegativeArraySizeException if {@code newLength < 0}
2499      * @throws NullPointerException if {@code original == null}
2500      * @since 1.6
2501      */
copyOf(double[] original, int newLength)2502     public static double[] copyOf(double[] original, int newLength) {
2503         if (newLength < 0) {
2504             throw new NegativeArraySizeException(Integer.toString(newLength));
2505         }
2506         return copyOfRange(original, 0, newLength);
2507     }
2508 
2509     /**
2510      * Copies {@code newLength} elements from {@code original} into a new array.
2511      * If {@code newLength} is greater than {@code original.length}, the result is padded
2512      * with the value {@code 0.0f}.
2513      *
2514      * @param original the original array
2515      * @param newLength the length of the new array
2516      * @return the new array
2517      * @throws NegativeArraySizeException if {@code newLength < 0}
2518      * @throws NullPointerException if {@code original == null}
2519      * @since 1.6
2520      */
copyOf(float[] original, int newLength)2521     public static float[] copyOf(float[] original, int newLength) {
2522         if (newLength < 0) {
2523             throw new NegativeArraySizeException(Integer.toString(newLength));
2524         }
2525         return copyOfRange(original, 0, newLength);
2526     }
2527 
2528     /**
2529      * Copies {@code newLength} elements from {@code original} into a new array.
2530      * If {@code newLength} is greater than {@code original.length}, the result is padded
2531      * with the value {@code 0}.
2532      *
2533      * @param original the original array
2534      * @param newLength the length of the new array
2535      * @return the new array
2536      * @throws NegativeArraySizeException if {@code newLength < 0}
2537      * @throws NullPointerException if {@code original == null}
2538      * @since 1.6
2539      */
copyOf(int[] original, int newLength)2540     public static int[] copyOf(int[] original, int newLength) {
2541         if (newLength < 0) {
2542             throw new NegativeArraySizeException(Integer.toString(newLength));
2543         }
2544         return copyOfRange(original, 0, newLength);
2545     }
2546 
2547     /**
2548      * Copies {@code newLength} elements from {@code original} into a new array.
2549      * If {@code newLength} is greater than {@code original.length}, the result is padded
2550      * with the value {@code 0L}.
2551      *
2552      * @param original the original array
2553      * @param newLength the length of the new array
2554      * @return the new array
2555      * @throws NegativeArraySizeException if {@code newLength < 0}
2556      * @throws NullPointerException if {@code original == null}
2557      * @since 1.6
2558      */
copyOf(long[] original, int newLength)2559     public static long[] copyOf(long[] original, int newLength) {
2560         if (newLength < 0) {
2561             throw new NegativeArraySizeException(Integer.toString(newLength));
2562         }
2563         return copyOfRange(original, 0, newLength);
2564     }
2565 
2566     /**
2567      * Copies {@code newLength} elements from {@code original} into a new array.
2568      * If {@code newLength} is greater than {@code original.length}, the result is padded
2569      * with the value {@code (short) 0}.
2570      *
2571      * @param original the original array
2572      * @param newLength the length of the new array
2573      * @return the new array
2574      * @throws NegativeArraySizeException if {@code newLength < 0}
2575      * @throws NullPointerException if {@code original == null}
2576      * @since 1.6
2577      */
copyOf(short[] original, int newLength)2578     public static short[] copyOf(short[] original, int newLength) {
2579         if (newLength < 0) {
2580             throw new NegativeArraySizeException(Integer.toString(newLength));
2581         }
2582         return copyOfRange(original, 0, newLength);
2583     }
2584 
2585     /**
2586      * Copies {@code newLength} elements from {@code original} into a new array.
2587      * If {@code newLength} is greater than {@code original.length}, the result is padded
2588      * with the value {@code null}.
2589      *
2590      * @param original the original array
2591      * @param newLength the length of the new array
2592      * @return the new array
2593      * @throws NegativeArraySizeException if {@code newLength < 0}
2594      * @throws NullPointerException if {@code original == null}
2595      * @since 1.6
2596      */
copyOf(T[] original, int newLength)2597     public static <T> T[] copyOf(T[] original, int newLength) {
2598         if (original == null) {
2599             throw new NullPointerException("original == null");
2600         }
2601         if (newLength < 0) {
2602             throw new NegativeArraySizeException(Integer.toString(newLength));
2603         }
2604         return copyOfRange(original, 0, newLength);
2605     }
2606 
2607     /**
2608      * Copies {@code newLength} elements from {@code original} into a new array.
2609      * If {@code newLength} is greater than {@code original.length}, the result is padded
2610      * with the value {@code null}.
2611      *
2612      * @param original the original array
2613      * @param newLength the length of the new array
2614      * @param newType the class of the new array
2615      * @return the new array
2616      * @throws NegativeArraySizeException if {@code newLength < 0}
2617      * @throws NullPointerException if {@code original == null}
2618      * @throws ArrayStoreException if a value in {@code original} is incompatible with T
2619      * @since 1.6
2620      */
copyOf(U[] original, int newLength, Class<? extends T[]> newType)2621     public static <T, U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
2622         // We use the null pointer check in copyOfRange for exception priority compatibility.
2623         if (newLength < 0) {
2624             throw new NegativeArraySizeException(Integer.toString(newLength));
2625         }
2626         return copyOfRange(original, 0, newLength, newType);
2627     }
2628 
2629     /**
2630      * Copies elements from {@code original} into a new array, from indexes start (inclusive) to
2631      * end (exclusive). The original order of elements is preserved.
2632      * If {@code end} is greater than {@code original.length}, the result is padded
2633      * with the value {@code false}.
2634      *
2635      * @param original the original array
2636      * @param start the start index, inclusive
2637      * @param end the end index, exclusive
2638      * @return the new array
2639      * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length}
2640      * @throws IllegalArgumentException if {@code start > end}
2641      * @throws NullPointerException if {@code original == null}
2642      * @since 1.6
2643      */
copyOfRange(boolean[] original, int start, int end)2644     public static boolean[] copyOfRange(boolean[] original, int start, int end) {
2645         if (start > end) {
2646             throw new IllegalArgumentException();
2647         }
2648         int originalLength = original.length;
2649         if (start < 0 || start > originalLength) {
2650             throw new ArrayIndexOutOfBoundsException();
2651         }
2652         int resultLength = end - start;
2653         int copyLength = Math.min(resultLength, originalLength - start);
2654         boolean[] result = new boolean[resultLength];
2655         System.arraycopy(original, start, result, 0, copyLength);
2656         return result;
2657     }
2658 
2659     /**
2660      * Copies elements from {@code original} into a new array, from indexes start (inclusive) to
2661      * end (exclusive). The original order of elements is preserved.
2662      * If {@code end} is greater than {@code original.length}, the result is padded
2663      * with the value {@code (byte) 0}.
2664      *
2665      * @param original the original array
2666      * @param start the start index, inclusive
2667      * @param end the end index, exclusive
2668      * @return the new array
2669      * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length}
2670      * @throws IllegalArgumentException if {@code start > end}
2671      * @throws NullPointerException if {@code original == null}
2672      * @since 1.6
2673      */
copyOfRange(byte[] original, int start, int end)2674     public static byte[] copyOfRange(byte[] original, int start, int end) {
2675         if (start > end) {
2676             throw new IllegalArgumentException();
2677         }
2678         int originalLength = original.length;
2679         if (start < 0 || start > originalLength) {
2680             throw new ArrayIndexOutOfBoundsException();
2681         }
2682         int resultLength = end - start;
2683         int copyLength = Math.min(resultLength, originalLength - start);
2684         byte[] result = new byte[resultLength];
2685         System.arraycopy(original, start, result, 0, copyLength);
2686         return result;
2687     }
2688 
2689     /**
2690      * Copies elements from {@code original} into a new array, from indexes start (inclusive) to
2691      * end (exclusive). The original order of elements is preserved.
2692      * If {@code end} is greater than {@code original.length}, the result is padded
2693      * with the value {@code '\\u0000'}.
2694      *
2695      * @param original the original array
2696      * @param start the start index, inclusive
2697      * @param end the end index, exclusive
2698      * @return the new array
2699      * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length}
2700      * @throws IllegalArgumentException if {@code start > end}
2701      * @throws NullPointerException if {@code original == null}
2702      * @since 1.6
2703      */
copyOfRange(char[] original, int start, int end)2704     public static char[] copyOfRange(char[] original, int start, int end) {
2705         if (start > end) {
2706             throw new IllegalArgumentException();
2707         }
2708         int originalLength = original.length;
2709         if (start < 0 || start > originalLength) {
2710             throw new ArrayIndexOutOfBoundsException();
2711         }
2712         int resultLength = end - start;
2713         int copyLength = Math.min(resultLength, originalLength - start);
2714         char[] result = new char[resultLength];
2715         System.arraycopy(original, start, result, 0, copyLength);
2716         return result;
2717     }
2718 
2719     /**
2720      * Copies elements from {@code original} into a new array, from indexes start (inclusive) to
2721      * end (exclusive). The original order of elements is preserved.
2722      * If {@code end} is greater than {@code original.length}, the result is padded
2723      * with the value {@code 0.0d}.
2724      *
2725      * @param original the original array
2726      * @param start the start index, inclusive
2727      * @param end the end index, exclusive
2728      * @return the new array
2729      * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length}
2730      * @throws IllegalArgumentException if {@code start > end}
2731      * @throws NullPointerException if {@code original == null}
2732      * @since 1.6
2733      */
copyOfRange(double[] original, int start, int end)2734     public static double[] copyOfRange(double[] original, int start, int end) {
2735         if (start > end) {
2736             throw new IllegalArgumentException();
2737         }
2738         int originalLength = original.length;
2739         if (start < 0 || start > originalLength) {
2740             throw new ArrayIndexOutOfBoundsException();
2741         }
2742         int resultLength = end - start;
2743         int copyLength = Math.min(resultLength, originalLength - start);
2744         double[] result = new double[resultLength];
2745         System.arraycopy(original, start, result, 0, copyLength);
2746         return result;
2747     }
2748 
2749     /**
2750      * Copies elements from {@code original} into a new array, from indexes start (inclusive) to
2751      * end (exclusive). The original order of elements is preserved.
2752      * If {@code end} is greater than {@code original.length}, the result is padded
2753      * with the value {@code 0.0f}.
2754      *
2755      * @param original the original array
2756      * @param start the start index, inclusive
2757      * @param end the end index, exclusive
2758      * @return the new array
2759      * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length}
2760      * @throws IllegalArgumentException if {@code start > end}
2761      * @throws NullPointerException if {@code original == null}
2762      * @since 1.6
2763      */
copyOfRange(float[] original, int start, int end)2764     public static float[] copyOfRange(float[] original, int start, int end) {
2765         if (start > end) {
2766             throw new IllegalArgumentException();
2767         }
2768         int originalLength = original.length;
2769         if (start < 0 || start > originalLength) {
2770             throw new ArrayIndexOutOfBoundsException();
2771         }
2772         int resultLength = end - start;
2773         int copyLength = Math.min(resultLength, originalLength - start);
2774         float[] result = new float[resultLength];
2775         System.arraycopy(original, start, result, 0, copyLength);
2776         return result;
2777     }
2778 
2779     /**
2780      * Copies elements from {@code original} into a new array, from indexes start (inclusive) to
2781      * end (exclusive). The original order of elements is preserved.
2782      * If {@code end} is greater than {@code original.length}, the result is padded
2783      * with the value {@code 0}.
2784      *
2785      * @param original the original array
2786      * @param start the start index, inclusive
2787      * @param end the end index, exclusive
2788      * @return the new array
2789      * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length}
2790      * @throws IllegalArgumentException if {@code start > end}
2791      * @throws NullPointerException if {@code original == null}
2792      * @since 1.6
2793      */
copyOfRange(int[] original, int start, int end)2794     public static int[] copyOfRange(int[] original, int start, int end) {
2795         if (start > end) {
2796             throw new IllegalArgumentException();
2797         }
2798         int originalLength = original.length;
2799         if (start < 0 || start > originalLength) {
2800             throw new ArrayIndexOutOfBoundsException();
2801         }
2802         int resultLength = end - start;
2803         int copyLength = Math.min(resultLength, originalLength - start);
2804         int[] result = new int[resultLength];
2805         System.arraycopy(original, start, result, 0, copyLength);
2806         return result;
2807     }
2808 
2809     /**
2810      * Copies elements from {@code original} into a new array, from indexes start (inclusive) to
2811      * end (exclusive). The original order of elements is preserved.
2812      * If {@code end} is greater than {@code original.length}, the result is padded
2813      * with the value {@code 0L}.
2814      *
2815      * @param original the original array
2816      * @param start the start index, inclusive
2817      * @param end the end index, exclusive
2818      * @return the new array
2819      * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length}
2820      * @throws IllegalArgumentException if {@code start > end}
2821      * @throws NullPointerException if {@code original == null}
2822      * @since 1.6
2823      */
copyOfRange(long[] original, int start, int end)2824     public static long[] copyOfRange(long[] original, int start, int end) {
2825         if (start > end) {
2826             throw new IllegalArgumentException();
2827         }
2828         int originalLength = original.length;
2829         if (start < 0 || start > originalLength) {
2830             throw new ArrayIndexOutOfBoundsException();
2831         }
2832         int resultLength = end - start;
2833         int copyLength = Math.min(resultLength, originalLength - start);
2834         long[] result = new long[resultLength];
2835         System.arraycopy(original, start, result, 0, copyLength);
2836         return result;
2837     }
2838 
2839     /**
2840      * Copies elements from {@code original} into a new array, from indexes start (inclusive) to
2841      * end (exclusive). The original order of elements is preserved.
2842      * If {@code end} is greater than {@code original.length}, the result is padded
2843      * with the value {@code (short) 0}.
2844      *
2845      * @param original the original array
2846      * @param start the start index, inclusive
2847      * @param end the end index, exclusive
2848      * @return the new array
2849      * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length}
2850      * @throws IllegalArgumentException if {@code start > end}
2851      * @throws NullPointerException if {@code original == null}
2852      * @since 1.6
2853      */
copyOfRange(short[] original, int start, int end)2854     public static short[] copyOfRange(short[] original, int start, int end) {
2855         if (start > end) {
2856             throw new IllegalArgumentException();
2857         }
2858         int originalLength = original.length;
2859         if (start < 0 || start > originalLength) {
2860             throw new ArrayIndexOutOfBoundsException();
2861         }
2862         int resultLength = end - start;
2863         int copyLength = Math.min(resultLength, originalLength - start);
2864         short[] result = new short[resultLength];
2865         System.arraycopy(original, start, result, 0, copyLength);
2866         return result;
2867     }
2868 
2869     /**
2870      * Copies elements from {@code original} into a new array, from indexes start (inclusive) to
2871      * end (exclusive). The original order of elements is preserved.
2872      * If {@code end} is greater than {@code original.length}, the result is padded
2873      * with the value {@code null}.
2874      *
2875      * @param original the original array
2876      * @param start the start index, inclusive
2877      * @param end the end index, exclusive
2878      * @return the new array
2879      * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length}
2880      * @throws IllegalArgumentException if {@code start > end}
2881      * @throws NullPointerException if {@code original == null}
2882      * @since 1.6
2883      */
2884     @SuppressWarnings("unchecked")
copyOfRange(T[] original, int start, int end)2885     public static <T> T[] copyOfRange(T[] original, int start, int end) {
2886         int originalLength = original.length; // For exception priority compatibility.
2887         if (start > end) {
2888             throw new IllegalArgumentException();
2889         }
2890         if (start < 0 || start > originalLength) {
2891             throw new ArrayIndexOutOfBoundsException();
2892         }
2893         int resultLength = end - start;
2894         int copyLength = Math.min(resultLength, originalLength - start);
2895         T[] result = (T[]) Array.newInstance(original.getClass().getComponentType(), resultLength);
2896         System.arraycopy(original, start, result, 0, copyLength);
2897         return result;
2898     }
2899 
2900     /**
2901      * Copies elements from {@code original} into a new array, from indexes start (inclusive) to
2902      * end (exclusive). The original order of elements is preserved.
2903      * If {@code end} is greater than {@code original.length}, the result is padded
2904      * with the value {@code null}.
2905      *
2906      * @param original the original array
2907      * @param start the start index, inclusive
2908      * @param end the end index, exclusive
2909      * @return the new array
2910      * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length}
2911      * @throws IllegalArgumentException if {@code start > end}
2912      * @throws NullPointerException if {@code original == null}
2913      * @throws ArrayStoreException if a value in {@code original} is incompatible with T
2914      * @since 1.6
2915      */
2916     @SuppressWarnings("unchecked")
copyOfRange(U[] original, int start, int end, Class<? extends T[]> newType)2917     public static <T, U> T[] copyOfRange(U[] original, int start, int end, Class<? extends T[]> newType) {
2918         if (start > end) {
2919             throw new IllegalArgumentException();
2920         }
2921         int originalLength = original.length;
2922         if (start < 0 || start > originalLength) {
2923             throw new ArrayIndexOutOfBoundsException();
2924         }
2925         int resultLength = end - start;
2926         int copyLength = Math.min(resultLength, originalLength - start);
2927         T[] result = (T[]) Array.newInstance(newType.getComponentType(), resultLength);
2928         System.arraycopy(original, start, result, 0, copyLength);
2929         return result;
2930     }
2931 }
2932