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