View Javadoc

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  package org.apache.commons.lang;
18  
19  import java.lang.reflect.Array;
20  import java.util.HashMap;
21  import java.util.Map;
22  
23  import org.apache.commons.lang.builder.EqualsBuilder;
24  import org.apache.commons.lang.builder.HashCodeBuilder;
25  import org.apache.commons.lang.builder.ToStringBuilder;
26  import org.apache.commons.lang.builder.ToStringStyle;
27  
28  /**
29   * <p>Operations on arrays, primitive arrays (like <code>int[]</code>) and
30   * primitive wrapper arrays (like <code>Integer[]</code>).</p>
31   * 
32   * <p>This class tries to handle <code>null</code> input gracefully.
33   * An exception will not be thrown for a <code>null</code>
34   * array input. However, an Object array that contains a <code>null</code>
35   * element may throw an exception. Each method documents its behaviour.</p>
36   *
37   * @author Stephen Colebourne
38   * @author Moritz Petersen
39   * @author <a href="mailto:fredrik@westermarck.com">Fredrik Westermarck</a>
40   * @author Nikolay Metchev
41   * @author Matthew Hawthorne
42   * @author Tim O'Brien
43   * @author Pete Gieser
44   * @author Gary Gregory
45   * @author <a href="mailto:equinus100@hotmail.com">Ashwin S</a>
46   * @author Maarten Coene
47   * @since 2.0
48   * @version $Id: ArrayUtils.java 632503 2008-03-01 00:21:52Z ggregory $
49   */
50  public class ArrayUtils {
51  
52      /**
53       * An empty immutable <code>Object</code> array.
54       */
55      public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
56      /**
57       * An empty immutable <code>Class</code> array.
58       */
59      public static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
60      /**
61       * An empty immutable <code>String</code> array.
62       */
63      public static final String[] EMPTY_STRING_ARRAY = new String[0];
64      /**
65       * An empty immutable <code>long</code> array.
66       */
67      public static final long[] EMPTY_LONG_ARRAY = new long[0];
68      /**
69       * An empty immutable <code>Long</code> array.
70       */
71      public static final Long[] EMPTY_LONG_OBJECT_ARRAY = new Long[0];
72      /**
73       * An empty immutable <code>int</code> array.
74       */
75      public static final int[] EMPTY_INT_ARRAY = new int[0];
76      /**
77       * An empty immutable <code>Integer</code> array.
78       */
79      public static final Integer[] EMPTY_INTEGER_OBJECT_ARRAY = new Integer[0];
80      /**
81       * An empty immutable <code>short</code> array.
82       */
83      public static final short[] EMPTY_SHORT_ARRAY = new short[0];
84      /**
85       * An empty immutable <code>Short</code> array.
86       */
87      public static final Short[] EMPTY_SHORT_OBJECT_ARRAY = new Short[0];
88      /**
89       * An empty immutable <code>byte</code> array.
90       */
91      public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
92      /**
93       * An empty immutable <code>Byte</code> array.
94       */
95      public static final Byte[] EMPTY_BYTE_OBJECT_ARRAY = new Byte[0];
96      /**
97       * An empty immutable <code>double</code> array.
98       */
99      public static final double[] EMPTY_DOUBLE_ARRAY = new double[0];
100     /**
101      * An empty immutable <code>Double</code> array.
102      */
103     public static final Double[] EMPTY_DOUBLE_OBJECT_ARRAY = new Double[0];
104     /**
105      * An empty immutable <code>float</code> array.
106      */
107     public static final float[] EMPTY_FLOAT_ARRAY = new float[0];
108     /**
109      * An empty immutable <code>Float</code> array.
110      */
111     public static final Float[] EMPTY_FLOAT_OBJECT_ARRAY = new Float[0];
112     /**
113      * An empty immutable <code>boolean</code> array.
114      */
115     public static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0];
116     /**
117      * An empty immutable <code>Boolean</code> array.
118      */
119     public static final Boolean[] EMPTY_BOOLEAN_OBJECT_ARRAY = new Boolean[0];
120     /**
121      * An empty immutable <code>char</code> array.
122      */
123     public static final char[] EMPTY_CHAR_ARRAY = new char[0];
124     /**
125      * An empty immutable <code>Character</code> array.
126      */
127     public static final Character[] EMPTY_CHARACTER_OBJECT_ARRAY = new Character[0];
128 
129     /**
130      * The index value when an element is not found in a list or array: <code>-1</code>.
131      * This value is returned by methods in this class and can also be used in comparisons with values returned by
132      * various method from {@link java.util.List}.
133      */
134     public static final int INDEX_NOT_FOUND = -1;
135 
136     /**
137      * <p>ArrayUtils instances should NOT be constructed in standard programming.
138      * Instead, the class should be used as <code>ArrayUtils.clone(new int[] {2})</code>.</p>
139      *
140      * <p>This constructor is public to permit tools that require a JavaBean instance
141      * to operate.</p>
142      */
143     public ArrayUtils() {
144       super();
145     }
146     
147     // Basic methods handling multi-dimensional arrays
148     //-----------------------------------------------------------------------
149     /**
150      * <p>Outputs an array as a String, treating <code>null</code> as an empty array.</p>
151      *
152      * <p>Multi-dimensional arrays are handled correctly, including
153      * multi-dimensional primitive arrays.</p>
154      *
155      * <p>The format is that of Java source code, for example <code>{a,b}</code>.</p>
156      * 
157      * @param array  the array to get a toString for, may be <code>null</code>
158      * @return a String representation of the array, '{}' if null array input
159      */
160     public static String toString(Object array) {
161         return toString(array, "{}");
162     }
163 
164     /**
165      * <p>Outputs an array as a String handling <code>null</code>s.</p>
166      *
167      * <p>Multi-dimensional arrays are handled correctly, including
168      * multi-dimensional primitive arrays.</p>
169      *
170      * <p>The format is that of Java source code, for example <code>{a,b}</code>.</p>
171      * 
172      * @param array  the array to get a toString for, may be <code>null</code>
173      * @param stringIfNull  the String to return if the array is <code>null</code>
174      * @return a String representation of the array
175      */    
176     public static String toString(Object array, String stringIfNull) {
177         if (array == null) {
178             return stringIfNull;
179         }
180         return new ToStringBuilder(array, ToStringStyle.SIMPLE_STYLE).append(array).toString();
181     }
182 
183     /**
184      * <p>Get a hashCode for an array handling multi-dimensional arrays correctly.</p>
185      * 
186      * <p>Multi-dimensional primitive arrays are also handled correctly by this method.</p>
187      * 
188      * @param array  the array to get a hashCode for, may be <code>null</code>
189      * @return a hashCode for the array, zero if null array input
190      */
191     public static int hashCode(Object array) {
192         return new HashCodeBuilder().append(array).toHashCode();
193     }
194 
195     /**
196      * <p>Compares two arrays, using equals(), handling multi-dimensional arrays
197      * correctly.</p>
198      * 
199      * <p>Multi-dimensional primitive arrays are also handled correctly by this method.</p>
200      * 
201      * @param array1  the left hand array to compare, may be <code>null</code>
202      * @param array2  the right hand array to compare, may be <code>null</code>
203      * @return <code>true</code> if the arrays are equal
204      */
205     public static boolean isEquals(Object array1, Object array2) {
206         return new EqualsBuilder().append(array1, array2).isEquals();
207     }
208 
209     // To map
210     //-----------------------------------------------------------------------
211     /**
212      * <p>Converts the given array into a {@link java.util.Map}. Each element of the array
213      * must be either a {@link java.util.Map.Entry} or an Array, containing at least two
214      * elements, where the first element is used as key and the second as
215      * value.</p>
216      *
217      * <p>This method can be used to initialize:</p>
218      * <pre>
219      * // Create a Map mapping colors.
220      * Map colorMap = MapUtils.toMap(new String[][] {{
221      *     {"RED", "#FF0000"},
222      *     {"GREEN", "#00FF00"},
223      *     {"BLUE", "#0000FF"}});
224      * </pre>
225      * 
226      * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
227      *
228      * @param array  an array whose elements are either a {@link java.util.Map.Entry} or
229      *  an Array containing at least two elements, may be <code>null</code>
230      * @return a <code>Map</code> that was created from the array
231      * @throws IllegalArgumentException  if one element of this Array is
232      *  itself an Array containing less then two elements
233      * @throws IllegalArgumentException  if the array contains elements other
234      *  than {@link java.util.Map.Entry} and an Array
235      */
236     public static Map toMap(Object[] array) {
237         if (array == null) {
238             return null;
239         }
240         final Map map = new HashMap((int) (array.length * 1.5));
241         for (int i = 0; i < array.length; i++) {
242             Object object = array[i];
243             if (object instanceof Map.Entry) {
244                 Map.Entry entry = (Map.Entry) object;
245                 map.put(entry.getKey(), entry.getValue());
246             } else if (object instanceof Object[]) {
247                 Object[] entry = (Object[]) object;
248                 if (entry.length < 2) {
249                     throw new IllegalArgumentException("Array element " + i + ", '"
250                         + object
251                         + "', has a length less than 2");
252                 }
253                 map.put(entry[0], entry[1]);
254             } else {
255                 throw new IllegalArgumentException("Array element " + i + ", '"
256                         + object
257                         + "', is neither of type Map.Entry nor an Array");
258             }
259         }
260         return map;
261     }
262 
263     // Clone
264     //-----------------------------------------------------------------------
265     /**
266      * <p>Shallow clones an array returning a typecast result and handling
267      * <code>null</code>.</p>
268      *
269      * <p>The objects in the array are not cloned, thus there is no special
270      * handling for multi-dimensional arrays.</p>
271      * 
272      * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
273      * 
274      * @param array  the array to shallow clone, may be <code>null</code>
275      * @return the cloned array, <code>null</code> if <code>null</code> input
276      */
277     public static Object[] clone(Object[] array) {
278         if (array == null) {
279             return null;
280         }
281         return (Object[]) array.clone();
282     }
283 
284     /**
285      * <p>Clones an array returning a typecast result and handling
286      * <code>null</code>.</p>
287      *
288      * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
289      * 
290      * @param array  the array to clone, may be <code>null</code>
291      * @return the cloned array, <code>null</code> if <code>null</code> input
292      */
293     public static long[] clone(long[] array) {
294         if (array == null) {
295             return null;
296         }
297         return (long[]) array.clone();
298     }
299 
300     /**
301      * <p>Clones an array returning a typecast result and handling
302      * <code>null</code>.</p>
303      *
304      * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
305      * 
306      * @param array  the array to clone, may be <code>null</code>
307      * @return the cloned array, <code>null</code> if <code>null</code> input
308      */
309     public static int[] clone(int[] array) {
310         if (array == null) {
311             return null;
312         }
313         return (int[]) array.clone();
314     }
315 
316     /**
317      * <p>Clones an array returning a typecast result and handling
318      * <code>null</code>.</p>
319      *
320      * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
321      * 
322      * @param array  the array to clone, may be <code>null</code>
323      * @return the cloned array, <code>null</code> if <code>null</code> input
324      */
325     public static short[] clone(short[] array) {
326         if (array == null) {
327             return null;
328         }
329         return (short[]) array.clone();
330     }
331 
332     /**
333      * <p>Clones an array returning a typecast result and handling
334      * <code>null</code>.</p>
335      *
336      * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
337      * 
338      * @param array  the array to clone, may be <code>null</code>
339      * @return the cloned array, <code>null</code> if <code>null</code> input
340      */
341     public static char[] clone(char[] array) {
342         if (array == null) {
343             return null;
344         }
345         return (char[]) array.clone();
346     }
347 
348     /**
349      * <p>Clones an array returning a typecast result and handling
350      * <code>null</code>.</p>
351      *
352      * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
353      * 
354      * @param array  the array to clone, may be <code>null</code>
355      * @return the cloned array, <code>null</code> if <code>null</code> input
356      */
357     public static byte[] clone(byte[] array) {
358         if (array == null) {
359             return null;
360         }
361         return (byte[]) array.clone();
362     }
363 
364     /**
365      * <p>Clones an array returning a typecast result and handling
366      * <code>null</code>.</p>
367      *
368      * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
369      * 
370      * @param array  the array to clone, may be <code>null</code>
371      * @return the cloned array, <code>null</code> if <code>null</code> input
372      */
373     public static double[] clone(double[] array) {
374         if (array == null) {
375             return null;
376         }
377         return (double[]) array.clone();
378     }
379 
380     /**
381      * <p>Clones an array returning a typecast result and handling
382      * <code>null</code>.</p>
383      *
384      * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
385      * 
386      * @param array  the array to clone, may be <code>null</code>
387      * @return the cloned array, <code>null</code> if <code>null</code> input
388      */
389     public static float[] clone(float[] array) {
390         if (array == null) {
391             return null;
392         }
393         return (float[]) array.clone();
394     }
395 
396     /**
397      * <p>Clones an array returning a typecast result and handling
398      * <code>null</code>.</p>
399      *
400      * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
401      * 
402      * @param array  the array to clone, may be <code>null</code>
403      * @return the cloned array, <code>null</code> if <code>null</code> input
404      */
405     public static boolean[] clone(boolean[] array) {
406         if (array == null) {
407             return null;
408         }
409         return (boolean[]) array.clone();
410     }
411 
412     // Subarrays
413     //-----------------------------------------------------------------------
414     /**
415      * <p>Produces a new array containing the elements between
416      * the start and end indices.</p>
417      *
418      * <p>The start index is inclusive, the end index exclusive.
419      * Null array input produces null output.</p>
420      *
421      * <p>The component type of the subarray is always the same as
422      * that of the input array. Thus, if the input is an array of type
423      * <code>Date</code>, the following usage is envisaged:</p>
424      *
425      * <pre>
426      * Date[] someDates = (Date[])ArrayUtils.subarray(allDates, 2, 5);
427      * </pre>
428      *
429      * @param array  the array
430      * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
431      *      is promoted to 0, overvalue (&gt;array.length) results
432      *      in an empty array.
433      * @param endIndexExclusive  elements up to endIndex-1 are present in the
434      *      returned subarray. Undervalue (&lt; startIndex) produces
435      *      empty array, overvalue (&gt;array.length) is demoted to
436      *      array length.
437      * @return a new array containing the elements between
438      *      the start and end indices.
439      * @since 2.1
440      */
441     public static Object[] subarray(Object[] array, int startIndexInclusive, int endIndexExclusive) {
442         if (array == null) {
443             return null;
444         }
445         if (startIndexInclusive < 0) {
446             startIndexInclusive = 0;
447         }
448         if (endIndexExclusive > array.length) {
449             endIndexExclusive = array.length;
450         }
451         int newSize = endIndexExclusive - startIndexInclusive;
452         Class type = array.getClass().getComponentType();
453         if (newSize <= 0) {
454             return (Object[]) Array.newInstance(type, 0);
455         }
456         Object[] subarray = (Object[]) Array.newInstance(type, newSize);
457         System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
458         return subarray;
459     }
460 
461     /**
462      * <p>Produces a new <code>long</code> array containing the elements
463      * between the start and end indices.</p>
464      *
465      * <p>The start index is inclusive, the end index exclusive.
466      * Null array input produces null output.</p>
467      *
468      * @param array  the array
469      * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
470      *      is promoted to 0, overvalue (&gt;array.length) results
471      *      in an empty array.
472      * @param endIndexExclusive  elements up to endIndex-1 are present in the
473      *      returned subarray. Undervalue (&lt; startIndex) produces
474      *      empty array, overvalue (&gt;array.length) is demoted to
475      *      array length.
476      * @return a new array containing the elements between
477      *      the start and end indices.
478      * @since 2.1
479      */
480     public static long[] subarray(long[] array, int startIndexInclusive, int endIndexExclusive) {
481         if (array == null) {
482             return null;
483         }
484         if (startIndexInclusive < 0) {
485             startIndexInclusive = 0;
486         }
487         if (endIndexExclusive > array.length) {
488             endIndexExclusive = array.length;
489         }
490         int newSize = endIndexExclusive - startIndexInclusive;
491         if (newSize <= 0) {
492             return EMPTY_LONG_ARRAY;
493         }
494 
495         long[] subarray = new long[newSize];
496         System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
497         return subarray;
498     }
499 
500     /**
501      * <p>Produces a new <code>int</code> array containing the elements
502      * between the start and end indices.</p>
503      *
504      * <p>The start index is inclusive, the end index exclusive.
505      * Null array input produces null output.</p>
506      *
507      * @param array  the array
508      * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
509      *      is promoted to 0, overvalue (&gt;array.length) results
510      *      in an empty array.
511      * @param endIndexExclusive  elements up to endIndex-1 are present in the
512      *      returned subarray. Undervalue (&lt; startIndex) produces
513      *      empty array, overvalue (&gt;array.length) is demoted to
514      *      array length.
515      * @return a new array containing the elements between
516      *      the start and end indices.
517      * @since 2.1
518      */
519     public static int[] subarray(int[] array, int startIndexInclusive, int endIndexExclusive) {
520         if (array == null) {
521             return null;
522         }
523         if (startIndexInclusive < 0) {
524             startIndexInclusive = 0;
525         }
526         if (endIndexExclusive > array.length) {
527             endIndexExclusive = array.length;
528         }
529         int newSize = endIndexExclusive - startIndexInclusive;
530         if (newSize <= 0) {
531             return EMPTY_INT_ARRAY;
532         }
533 
534         int[] subarray = new int[newSize];
535         System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
536         return subarray;
537     }
538 
539     /**
540      * <p>Produces a new <code>short</code> array containing the elements
541      * between the start and end indices.</p>
542      *
543      * <p>The start index is inclusive, the end index exclusive.
544      * Null array input produces null output.</p>
545      *
546      * @param array  the array
547      * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
548      *      is promoted to 0, overvalue (&gt;array.length) results
549      *      in an empty array.
550      * @param endIndexExclusive  elements up to endIndex-1 are present in the
551      *      returned subarray. Undervalue (&lt; startIndex) produces
552      *      empty array, overvalue (&gt;array.length) is demoted to
553      *      array length.
554      * @return a new array containing the elements between
555      *      the start and end indices.
556      * @since 2.1
557      */
558     public static short[] subarray(short[] array, int startIndexInclusive, int endIndexExclusive) {
559         if (array == null) {
560             return null;
561         }
562         if (startIndexInclusive < 0) {
563             startIndexInclusive = 0;
564         }
565         if (endIndexExclusive > array.length) {
566             endIndexExclusive = array.length;
567         }
568         int newSize = endIndexExclusive - startIndexInclusive;
569         if (newSize <= 0) {
570             return EMPTY_SHORT_ARRAY;
571         }
572 
573         short[] subarray = new short[newSize];
574         System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
575         return subarray;
576     }
577 
578     /**
579      * <p>Produces a new <code>char</code> array containing the elements
580      * between the start and end indices.</p>
581      *
582      * <p>The start index is inclusive, the end index exclusive.
583      * Null array input produces null output.</p>
584      *
585      * @param array  the array
586      * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
587      *      is promoted to 0, overvalue (&gt;array.length) results
588      *      in an empty array.
589      * @param endIndexExclusive  elements up to endIndex-1 are present in the
590      *      returned subarray. Undervalue (&lt; startIndex) produces
591      *      empty array, overvalue (&gt;array.length) is demoted to
592      *      array length.
593      * @return a new array containing the elements between
594      *      the start and end indices.
595      * @since 2.1
596      */
597     public static char[] subarray(char[] array, int startIndexInclusive, int endIndexExclusive) {
598         if (array == null) {
599             return null;
600         }
601         if (startIndexInclusive < 0) {
602             startIndexInclusive = 0;
603         }
604         if (endIndexExclusive > array.length) {
605             endIndexExclusive = array.length;
606         }
607         int newSize = endIndexExclusive - startIndexInclusive;
608         if (newSize <= 0) {
609             return EMPTY_CHAR_ARRAY;
610         }
611 
612         char[] subarray = new char[newSize];
613         System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
614         return subarray;
615     }
616 
617     /**
618      * <p>Produces a new <code>byte</code> array containing the elements
619      * between the start and end indices.</p>
620      *
621      * <p>The start index is inclusive, the end index exclusive.
622      * Null array input produces null output.</p>
623      *
624      * @param array  the array
625      * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
626      *      is promoted to 0, overvalue (&gt;array.length) results
627      *      in an empty array.
628      * @param endIndexExclusive  elements up to endIndex-1 are present in the
629      *      returned subarray. Undervalue (&lt; startIndex) produces
630      *      empty array, overvalue (&gt;array.length) is demoted to
631      *      array length.
632      * @return a new array containing the elements between
633      *      the start and end indices.
634      * @since 2.1
635      */
636     public static byte[] subarray(byte[] array, int startIndexInclusive, int endIndexExclusive) {
637         if (array == null) {
638             return null;
639         }
640         if (startIndexInclusive < 0) {
641             startIndexInclusive = 0;
642         }
643         if (endIndexExclusive > array.length) {
644             endIndexExclusive = array.length;
645         }
646         int newSize = endIndexExclusive - startIndexInclusive;
647         if (newSize <= 0) {
648             return EMPTY_BYTE_ARRAY;
649         }
650 
651         byte[] subarray = new byte[newSize];
652         System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
653         return subarray;
654     }
655 
656     /**
657      * <p>Produces a new <code>double</code> array containing the elements
658      * between the start and end indices.</p>
659      *
660      * <p>The start index is inclusive, the end index exclusive.
661      * Null array input produces null output.</p>
662      *
663      * @param array  the array
664      * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
665      *      is promoted to 0, overvalue (&gt;array.length) results
666      *      in an empty array.
667      * @param endIndexExclusive  elements up to endIndex-1 are present in the
668      *      returned subarray. Undervalue (&lt; startIndex) produces
669      *      empty array, overvalue (&gt;array.length) is demoted to
670      *      array length.
671      * @return a new array containing the elements between
672      *      the start and end indices.
673      * @since 2.1
674      */
675     public static double[] subarray(double[] array, int startIndexInclusive, int endIndexExclusive) {
676         if (array == null) {
677             return null;
678         }
679         if (startIndexInclusive < 0) {
680             startIndexInclusive = 0;
681         }
682         if (endIndexExclusive > array.length) {
683             endIndexExclusive = array.length;
684         }
685         int newSize = endIndexExclusive - startIndexInclusive;
686         if (newSize <= 0) {
687             return EMPTY_DOUBLE_ARRAY;
688         }
689 
690         double[] subarray = new double[newSize];
691         System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
692         return subarray;
693     }
694 
695     /**
696      * <p>Produces a new <code>float</code> array containing the elements
697      * between the start and end indices.</p>
698      *
699      * <p>The start index is inclusive, the end index exclusive.
700      * Null array input produces null output.</p>
701      *
702      * @param array  the array
703      * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
704      *      is promoted to 0, overvalue (&gt;array.length) results
705      *      in an empty array.
706      * @param endIndexExclusive  elements up to endIndex-1 are present in the
707      *      returned subarray. Undervalue (&lt; startIndex) produces
708      *      empty array, overvalue (&gt;array.length) is demoted to
709      *      array length.
710      * @return a new array containing the elements between
711      *      the start and end indices.
712      * @since 2.1
713      */
714     public static float[] subarray(float[] array, int startIndexInclusive, int endIndexExclusive) {
715         if (array == null) {
716             return null;
717         }
718         if (startIndexInclusive < 0) {
719             startIndexInclusive = 0;
720         }
721         if (endIndexExclusive > array.length) {
722             endIndexExclusive = array.length;
723         }
724         int newSize = endIndexExclusive - startIndexInclusive;
725         if (newSize <= 0) {
726             return EMPTY_FLOAT_ARRAY;
727         }
728 
729         float[] subarray = new float[newSize];
730         System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
731         return subarray;
732     }
733 
734     /**
735      * <p>Produces a new <code>boolean</code> array containing the elements
736      * between the start and end indices.</p>
737      *
738      * <p>The start index is inclusive, the end index exclusive.
739      * Null array input produces null output.</p>
740      *
741      * @param array  the array
742      * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
743      *      is promoted to 0, overvalue (&gt;array.length) results
744      *      in an empty array.
745      * @param endIndexExclusive  elements up to endIndex-1 are present in the
746      *      returned subarray. Undervalue (&lt; startIndex) produces
747      *      empty array, overvalue (&gt;array.length) is demoted to
748      *      array length.
749      * @return a new array containing the elements between
750      *      the start and end indices.
751      * @since 2.1
752      */
753     public static boolean[] subarray(boolean[] array, int startIndexInclusive, int endIndexExclusive) {
754         if (array == null) {
755             return null;
756         }
757         if (startIndexInclusive < 0) {
758             startIndexInclusive = 0;
759         }
760         if (endIndexExclusive > array.length) {
761             endIndexExclusive = array.length;
762         }
763         int newSize = endIndexExclusive - startIndexInclusive;
764         if (newSize <= 0) {
765             return EMPTY_BOOLEAN_ARRAY;
766         }
767 
768         boolean[] subarray = new boolean[newSize];
769         System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
770         return subarray;
771     }
772 
773     // Is same length
774     //-----------------------------------------------------------------------
775     /**
776      * <p>Checks whether two arrays are the same length, treating
777      * <code>null</code> arrays as length <code>0</code>.
778      *
779      * <p>Any multi-dimensional aspects of the arrays are ignored.</p>
780      * 
781      * @param array1 the first array, may be <code>null</code>
782      * @param array2 the second array, may be <code>null</code>
783      * @return <code>true</code> if length of arrays matches, treating
784      *  <code>null</code> as an empty array
785      */    
786     public static boolean isSameLength(Object[] array1, Object[] array2) {
787         if ((array1 == null && array2 != null && array2.length > 0) ||
788             (array2 == null && array1 != null && array1.length > 0) ||
789             (array1 != null && array2 != null && array1.length != array2.length)) {
790                 return false;
791         }
792         return true;
793     }
794 
795     /**
796      * <p>Checks whether two arrays are the same length, treating
797      * <code>null</code> arrays as length <code>0</code>.</p>
798      * 
799      * @param array1 the first array, may be <code>null</code>
800      * @param array2 the second array, may be <code>null</code>
801      * @return <code>true</code> if length of arrays matches, treating
802      *  <code>null</code> as an empty array
803      */
804     public static boolean isSameLength(long[] array1, long[] array2) {
805         if ((array1 == null && array2 != null && array2.length > 0) ||
806             (array2 == null && array1 != null && array1.length > 0) ||
807             (array1 != null && array2 != null && array1.length != array2.length)) {
808                 return false;
809         }
810         return true;
811     }
812 
813     /**
814      * <p>Checks whether two arrays are the same length, treating
815      * <code>null</code> arrays as length <code>0</code>.</p>
816      * 
817      * @param array1 the first array, may be <code>null</code>
818      * @param array2 the second array, may be <code>null</code>
819      * @return <code>true</code> if length of arrays matches, treating
820      *  <code>null</code> as an empty array
821      */
822     public static boolean isSameLength(int[] array1, int[] array2) {
823         if ((array1 == null && array2 != null && array2.length > 0) ||
824             (array2 == null && array1 != null && array1.length > 0) ||
825             (array1 != null && array2 != null && array1.length != array2.length)) {
826                 return false;
827         }
828         return true;
829     }
830 
831     /**
832      * <p>Checks whether two arrays are the same length, treating
833      * <code>null</code> arrays as length <code>0</code>.</p>
834      * 
835      * @param array1 the first array, may be <code>null</code>
836      * @param array2 the second array, may be <code>null</code>
837      * @return <code>true</code> if length of arrays matches, treating
838      *  <code>null</code> as an empty array
839      */
840     public static boolean isSameLength(short[] array1, short[] array2) {
841         if ((array1 == null && array2 != null && array2.length > 0) ||
842             (array2 == null && array1 != null && array1.length > 0) ||
843             (array1 != null && array2 != null && array1.length != array2.length)) {
844                 return false;
845         }
846         return true;
847     }
848 
849     /**
850      * <p>Checks whether two arrays are the same length, treating
851      * <code>null</code> arrays as length <code>0</code>.</p>
852      * 
853      * @param array1 the first array, may be <code>null</code>
854      * @param array2 the second array, may be <code>null</code>
855      * @return <code>true</code> if length of arrays matches, treating
856      *  <code>null</code> as an empty array
857      */
858     public static boolean isSameLength(char[] array1, char[] array2) {
859         if ((array1 == null && array2 != null && array2.length > 0) ||
860             (array2 == null && array1 != null && array1.length > 0) ||
861             (array1 != null && array2 != null && array1.length != array2.length)) {
862                 return false;
863         }
864         return true;
865     }
866 
867     /**
868      * <p>Checks whether two arrays are the same length, treating
869      * <code>null</code> arrays as length <code>0</code>.</p>
870      * 
871      * @param array1 the first array, may be <code>null</code>
872      * @param array2 the second array, may be <code>null</code>
873      * @return <code>true</code> if length of arrays matches, treating
874      *  <code>null</code> as an empty array
875      */
876     public static boolean isSameLength(byte[] array1, byte[] array2) {
877         if ((array1 == null && array2 != null && array2.length > 0) ||
878             (array2 == null && array1 != null && array1.length > 0) ||
879             (array1 != null && array2 != null && array1.length != array2.length)) {
880                 return false;
881         }
882         return true;
883     }
884 
885     /**
886      * <p>Checks whether two arrays are the same length, treating
887      * <code>null</code> arrays as length <code>0</code>.</p>
888      * 
889      * @param array1 the first array, may be <code>null</code>
890      * @param array2 the second array, may be <code>null</code>
891      * @return <code>true</code> if length of arrays matches, treating
892      *  <code>null</code> as an empty array
893      */
894     public static boolean isSameLength(double[] array1, double[] array2) {
895         if ((array1 == null && array2 != null && array2.length > 0) ||
896             (array2 == null && array1 != null && array1.length > 0) ||
897             (array1 != null && array2 != null && array1.length != array2.length)) {
898                 return false;
899         }
900         return true;
901     }
902 
903     /**
904      * <p>Checks whether two arrays are the same length, treating
905      * <code>null</code> arrays as length <code>0</code>.</p>
906      * 
907      * @param array1 the first array, may be <code>null</code>
908      * @param array2 the second array, may be <code>null</code>
909      * @return <code>true</code> if length of arrays matches, treating
910      *  <code>null</code> as an empty array
911      */
912     public static boolean isSameLength(float[] array1, float[] array2) {
913         if ((array1 == null && array2 != null && array2.length > 0) ||
914             (array2 == null && array1 != null && array1.length > 0) ||
915             (array1 != null && array2 != null && array1.length != array2.length)) {
916                 return false;
917         }
918         return true;
919     }
920 
921     /**
922      * <p>Checks whether two arrays are the same length, treating
923      * <code>null</code> arrays as length <code>0</code>.</p>
924      * 
925      * @param array1 the first array, may be <code>null</code>
926      * @param array2 the second array, may be <code>null</code>
927      * @return <code>true</code> if length of arrays matches, treating
928      *  <code>null</code> as an empty array
929      */
930     public static boolean isSameLength(boolean[] array1, boolean[] array2) {
931         if ((array1 == null && array2 != null && array2.length > 0) ||
932             (array2 == null && array1 != null && array1.length > 0) ||
933             (array1 != null && array2 != null && array1.length != array2.length)) {
934                 return false;
935         }
936         return true;
937     }
938 
939     //-----------------------------------------------------------------------
940     /**
941      * <p>Returns the length of the specified array.
942      * This method can deal with <code>Object</code> arrays and with primitive arrays.</p>
943      *
944      * <p>If the input array is <code>null</code>, <code>0</code> is returned.</p>
945      *
946      * <pre>
947      * ArrayUtils.getLength(null)            = 0
948      * ArrayUtils.getLength([])              = 0
949      * ArrayUtils.getLength([null])          = 1
950      * ArrayUtils.getLength([true, false])   = 2
951      * ArrayUtils.getLength([1, 2, 3])       = 3
952      * ArrayUtils.getLength(["a", "b", "c"]) = 3
953      * </pre>
954      *
955      * @param array  the array to retrieve the length from, may be null
956      * @return The length of the array, or <code>0</code> if the array is <code>null</code>
957      * @throws IllegalArgumentException if the object arguement is not an array.
958      * @since 2.1
959      */
960     public static int getLength(Object array) {
961         if (array == null) {
962             return 0;
963         }
964         return Array.getLength(array);
965     }
966 
967     /**
968      * <p>Checks whether two arrays are the same type taking into account
969      * multi-dimensional arrays.</p>
970      * 
971      * @param array1 the first array, must not be <code>null</code>
972      * @param array2 the second array, must not be <code>null</code>
973      * @return <code>true</code> if type of arrays matches
974      * @throws IllegalArgumentException if either array is <code>null</code>
975      */    
976     public static boolean isSameType(Object array1, Object array2) {
977         if (array1 == null || array2 == null) {
978             throw new IllegalArgumentException("The Array must not be null");
979         }
980         return array1.getClass().getName().equals(array2.getClass().getName());
981     }
982 
983     // Reverse
984     //-----------------------------------------------------------------------
985     /** 
986      * <p>Reverses the order of the given array.</p>
987      *
988      * <p>There is no special handling for multi-dimensional arrays.</p>
989      *
990      * <p>This method does nothing for a <code>null</code> input array.</p>
991      * 
992      * @param array  the array to reverse, may be <code>null</code>
993      */
994     public static void reverse(Object[] array) {
995         if (array == null) {
996             return;
997         }
998         int i = 0;
999         int j = array.length - 1;
1000         Object tmp;
1001         while (j > i) {
1002             tmp = array[j];
1003             array[j] = array[i];
1004             array[i] = tmp;
1005             j--;
1006             i++;
1007         }
1008     }
1009 
1010     /**
1011      * <p>Reverses the order of the given array.</p>
1012      * 
1013      * <p>This method does nothing for a <code>null</code> input array.</p>
1014      * 
1015      * @param array  the array to reverse, may be <code>null</code>
1016      */
1017     public static void reverse(long[] array) {
1018         if (array == null) {
1019             return;
1020         }
1021         int i = 0;
1022         int j = array.length - 1;
1023         long tmp;
1024         while (j > i) {
1025             tmp = array[j];
1026             array[j] = array[i];
1027             array[i] = tmp;
1028             j--;
1029             i++;
1030         }
1031     }
1032 
1033     /**
1034      * <p>Reverses the order of the given array.</p>
1035      * 
1036      * <p>This method does nothing for a <code>null</code> input array.</p>
1037      * 
1038      * @param array  the array to reverse, may be <code>null</code>
1039      */
1040     public static void reverse(int[] array) {
1041         if (array == null) {
1042             return;
1043         }
1044         int i = 0;
1045         int j = array.length - 1;
1046         int tmp;
1047         while (j > i) {
1048             tmp = array[j];
1049             array[j] = array[i];
1050             array[i] = tmp;
1051             j--;
1052             i++;
1053         }
1054     }
1055 
1056     /**
1057      * <p>Reverses the order of the given array.</p>
1058      * 
1059      * <p>This method does nothing for a <code>null</code> input array.</p>
1060      * 
1061      * @param array  the array to reverse, may be <code>null</code>
1062      */
1063     public static void reverse(short[] array) {
1064         if (array == null) {
1065             return;
1066         }
1067         int i = 0;
1068         int j = array.length - 1;
1069         short tmp;
1070         while (j > i) {
1071             tmp = array[j];
1072             array[j] = array[i];
1073             array[i] = tmp;
1074             j--;
1075             i++;
1076         }
1077     }
1078 
1079     /**
1080      * <p>Reverses the order of the given array.</p>
1081      * 
1082      * <p>This method does nothing for a <code>null</code> input array.</p>
1083      * 
1084      * @param array  the array to reverse, may be <code>null</code>
1085      */
1086     public static void reverse(char[] array) {
1087         if (array == null) {
1088             return;
1089         }
1090         int i = 0;
1091         int j = array.length - 1;
1092         char tmp;
1093         while (j > i) {
1094             tmp = array[j];
1095             array[j] = array[i];
1096             array[i] = tmp;
1097             j--;
1098             i++;
1099         }
1100     }
1101 
1102     /**
1103      * <p>Reverses the order of the given array.</p>
1104      * 
1105      * <p>This method does nothing for a <code>null</code> input array.</p>
1106      * 
1107      * @param array  the array to reverse, may be <code>null</code>
1108      */
1109     public static void reverse(byte[] array) {
1110         if (array == null) {
1111             return;
1112         }
1113         int i = 0;
1114         int j = array.length - 1;
1115         byte tmp;
1116         while (j > i) {
1117             tmp = array[j];
1118             array[j] = array[i];
1119             array[i] = tmp;
1120             j--;
1121             i++;
1122         }
1123     }
1124 
1125     /**
1126      * <p>Reverses the order of the given array.</p>
1127      * 
1128      * <p>This method does nothing for a <code>null</code> input array.</p>
1129      * 
1130      * @param array  the array to reverse, may be <code>null</code>
1131      */
1132     public static void reverse(double[] array) {
1133         if (array == null) {
1134             return;
1135         }
1136         int i = 0;
1137         int j = array.length - 1;
1138         double tmp;
1139         while (j > i) {
1140             tmp = array[j];
1141             array[j] = array[i];
1142             array[i] = tmp;
1143             j--;
1144             i++;
1145         }
1146     }
1147 
1148     /**