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