001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.lang3;
018    
019    import java.lang.reflect.Array;
020    import java.util.HashMap;
021    import java.util.Map;
022    
023    import org.apache.commons.lang3.builder.EqualsBuilder;
024    import org.apache.commons.lang3.builder.ToStringBuilder;
025    import org.apache.commons.lang3.builder.ToStringStyle;
026    
027    /**
028     * <p>Operations on arrays, primitive arrays (like <code>int[]</code>) and
029     * primitive wrapper arrays (like <code>Integer[]</code>).</p>
030     *
031     * <p>This class tries to handle <code>null</code> input gracefully.
032     * An exception will not be thrown for a <code>null</code>
033     * array input. However, an Object array that contains a <code>null</code>
034     * element may throw an exception. Each method documents its behaviour.</p>
035     *
036     * <p>#ThreadSafe#</p>
037     * @author Apache Software Foundation
038     * @author Moritz Petersen
039     * @author <a href="mailto:fredrik@westermarck.com">Fredrik Westermarck</a>
040     * @author Nikolay Metchev
041     * @author Matthew Hawthorne
042     * @author Tim O'Brien
043     * @author Pete Gieser
044     * @author Gary Gregory
045     * @author <a href="mailto:equinus100@hotmail.com">Ashwin S</a>
046     * @author Maarten Coene
047     * @author <a href="mailto:levon@lk.otherinbox.com">Levon Karayan</a>
048     * @since 2.0
049     * @version $Id: ArrayUtils.java 918868 2010-03-04 06:22:16Z bayard $
050     */
051    public class ArrayUtils {
052    
053        /**
054         * An empty immutable <code>Object</code> array.
055         */
056        public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
057        /**
058         * An empty immutable <code>Class</code> array.
059         */
060        public static final Class<?>[] EMPTY_CLASS_ARRAY = new Class[0];
061        /**
062         * An empty immutable <code>String</code> array.
063         */
064        public static final String[] EMPTY_STRING_ARRAY = new String[0];
065        /**
066         * An empty immutable <code>long</code> array.
067         */
068        public static final long[] EMPTY_LONG_ARRAY = new long[0];
069        /**
070         * An empty immutable <code>Long</code> array.
071         */
072        public static final Long[] EMPTY_LONG_OBJECT_ARRAY = new Long[0];
073        /**
074         * An empty immutable <code>int</code> array.
075         */
076        public static final int[] EMPTY_INT_ARRAY = new int[0];
077        /**
078         * An empty immutable <code>Integer</code> array.
079         */
080        public static final Integer[] EMPTY_INTEGER_OBJECT_ARRAY = new Integer[0];
081        /**
082         * An empty immutable <code>short</code> array.
083         */
084        public static final short[] EMPTY_SHORT_ARRAY = new short[0];
085        /**
086         * An empty immutable <code>Short</code> array.
087         */
088        public static final Short[] EMPTY_SHORT_OBJECT_ARRAY = new Short[0];
089        /**
090         * An empty immutable <code>byte</code> array.
091         */
092        public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
093        /**
094         * An empty immutable <code>Byte</code> array.
095         */
096        public static final Byte[] EMPTY_BYTE_OBJECT_ARRAY = new Byte[0];
097        /**
098         * An empty immutable <code>double</code> array.
099         */
100        public static final double[] EMPTY_DOUBLE_ARRAY = new double[0];
101        /**
102         * An empty immutable <code>Double</code> array.
103         */
104        public static final Double[] EMPTY_DOUBLE_OBJECT_ARRAY = new Double[0];
105        /**
106         * An empty immutable <code>float</code> array.
107         */
108        public static final float[] EMPTY_FLOAT_ARRAY = new float[0];
109        /**
110         * An empty immutable <code>Float</code> array.
111         */
112        public static final Float[] EMPTY_FLOAT_OBJECT_ARRAY = new Float[0];
113        /**
114         * An empty immutable <code>boolean</code> array.
115         */
116        public static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0];
117        /**
118         * An empty immutable <code>Boolean</code> array.
119         */
120        public static final Boolean[] EMPTY_BOOLEAN_OBJECT_ARRAY = new Boolean[0];
121        /**
122         * An empty immutable <code>char</code> array.
123         */
124        public static final char[] EMPTY_CHAR_ARRAY = new char[0];
125        /**
126         * An empty immutable <code>Character</code> array.
127         */
128        public static final Character[] EMPTY_CHARACTER_OBJECT_ARRAY = new Character[0];
129    
130        /**
131         * The index value when an element is not found in a list or array: <code>-1</code>.
132         * This value is returned by methods in this class and can also be used in comparisons with values returned by
133         * various method from {@link java.util.List}.
134         */
135        public static final int INDEX_NOT_FOUND = -1;
136    
137        /**
138         * <p>ArrayUtils instances should NOT be constructed in standard programming.
139         * Instead, the class should be used as <code>ArrayUtils.clone(new int[] {2})</code>.</p>
140         *
141         * <p>This constructor is public to permit tools that require a JavaBean instance
142         * to operate.</p>
143         */
144        public ArrayUtils() {
145          super();
146        }
147    
148        // Basic methods handling multi-dimensional arrays
149        //-----------------------------------------------------------------------
150        /**
151         * <p>Outputs an array as a String, treating <code>null</code> as an empty array.</p>
152         *
153         * <p>Multi-dimensional arrays are handled correctly, including
154         * multi-dimensional primitive arrays.</p>
155         *
156         * <p>The format is that of Java source code, for example <code>{a,b}</code>.</p>
157         *
158         * @param array  the array to get a toString for, may be <code>null</code>
159         * @return a String representation of the array, '{}' if null array input
160         */
161        public static String toString(Object array) {
162            return toString(array, "{}");
163        }
164    
165        /**
166         * <p>Outputs an array as a String handling <code>null</code>s.</p>
167         *
168         * <p>Multi-dimensional arrays are handled correctly, including
169         * multi-dimensional primitive arrays.</p>
170         *
171         * <p>The format is that of Java source code, for example <code>{a,b}</code>.</p>
172         *
173         * @param array  the array to get a toString for, may be <code>null</code>
174         * @param stringIfNull  the String to return if the array is <code>null</code>
175         * @return a String representation of the array
176         */
177        public static String toString(Object array, String stringIfNull) {
178            if (array == null) {
179                return stringIfNull;
180            }
181            return new ToStringBuilder(array, ToStringStyle.SIMPLE_STYLE).append(array).toString();
182        }
183    
184        /**
185         * <p>Compares two arrays, using equals(), handling multi-dimensional arrays
186         * correctly.</p>
187         *
188         * <p>Multi-dimensional primitive arrays are also handled correctly by this method.</p>
189         *
190         * @param array1  the left hand array to compare, may be <code>null</code>
191         * @param array2  the right hand array to compare, may be <code>null</code>
192         * @return <code>true</code> if the arrays are equal
193         */
194        public static boolean isEquals(Object array1, Object array2) {
195            return new EqualsBuilder().append(array1, array2).isEquals();
196        }
197    
198        // To map
199        //-----------------------------------------------------------------------
200        /**
201         * <p>Converts the given array into a {@link java.util.Map}. Each element of the array
202         * must be either a {@link java.util.Map.Entry} or an Array, containing at least two
203         * elements, where the first element is used as key and the second as
204         * value.</p>
205         *
206         * <p>This method can be used to initialize:</p>
207         * <pre>
208         * // Create a Map mapping colors.
209         * Map colorMap = MapUtils.toMap(new String[][] {{
210         *     {"RED", "#FF0000"},
211         *     {"GREEN", "#00FF00"},
212         *     {"BLUE", "#0000FF"}});
213         * </pre>
214         *
215         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
216         *
217         * @param array  an array whose elements are either a {@link java.util.Map.Entry} or
218         *  an Array containing at least two elements, may be <code>null</code>
219         * @return a <code>Map</code> that was created from the array
220         * @throws IllegalArgumentException  if one element of this Array is
221         *  itself an Array containing less then two elements
222         * @throws IllegalArgumentException  if the array contains elements other
223         *  than {@link java.util.Map.Entry} and an Array
224         */
225        public static Map<Object, Object> toMap(Object[] array) {
226            if (array == null) {
227                return null;
228            }
229            final Map<Object, Object> map = new HashMap<Object, Object>((int) (array.length * 1.5));
230            for (int i = 0; i < array.length; i++) {
231                Object object = array[i];
232                if (object instanceof Map.Entry<?, ?>) {
233                    Map.Entry<?,?> entry = (Map.Entry<?,?>) object;
234                    map.put(entry.getKey(), entry.getValue());
235                } else if (object instanceof Object[]) {
236                    Object[] entry = (Object[]) object;
237                    if (entry.length < 2) {
238                        throw new IllegalArgumentException("Array element " + i + ", '"
239                            + object
240                            + "', has a length less than 2");
241                    }
242                    map.put(entry[0], entry[1]);
243                } else {
244                    throw new IllegalArgumentException("Array element " + i + ", '"
245                            + object
246                            + "', is neither of type Map.Entry nor an Array");
247                }
248            }
249            return map;
250        }
251    
252        // Generic array
253        //-----------------------------------------------------------------------
254        /**
255         * Create a type-safe generic array.
256         *
257         * <p>Arrays are covariant i.e. they cannot be created from a generic type:</p>
258         *
259         * <pre>
260        public static &lt;T&gt; T[] createAnArray(int size)
261        {
262            return T[size]; // compiler error here
263        }
264        public static &lt;T&gt; T[] createAnArray(int size)
265        {
266            return (T[])Object[size]; // ClassCastException at runtime
267        }
268         * </pre>
269         *
270         * <p>Therefore new arrays of generic types can be created with this method, e.g. an arrays
271         * of Strings:</p>
272         *
273         * <pre>
274        String[] array = ArrayUtils.toArray("1", "2");
275        String[] emptyArray = ArrayUtils.&lt;String&gt;toArray();
276         * </pre>
277         * 
278         * The method is typically used in scenarios, where the caller itself uses generic types
279         * that have to be combined into an array.
280         * 
281         * Note, this method makes only sense to provide arguments of the same type so that the
282         * compiler can deduce the type of the array itself. While it is possible to select the
283         * type explicitly like in <code>Number[] array = ArrayUtils.<Number>toArray(new
284         * Integer(42), new Double(Math.PI))</code>, there is no real advantage to <code>new
285         * Number[] {new Integer(42), new Double(Math.PI)}</code> anymore.
286         *
287         * @param  <T>   the array's element type
288         * @param  items the items of the array
289         * @return the array
290         * @since  3.0
291         */
292        public static <T> T[] toArray(final T... items)
293        {
294            return items;
295        }
296        
297        // Clone
298        //-----------------------------------------------------------------------
299        /**
300         * <p>Shallow clones an array returning a typecast result and handling
301         * <code>null</code>.</p>
302         *
303         * <p>The objects in the array are not cloned, thus there is no special
304         * handling for multi-dimensional arrays.</p>
305         *
306         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
307         *
308         * @param array  the array to shallow clone, may be <code>null</code>
309         * @return the cloned array, <code>null</code> if <code>null</code> input
310         */
311        public static <T> T[] clone(T[] array) {
312            if (array == null) {
313                return null;
314            }
315            return array.clone();
316        }
317    
318        /**
319         * <p>Clones an array returning a typecast result and handling
320         * <code>null</code>.</p>
321         *
322         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
323         *
324         * @param array  the array to clone, may be <code>null</code>
325         * @return the cloned array, <code>null</code> if <code>null</code> input
326         */
327        public static long[] clone(long[] array) {
328            if (array == null) {
329                return null;
330            }
331            return array.clone();
332        }
333    
334        /**
335         * <p>Clones an array returning a typecast result and handling
336         * <code>null</code>.</p>
337         *
338         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
339         *
340         * @param array  the array to clone, may be <code>null</code>
341         * @return the cloned array, <code>null</code> if <code>null</code> input
342         */
343        public static int[] clone(int[] array) {
344            if (array == null) {
345                return null;
346            }
347            return array.clone();
348        }
349    
350        /**
351         * <p>Clones an array returning a typecast result and handling
352         * <code>null</code>.</p>
353         *
354         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
355         *
356         * @param array  the array to clone, may be <code>null</code>
357         * @return the cloned array, <code>null</code> if <code>null</code> input
358         */
359        public static short[] clone(short[] array) {
360            if (array == null) {
361                return null;
362            }
363            return array.clone();
364        }
365    
366        /**
367         * <p>Clones an array returning a typecast result and handling
368         * <code>null</code>.</p>
369         *
370         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
371         *
372         * @param array  the array to clone, may be <code>null</code>
373         * @return the cloned array, <code>null</code> if <code>null</code> input
374         */
375        public static char[] clone(char[] array) {
376            if (array == null) {
377                return null;
378            }
379            return array.clone();
380        }
381    
382        /**
383         * <p>Clones an array returning a typecast result and handling
384         * <code>null</code>.</p>
385         *
386         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
387         *
388         * @param array  the array to clone, may be <code>null</code>
389         * @return the cloned array, <code>null</code> if <code>null</code> input
390         */
391        public static byte[] clone(byte[] array) {
392            if (array == null) {
393                return null;
394            }
395            return array.clone();
396        }
397    
398        /**
399         * <p>Clones an array returning a typecast result and handling
400         * <code>null</code>.</p>
401         *
402         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
403         *
404         * @param array  the array to clone, may be <code>null</code>
405         * @return the cloned array, <code>null</code> if <code>null</code> input
406         */
407        public static double[] clone(double[] array) {
408            if (array == null) {
409                return null;
410            }
411            return array.clone();
412        }
413    
414        /**
415         * <p>Clones an array returning a typecast result and handling
416         * <code>null</code>.</p>
417         *
418         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
419         *
420         * @param array  the array to clone, may be <code>null</code>
421         * @return the cloned array, <code>null</code> if <code>null</code> input
422         */
423        public static float[] clone(float[] array) {
424            if (array == null) {
425                return null;
426            }
427            return array.clone();
428        }
429    
430        /**
431         * <p>Clones an array returning a typecast result and handling
432         * <code>null</code>.</p>
433         *
434         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
435         *
436         * @param array  the array to clone, may be <code>null</code>
437         * @return the cloned array, <code>null</code> if <code>null</code> input
438         */
439        public static boolean[] clone(boolean[] array) {
440            if (array == null) {
441                return null;
442            }
443            return array.clone();
444        }
445    
446        // nullToEmpty
447        //-----------------------------------------------------------------------
448        /**
449         * <p>Defensive programming technique to change a <code>null</code>
450         * reference to an empty one.</p>
451         *
452         * <p>This method returns an empty array for a <code>null</code> input array.</p>
453         * 
454         * <p>As a memory optimizing technique an empty array passed in will be overridden with 
455         * the empty <code>public static</code> references in this class.</p>
456         *
457         * @param array  the array to check for <code>null</code> or empty
458         * @return the same array, <code>public static</code> empty array if <code>null</code> or empty input
459         * @since 2.5
460         */
461        public static Object[] nullToEmpty(Object[] array) {
462            if (array == null || array.length == 0) {
463                return EMPTY_OBJECT_ARRAY;
464            }
465            return array;
466        }
467    
468        /**
469         * <p>Defensive programming technique to change a <code>null</code>
470         * reference to an empty one.</p>
471         *
472         * <p>This method returns an empty array for a <code>null</code> input array.</p>
473         * 
474         * <p>As a memory optimizing technique an empty array passed in will be overridden with 
475         * the empty <code>public static</code> references in this class.</p>
476         *
477         * @param array  the array to check for <code>null</code> or empty
478         * @return the same array, <code>public static</code> empty array if <code>null</code> or empty input
479         * @since 2.5
480         */
481        public static String[] nullToEmpty(String[] array) {
482            if (array == null || array.length == 0) {
483                return EMPTY_STRING_ARRAY;
484            }
485            return array;
486        }
487    
488        /**
489         * <p>Defensive programming technique to change a <code>null</code>
490         * reference to an empty one.</p>
491         *
492         * <p>This method returns an empty array for a <code>null</code> input array.</p>
493         * 
494         * <p>As a memory optimizing technique an empty array passed in will be overridden with 
495         * the empty <code>public static</code> references in this class.</p>
496         *
497         * @param array  the array to check for <code>null</code> or empty
498         * @return the same array, <code>public static</code> empty array if <code>null</code> or empty input
499         * @since 2.5
500         */
501        public static long[] nullToEmpty(long[] array) {
502            if (array == null || array.length == 0) {
503                return EMPTY_LONG_ARRAY;
504            }
505            return array;
506        }
507    
508        /**
509         * <p>Defensive programming technique to change a <code>null</code>
510         * reference to an empty one.</p>
511         *
512         * <p>This method returns an empty array for a <code>null</code> input array.</p>
513         * 
514         * <p>As a memory optimizing technique an empty array passed in will be overridden with 
515         * the empty <code>public static</code> references in this class.</p>
516         *
517         * @param array  the array to check for <code>null</code> or empty
518         * @return the same array, <code>public static</code> empty array if <code>null</code> or empty input
519         * @since 2.5
520         */
521        public static int[] nullToEmpty(int[] array) {
522            if (array == null || array.length == 0) {
523                return EMPTY_INT_ARRAY;
524            }
525            return array;
526        }
527    
528        /**
529         * <p>Defensive programming technique to change a <code>null</code>
530         * reference to an empty one.</p>
531         *
532         * <p>This method returns an empty array for a <code>null</code> input array.</p>
533         * 
534         * <p>As a memory optimizing technique an empty array passed in will be overridden with 
535         * the empty <code>public static</code> references in this class.</p>
536         *
537         * @param array  the array to check for <code>null</code> or empty
538         * @return the same array, <code>public static</code> empty array if <code>null</code> or empty input
539         * @since 2.5
540         */
541        public static short[] nullToEmpty(short[] array) {
542            if (array == null || array.length == 0) {
543                return EMPTY_SHORT_ARRAY;
544            }
545            return array;
546        }
547    
548        /**
549         * <p>Defensive programming technique to change a <code>null</code>
550         * reference to an empty one.</p>
551         *
552         * <p>This method returns an empty array for a <code>null</code> input array.</p>
553         * 
554         * <p>As a memory optimizing technique an empty array passed in will be overridden with 
555         * the empty <code>public static</code> references in this class.</p>
556         *
557         * @param array  the array to check for <code>null</code> or empty
558         * @return the same array, <code>public static</code> empty array if <code>null</code> or empty input
559         * @since 2.5
560         */
561        public static char[] nullToEmpty(char[] array) {
562            if (array == null || array.length == 0) {
563                return EMPTY_CHAR_ARRAY;
564            }
565            return array;
566        }
567    
568        /**
569         * <p>Defensive programming technique to change a <code>null</code>
570         * reference to an empty one.</p>
571         *
572         * <p>This method returns an empty array for a <code>null</code> input array.</p>
573         * 
574         * <p>As a memory optimizing technique an empty array passed in will be overridden with 
575         * the empty <code>public static</code> references in this class.</p>
576         *
577         * @param array  the array to check for <code>null</code> or empty
578         * @return the same array, <code>public static</code> empty array if <code>null</code> or empty input
579         * @since 2.5
580         */
581        public static byte[] nullToEmpty(byte[] array) {
582            if (array == null || array.length == 0) {
583                return EMPTY_BYTE_ARRAY;
584            }
585            return array;
586        }
587    
588        /**
589         * <p>Defensive programming technique to change a <code>null</code>
590         * reference to an empty one.</p>
591         *
592         * <p>This method returns an empty array for a <code>null</code> input array.</p>
593         * 
594         * <p>As a memory optimizing technique an empty array passed in will be overridden with 
595         * the empty <code>public static</code> references in this class.</p>
596         *
597         * @param array  the array to check for <code>null</code> or empty
598         * @return the same array, <code>public static</code> empty array if <code>null</code> or empty input
599         * @since 2.5
600         */
601        public static double[] nullToEmpty(double[] array) {
602            if (array == null || array.length == 0) {
603                return EMPTY_DOUBLE_ARRAY;
604            }
605            return array;
606        }
607    
608        /**
609         * <p>Defensive programming technique to change a <code>null</code>
610         * reference to an empty one.</p>
611         *
612         * <p>This method returns an empty array for a <code>null</code> input array.</p>
613         * 
614         * <p>As a memory optimizing technique an empty array passed in will be overridden with 
615         * the empty <code>public static</code> references in this class.</p>
616         *
617         * @param array  the array to check for <code>null</code> or empty
618         * @return the same array, <code>public static</code> empty array if <code>null</code> or empty input
619         * @since 2.5
620         */
621        public static float[] nullToEmpty(float[] array) {
622            if (array == null || array.length == 0) {
623                return EMPTY_FLOAT_ARRAY;
624            }
625            return array;
626        }
627    
628        /**
629         * <p>Defensive programming technique to change a <code>null</code>
630         * reference to an empty one.</p>
631         *
632         * <p>This method returns an empty array for a <code>null</code> input array.</p>
633         * 
634         * <p>As a memory optimizing technique an empty array passed in will be overridden with 
635         * the empty <code>public static</code> references in this class.</p>
636         *
637         * @param array  the array to check for <code>null</code> or empty
638         * @return the same array, <code>public static</code> empty array if <code>null</code> or empty input
639         * @since 2.5
640         */
641        public static boolean[] nullToEmpty(boolean[] array) {
642            if (array == null || array.length == 0) {
643                return EMPTY_BOOLEAN_ARRAY;
644            }
645            return array;
646        }
647    
648        /**
649         * <p>Defensive programming technique to change a <code>null</code>
650         * reference to an empty one.</p>
651         *
652         * <p>This method returns an empty array for a <code>null</code> input array.</p>
653         * 
654         * <p>As a memory optimizing technique an empty array passed in will be overridden with 
655         * the empty <code>public static</code> references in this class.</p>
656         *
657         * @param array  the array to check for <code>null</code> or empty
658         * @return the same array, <code>public static</code> empty array if <code>null</code> or empty input
659         * @since 2.5
660         */
661        public static Long[] nullToEmpty(Long[] array) {
662            if (array == null || array.length == 0) {
663                return EMPTY_LONG_OBJECT_ARRAY;
664            }
665            return array;
666        }
667    
668        /**
669         * <p>Defensive programming technique to change a <code>null</code>
670         * reference to an empty one.</p>
671         *
672         * <p>This method returns an empty array for a <code>null</code> input array.</p>
673         * 
674         * <p>As a memory optimizing technique an empty array passed in will be overridden with 
675         * the empty <code>public static</code> references in this class.</p>
676         *
677         * @param array  the array to check for <code>null</code> or empty
678         * @return the same array, <code>public static</code> empty array if <code>null</code> or empty input
679         * @since 2.5
680         */
681        public static Integer[] nullToEmpty(Integer[] array) {
682            if (array == null || array.length == 0) {
683                return EMPTY_INTEGER_OBJECT_ARRAY;
684            }
685            return array;
686        }
687    
688        /**
689         * <p>Defensive programming technique to change a <code>null</code>
690         * reference to an empty one.</p>
691         *
692         * <p>This method returns an empty array for a <code>null</code> input array.</p>
693         * 
694         * <p>As a memory optimizing technique an empty array passed in will be overridden with 
695         * the empty <code>public static</code> references in this class.</p>
696         *
697         * @param array  the array to check for <code>null</code> or empty
698         * @return the same array, <code>public static</code> empty array if <code>null</code> or empty input
699         * @since 2.5
700         */
701        public static Short[] nullToEmpty(Short[] array) {
702            if (array == null || array.length == 0) {
703                return EMPTY_SHORT_OBJECT_ARRAY;
704            }
705            return array;
706        }
707    
708        /**
709         * <p>Defensive programming technique to change a <code>null</code>
710         * reference to an empty one.</p>
711         *
712         * <p>This method returns an empty array for a <code>null</code> input array.</p>
713         * 
714         * <p>As a memory optimizing technique an empty array passed in will be overridden with 
715         * the empty <code>public static</code> references in this class.</p>
716         *
717         * @param array  the array to check for <code>null</code> or empty
718         * @return the same array, <code>public static</code> empty array if <code>null</code> or empty input
719         * @since 2.5
720         */
721        public static Character[] nullToEmpty(Character[] array) {
722            if (array == null || array.length == 0) {
723                return EMPTY_CHARACTER_OBJECT_ARRAY;
724            }
725            return array;
726        }
727    
728        /**
729         * <p>Defensive programming technique to change a <code>null</code>
730         * reference to an empty one.</p>
731         *
732         * <p>This method returns an empty array for a <code>null</code> input array.</p>
733         * 
734         * <p>As a memory optimizing technique an empty array passed in will be overridden with 
735         * the empty <code>public static</code> references in this class.</p>
736         *
737         * @param array  the array to check for <code>null</code> or empty
738         * @return the same array, <code>public static</code> empty array if <code>null</code> or empty input
739         * @since 2.5
740         */
741        public static Byte[] nullToEmpty(Byte[] array) {
742            if (array == null || array.length == 0) {
743                return EMPTY_BYTE_OBJECT_ARRAY;
744            }
745            return array;
746        }
747    
748        /**
749         * <p>Defensive programming technique to change a <code>null</code>
750         * reference to an empty one.</p>
751         *
752         * <p>This method returns an empty array for a <code>null</code> input array.</p>
753         * 
754         * <p>As a memory optimizing technique an empty array passed in will be overridden with 
755         * the empty <code>public static</code> references in this class.</p>
756         *
757         * @param array  the array to check for <code>null</code> or empty
758         * @return the same array, <code>public static</code> empty array if <code>null</code> or empty input
759         * @since 2.5
760         */
761        public static Double[] nullToEmpty(Double[] array) {
762            if (array == null || array.length == 0) {
763                return EMPTY_DOUBLE_OBJECT_ARRAY;
764            }
765            return array;
766        }
767    
768        /**
769         * <p>Defensive programming technique to change a <code>null</code>
770         * reference to an empty one.</p>
771         *
772         * <p>This method returns an empty array for a <code>null</code> input array.</p>
773         * 
774         * <p>As a memory optimizing technique an empty array passed in will be overridden with 
775         * the empty <code>public static</code> references in this class.</p>
776         *
777         * @param array  the array to check for <code>null</code> or empty
778         * @return the same array, <code>public static</code> empty array if <code>null</code> or empty input
779         * @since 2.5
780         */
781        public static Float[] nullToEmpty(Float[] array) {
782            if (array == null || array.length == 0) {
783                return EMPTY_FLOAT_OBJECT_ARRAY;
784            }
785            return array;
786        }
787    
788        /**
789         * <p>Defensive programming technique to change a <code>null</code>
790         * reference to an empty one.</p>
791         *
792         * <p>This method returns an empty array for a <code>null</code> input array.</p>
793         * 
794         * <p>As a memory optimizing technique an empty array passed in will be overridden with 
795         * the empty <code>public static</code> references in this class.</p>
796         *
797         * @param array  the array to check for <code>null</code> or empty
798         * @return the same array, <code>public static</code> empty array if <code>null</code> or empty input
799         * @since 2.5
800         */
801        public static Boolean[] nullToEmpty(Boolean[] array) {
802            if (array == null || array.length == 0) {
803                return EMPTY_BOOLEAN_OBJECT_ARRAY;
804            }
805            return array;
806        }
807    
808        // Subarrays
809        //-----------------------------------------------------------------------
810        /**
811         * <p>Produces a new array containing the elements between
812         * the start and end indices.</p>
813         *
814         * <p>The start index is inclusive, the end index exclusive.
815         * Null array input produces null output.</p>
816         *
817         * <p>The component type of the subarray is always the same as
818         * that of the input array. Thus, if the input is an array of type
819         * <code>Date</code>, the following usage is envisaged:</p>
820         *
821         * <pre>
822         * Date[] someDates = (Date[])ArrayUtils.subarray(allDates, 2, 5);
823         * </pre>
824         *
825         * @param array  the array
826         * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
827         *      is promoted to 0, overvalue (&gt;array.length) results
828         *      in an empty array.
829         * @param endIndexExclusive  elements up to endIndex-1 are present in the
830         *      returned subarray. Undervalue (&lt; startIndex) produces
831         *      empty array, overvalue (&gt;array.length) is demoted to
832         *      array length.
833         * @return a new array containing the elements between
834         *      the start and end indices.
835         * @since 2.1
836         */
837        public static <T> T[] subarray(T[] array, int startIndexInclusive, int endIndexExclusive) {
838            if (array == null) {
839                return null;
840            }
841            if (startIndexInclusive < 0) {
842                startIndexInclusive = 0;
843            }
844            if (endIndexExclusive > array.length) {
845                endIndexExclusive = array.length;
846            }
847            int newSize = endIndexExclusive - startIndexInclusive;
848            Class<?> type = array.getClass().getComponentType();
849            if (newSize <= 0) {
850                @SuppressWarnings("unchecked") // OK, because array is of type T
851                final T[] emptyArray = (T[]) Array.newInstance(type, 0);
852                return emptyArray;
853            }
854            @SuppressWarnings("unchecked") // OK, because array is of type T
855            T[] subarray = (T[]) Array.newInstance(type, newSize);
856            System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
857            return subarray;
858        }
859    
860        /**
861         * <p>Produces a new <code>long</code> array containing the elements
862         * between the start and end indices.</p>
863         *
864         * <p>The start index is inclusive, the end index exclusive.
865         * Null array input produces null output.</p>
866         *
867         * @param array  the array
868         * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
869         *      is promoted to 0, overvalue (&gt;array.length) results
870         *      in an empty array.
871         * @param endIndexExclusive  elements up to endIndex-1 are present in the
872         *      returned subarray. Undervalue (&lt; startIndex) produces
873         *      empty array, overvalue (&gt;array.length) is demoted to
874         *      array length.
875         * @return a new array containing the elements between
876         *      the start and end indices.
877         * @since 2.1
878         */
879        public static long[] subarray(long[] array, int startIndexInclusive, int endIndexExclusive) {
880            if (array == null) {
881                return null;
882            }
883            if (startIndexInclusive < 0) {
884                startIndexInclusive = 0;
885            }
886            if (endIndexExclusive > array.length) {
887                endIndexExclusive = array.length;
888            }
889            int newSize = endIndexExclusive - startIndexInclusive;
890            if (newSize <= 0) {
891                return EMPTY_LONG_ARRAY;
892            }
893    
894            long[] subarray = new long[newSize];
895            System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
896            return subarray;
897        }
898    
899        /**
900         * <p>Produces a new <code>int</code> array containing the elements
901         * between the start and end indices.</p>
902         *
903         * <p>The start index is inclusive, the end index exclusive.
904         * Null array input produces null output.</p>
905         *
906         * @param array  the array
907         * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
908         *      is promoted to 0, overvalue (&gt;array.length) results
909         *      in an empty array.
910         * @param endIndexExclusive  elements up to endIndex-1 are present in the
911         *      returned subarray. Undervalue (&lt; startIndex) produces
912         *      empty array, overvalue (&gt;array.length) is demoted to
913         *      array length.
914         * @return a new array containing the elements between
915         *      the start and end indices.
916         * @since 2.1
917         */
918        public static int[] subarray(int[] array, int startIndexInclusive, int endIndexExclusive) {
919            if (array == null) {
920                return null;
921            }
922            if (startIndexInclusive < 0) {
923                startIndexInclusive = 0;
924            }
925            if (endIndexExclusive > array.length) {
926                endIndexExclusive = array.length;
927            }
928            int newSize = endIndexExclusive - startIndexInclusive;
929            if (newSize <= 0) {
930                return EMPTY_INT_ARRAY;
931            }
932    
933            int[] subarray = new int[newSize];
934            System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
935            return subarray;
936        }
937    
938        /**
939         * <p>Produces a new <code>short</code> array containing the elements
940         * between the start and end indices.</p>
941         *
942         * <p>The start index is inclusive, the end index exclusive.
943         * Null array input produces null output.</p>
944         *
945         * @param array  the array
946         * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
947         *      is promoted to 0, overvalue (&gt;array.length) results
948         *      in an empty array.
949         * @param endIndexExclusive  elements up to endIndex-1 are present in the
950         *      returned subarray. Undervalue (&lt; startIndex) produces
951         *      empty array, overvalue (&gt;array.length) is demoted to
952         *      array length.
953         * @return a new array containing the elements between
954         *      the start and end indices.
955         * @since 2.1
956         */
957        public static short[] subarray(short[] array, int startIndexInclusive, int endIndexExclusive) {
958            if (array == null) {
959                return null;
960            }
961            if (startIndexInclusive < 0) {
962                startIndexInclusive = 0;
963            }
964            if (endIndexExclusive > array.length) {
965                endIndexExclusive = array.length;
966            }
967            int newSize = endIndexExclusive - startIndexInclusive;
968            if (newSize <= 0) {
969                return EMPTY_SHORT_ARRAY;
970            }
971    
972            short[] subarray = new short[newSize];
973            System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
974            return subarray;
975        }
976    
977        /**
978         * <p>Produces a new <code>char</code> array containing the elements
979         * between the start and end indices.</p>
980         *
981         * <p>The start index is inclusive, the end index exclusive.
982         * Null array input produces null output.</p>
983         *
984         * @param array  the array
985         * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
986         *      is promoted to 0, overvalue (&gt;array.length) results
987         *      in an empty array.
988         * @param endIndexExclusive  elements up to endIndex-1 are present in the
989         *      returned subarray. Undervalue (&lt; startIndex) produces
990         *      empty array, overvalue (&gt;array.length) is demoted to
991         *      array length.
992         * @return a new array containing the elements between
993         *      the start and end indices.
994         * @since 2.1
995         */
996        public static char[] subarray(char[] array, int startIndexInclusive, int endIndexExclusive) {
997            if (array == null) {
998                return null;
999            }
1000            if (startIndexInclusive < 0) {
1001                startIndexInclusive = 0;
1002            }
1003            if (endIndexExclusive > array.length) {
1004                endIndexExclusive = array.length;
1005            }
1006            int newSize = endIndexExclusive - startIndexInclusive;
1007            if (newSize <= 0) {
1008                return EMPTY_CHAR_ARRAY;
1009            }
1010    
1011            char[] subarray = new char[newSize];
1012            System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
1013            return subarray;
1014        }
1015    
1016        /**
1017         * <p>Produces a new <code>byte</code> array containing the elements
1018         * between the start and end indices.</p>
1019         *
1020         * <p>The start index is inclusive, the end index exclusive.
1021         * Null array input produces null output.</p>
1022         *
1023         * @param array  the array
1024         * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
1025         *      is promoted to 0, overvalue (&gt;array.length) results
1026         *      in an empty array.
1027         * @param endIndexExclusive  elements up to endIndex-1 are present in the
1028         *      returned subarray. Undervalue (&lt; startIndex) produces
1029         *      empty array, overvalue (&gt;array.length) is demoted to
1030         *      array length.
1031         * @return a new array containing the elements between
1032         *      the start and end indices.
1033         * @since 2.1
1034         */
1035        public static byte[] subarray(byte[] array, int startIndexInclusive, int endIndexExclusive) {
1036            if (array == null) {
1037                return null;
1038            }
1039            if (startIndexInclusive < 0) {
1040                startIndexInclusive = 0;
1041            }
1042            if (endIndexExclusive > array.length) {
1043                endIndexExclusive = array.length;
1044            }
1045            int newSize = endIndexExclusive - startIndexInclusive;
1046            if (newSize <= 0) {
1047                return EMPTY_BYTE_ARRAY;
1048            }
1049    
1050            byte[] subarray = new byte[newSize];
1051            System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
1052            return subarray;
1053        }
1054    
1055        /**
1056         * <p>Produces a new <code>double</code> array containing the elements
1057         * between the start and end indices.</p>
1058         *
1059         * <p>The start index is inclusive, the end index exclusive.
1060         * Null array input produces null output.</p>
1061         *
1062         * @param array  the array
1063         * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
1064         *      is promoted to 0, overvalue (&gt;array.length) results
1065         *      in an empty array.
1066         * @param endIndexExclusive  elements up to endIndex-1 are present in the
1067         *      returned subarray. Undervalue (&lt; startIndex) produces
1068         *      empty array, overvalue (&gt;array.length) is demoted to
1069         *      array length.
1070         * @return a new array containing the elements between
1071         *      the start and end indices.
1072         * @since 2.1
1073         */
1074        public static double[] subarray(double[] array, int startIndexInclusive, int endIndexExclusive) {
1075            if (array == null) {
1076                return null;
1077            }
1078            if (startIndexInclusive < 0) {
1079                startIndexInclusive = 0;
1080            }
1081            if (endIndexExclusive > array.length) {
1082                endIndexExclusive = array.length;
1083            }
1084            int newSize = endIndexExclusive - startIndexInclusive;
1085            if (newSize <= 0) {
1086                return EMPTY_DOUBLE_ARRAY;
1087            }
1088    
1089            double[] subarray = new double[newSize];
1090            System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
1091            return subarray;
1092        }
1093    
1094        /**
1095         * <p>Produces a new <code>float</code> array containing the elements
1096         * between the start and end indices.</p>
1097         *
1098         * <p>The start index is inclusive, the end index exclusive.
1099         * Null array input produces null output.</p>
1100         *
1101         * @param array  the array
1102         * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
1103         *      is promoted to 0, overvalue (&gt;array.length) results
1104         *      in an empty array.
1105         * @param endIndexExclusive  elements up to endIndex-1 are present in the
1106         *      returned subarray. Undervalue (&lt; startIndex) produces
1107         *      empty array, overvalue (&gt;array.length) is demoted to
1108         *      array length.
1109         * @return a new array containing the elements between
1110         *      the start and end indices.
1111         * @since 2.1
1112         */
1113        public static float[] subarray(float[] array, int startIndexInclusive, int endIndexExclusive) {
1114            if (array == null) {
1115                return null;
1116            }
1117            if (startIndexInclusive < 0) {
1118                startIndexInclusive = 0;
1119            }
1120            if (endIndexExclusive > array.length) {
1121                endIndexExclusive = array.length;
1122            }
1123            int newSize = endIndexExclusive - startIndexInclusive;
1124            if (newSize <= 0) {
1125                return EMPTY_FLOAT_ARRAY;
1126            }
1127    
1128            float[] subarray = new float[newSize];
1129            System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
1130            return subarray;
1131        }
1132    
1133        /**
1134         * <p>Produces a new <code>boolean</code> array containing the elements
1135         * between the start and end indices.</p>
1136         *
1137         * <p>The start index is inclusive, the end index exclusive.
1138         * Null array input produces null output.</p>
1139         *
1140         * @param array  the array
1141         * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
1142         *      is promoted to 0, overvalue (&gt;array.length) results
1143         *      in an empty array.
1144         * @param endIndexExclusive  elements up to endIndex-1 are present in the
1145         *      returned subarray. Undervalue (&lt; startIndex) produces
1146         *      empty array, overvalue (&gt;array.length) is demoted to
1147         *      array length.
1148         * @return a new array containing the elements between
1149         *      the start and end indices.
1150         * @since 2.1
1151         */
1152        public static boolean[] subarray(boolean[] array, int startIndexInclusive, int endIndexExclusive) {
1153            if (array == null) {
1154                return null;
1155            }
1156            if (startIndexInclusive < 0) {
1157                startIndexInclusive = 0;
1158            }
1159            if (endIndexExclusive > array.length) {
1160                endIndexExclusive = array.length;
1161            }
1162            int newSize = endIndexExclusive - startIndexInclusive;
1163            if (newSize <= 0) {
1164                return EMPTY_BOOLEAN_ARRAY;
1165            }
1166    
1167            boolean[] subarray = new boolean[newSize];
1168            System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
1169            return subarray;
1170        }
1171    
1172        // Is same length
1173        //-----------------------------------------------------------------------
1174        /**
1175         * <p>Checks whether two arrays are the same length, treating
1176         * <code>null</code> arrays as length <code>0</code>.
1177         *
1178         * <p>Any multi-dimensional aspects of the arrays are ignored.</p>
1179         *
1180         * @param array1 the first array, may be <code>null</code>
1181         * @param array2 the second array, may be <code>null</code>
1182         * @return <code>true</code> if length of arrays matches, treating
1183         *  <code>null</code> as an empty array
1184         */
1185        public static boolean isSameLength(Object[] array1, Object[] array2) {
1186            if ((array1 == null && array2 != null && array2.length > 0) ||
1187                (array2 == null && array1 != null && array1.length > 0) ||
1188                (array1 != null && array2 != null && array1.length != array2.length)) {
1189                    return false;
1190            }
1191            return true;
1192        }
1193    
1194        /**
1195         * <p>Checks whether two arrays are the same length, treating
1196         * <code>null</code> arrays as length <code>0</code>.</p>
1197         *
1198         * @param array1 the first array, may be <code>null</code>
1199         * @param array2 the second array, may be <code>null</code>
1200         * @return <code>true</code> if length of arrays matches, treating
1201         *  <code>null</code> as an empty array
1202         */
1203        public static boolean isSameLength(long[] array1, long[] array2) {
1204            if ((array1 == null && array2 != null && array2.length > 0) ||
1205                (array2 == null && array1 != null && array1.length > 0) ||
1206                (array1 != null && array2 != null && array1.length != array2.length)) {
1207                    return false;
1208            }
1209            return true;
1210        }
1211    
1212        /**
1213         * <p>Checks whether two arrays are the same length, treating
1214         * <code>null</code> arrays as length <code>0</code>.</p>
1215         *
1216         * @param array1 the first array, may be <code>null</code>
1217         * @param array2 the second array, may be <code>null</code>
1218         * @return <code>true</code> if length of arrays matches, treating
1219         *  <code>null</code> as an empty array
1220         */
1221        public static boolean isSameLength(int[] array1, int[] array2) {
1222            if ((array1 == null && array2 != null && array2.length > 0) ||
1223                (array2 == null && array1 != null && array1.length > 0) ||
1224                (array1 != null && array2 != null && array1.length != array2.length)) {
1225                    return false;
1226            }
1227            return true;
1228        }
1229    
1230        /**
1231         * <p>Checks whether two arrays are the same length, treating
1232         * <code>null</code> arrays as length <code>0</code>.</p>
1233         *
1234         * @param array1 the first array, may be <code>null</code>
1235         * @param array2 the second array, may be <code>null</code>
1236         * @return <code>true</code> if length of arrays matches, treating
1237         *  <code>null</code> as an empty array
1238         */
1239        public static boolean isSameLength(short[] array1, short[] array2) {
1240            if ((array1 == null && array2 != null && array2.length > 0) ||
1241                (array2 == null && array1 != null && array1.length > 0) ||
1242                (array1 != null && array2 != null && array1.length != array2.length)) {
1243                    return false;
1244            }
1245            return true;
1246        }
1247    
1248        /**
1249         * <p>Checks whether two arrays are the same length, treating
1250         * <code>null</code> arrays as length <code>0</code>.</p>
1251         *
1252         * @param array1 the first array, may be <code>null</code>
1253         * @param array2 the second array, may be <code>null</code>
1254         * @return <code>true</code> if length of arrays matches, treating
1255         *  <code>null</code> as an empty array
1256         */
1257        public static boolean isSameLength(char[] array1, char[] array2) {
1258            if ((array1 == null && array2 != null && array2.length > 0) ||
1259                (array2 == null && array1 != null && array1.length > 0) ||
1260                (array1 != null && array2 != null && array1.length != array2.length)) {
1261                    return false;
1262            }
1263            return true;
1264        }
1265    
1266        /**
1267         * <p>Checks whether two arrays are the same length, treating
1268         * <code>null</code> arrays as length <code>0</code>.</p>
1269         *
1270         * @param array1 the first array, may be <code>null</code>
1271         * @param array2 the second array, may be <code>null</code>
1272         * @return <code>true</code> if length of arrays matches, treating
1273         *  <code>null</code> as an empty array
1274         */
1275        public static boolean isSameLength(byte[] array1, byte[] array2) {
1276            if ((array1 == null && array2 != null && array2.length > 0) ||
1277                (array2 == null && array1 != null && array1.length > 0) ||
1278                (array1 != null && array2 != null && array1.length != array2.length)) {
1279                    return false;
1280            }
1281            return true;
1282        }
1283    
1284        /**
1285         * <p>Checks whether two arrays are the same length, treating
1286         * <code>null</code> arrays as length <code>0</code>.</p>
1287         *
1288         * @param array1 the first array, may be <code>null</code>
1289         * @param array2 the second array, may be <code>null</code>
1290         * @return <code>true</code> if length of arrays matches, treating
1291         *  <code>null</code> as an empty array
1292         */
1293        public static boolean isSameLength(double[] array1, double[] array2) {
1294            if ((array1 == null && array2 != null && array2.length > 0) ||
1295                (array2 == null && array1 != null && array1.length > 0) ||
1296                (array1 != null && array2 != null && array1.length != array2.length)) {
1297                    return false;
1298            }
1299            return true;
1300        }
1301    
1302        /**
1303         * <p>Checks whether two arrays are the same length, treating
1304         * <code>null</code> arrays as length <code>0</code>.</p>
1305         *
1306         * @param array1 the first array, may be <code>null</code>
1307         * @param array2 the second array, may be <code>null</code>
1308         * @return <code>true</code> if length of arrays matches, treating
1309         *  <code>null</code> as an empty array
1310         */
1311        public static boolean isSameLength(float[] array1, float[] array2) {
1312            if ((array1 == null && array2 != null && array2.length > 0) ||
1313                (array2 == null && array1 != null && array1.length > 0) ||
1314                (array1 != null && array2 != null && array1.length != array2.length)) {
1315                    return false;
1316            }
1317            return true;
1318        }
1319    
1320        /**
1321         * <p>Checks whether two arrays are the same length, treating
1322         * <code>null</code> arrays as length <code>0</code>.</p>
1323         *
1324         * @param array1 the first array, may be <code>null</code>
1325         * @param array2 the second array, may be <code>null</code>
1326         * @return <code>true</code> if length of arrays matches, treating
1327         *  <code>null</code> as an empty array
1328         */
1329        public static boolean isSameLength(boolean[] array1, boolean[] array2) {
1330            if ((array1 == null && array2 != null && array2.length > 0) ||
1331                (array2 == null && array1 != null && array1.length > 0) ||
1332                (array1 != null && array2 != null && array1.length != array2.length)) {
1333                    return false;
1334            }
1335            return true;
1336        }
1337    
1338        //-----------------------------------------------------------------------
1339        /**
1340         * <p>Returns the length of the specified array.
1341         * This method can deal with <code>Object</code> arrays and with primitive arrays.</p>
1342         *
1343         * <p>If the input array is <code>null</code>, <code>0</code> is returned.</p>
1344         *
1345         * <pre>
1346         * ArrayUtils.getLength(null)            = 0
1347         * ArrayUtils.getLength([])              = 0
1348         * ArrayUtils.getLength([null])          = 1
1349         * ArrayUtils.getLength([true, false])   = 2
1350         * ArrayUtils.getLength([1, 2, 3])       = 3
1351         * ArrayUtils.getLength(["a", "b", "c"]) = 3
1352         * </pre>
1353         *
1354         * @param array  the array to retrieve the length from, may be null
1355         * @return The length of the array, or <code>0</code> if the array is <code>null</code>
1356         * @throws IllegalArgumentException if the object arguement is not an array.
1357         * @since 2.1
1358         */
1359        public static int getLength(Object array) {
1360            if (array == null) {
1361                return 0;
1362            }
1363            return Array.getLength(array);
1364        }
1365    
1366        /**
1367         * <p>Checks whether two arrays are the same type taking into account
1368         * multi-dimensional arrays.</p>
1369         *
1370         * @param array1 the first array, must not be <code>null</code>
1371         * @param array2 the second array, must not be <code>null</code>
1372         * @return <code>true</code> if type of arrays matches
1373         * @throws IllegalArgumentException if either array is <code>null</code>
1374         */
1375        public static boolean isSameType(Object array1, Object array2) {
1376            if (array1 == null || array2 == null) {
1377                throw new IllegalArgumentException("The Array must not be null");
1378            }
1379            return array1.getClass().getName().equals(array2.getClass().getName());
1380        }
1381    
1382        // Reverse
1383        //-----------------------------------------------------------------------
1384        /**
1385         * <p>Reverses the order of the given array.</p>
1386         *
1387         * <p>There is no special handling for multi-dimensional arrays.</p>
1388         *
1389         * <p>This method does nothing for a <code>null</code> input array.</p>
1390         *
1391         * @param array  the array to reverse, may be <code>null</code>
1392         */
1393        public static void reverse(Object[] array) {
1394            if (array == null) {
1395                return;
1396            }
1397            int i = 0;
1398            int j = array.length - 1;
1399            Object tmp;
1400            while (j > i) {
1401                tmp = array[j];
1402                array[j] = array[i];
1403                array[i] = tmp;
1404                j--;
1405                i++;
1406            }
1407        }
1408    
1409        /**
1410         * <p>Reverses the order of the given array.</p>
1411         *
1412         * <p>This method does nothing for a <code>null</code> input array.</p>
1413         *
1414         * @param array  the array to reverse, may be <code>null</code>
1415         */
1416        public static void reverse(long[] array) {
1417            if (array == null) {
1418                return;
1419            }
1420            int i = 0;
1421            int j = array.length - 1;
1422            long tmp;
1423            while (j > i) {
1424                tmp = array[j];
1425                array[j] = array[i];
1426                array[i] = tmp;
1427                j--;
1428                i++;
1429            }
1430        }
1431    
1432        /**
1433         * <p>Reverses the order of the given array.</p>
1434         *
1435         * <p>This method does nothing for a <code>null</code> input array.</p>
1436         *
1437         * @param array  the array to reverse, may be <code>null</code>
1438         */
1439        public static void reverse(int[] array) {
1440            if (array == null) {
1441                return;
1442            }
1443            int i = 0;
1444            int j = array.length - 1;
1445            int tmp;
1446            while (j > i) {
1447                tmp = array[j];
1448                array[j] = array[i];
1449                array[i] = tmp;
1450                j--;
1451                i++;
1452            }
1453        }
1454    
1455        /**
1456         * <p>Reverses the order of the given array.</p>
1457         *
1458         * <p>This method does nothing for a <code>null</code> input array.</p>
1459         *
1460         * @param array  the array to reverse, may be <code>null</code>
1461         */
1462        public static void reverse(short[] array) {
1463            if (array == null) {
1464                return;
1465            }
1466            int i = 0;
1467            int j = array.length - 1;
1468            short tmp;
1469            while (j > i) {
1470                tmp = array[j];
1471                array[j] = array[i];
1472                array[i] = tmp;
1473                j--;
1474                i++;
1475            }
1476        }
1477    
1478        /**
1479         * <p>Reverses the order of the given array.</p>
1480         *
1481         * <p>This method does nothing for a <code>null</code> input array.</p>
1482         *
1483         * @param array  the array to reverse, may be <code>null</code>
1484         */
1485        public static void reverse(char[] array) {
1486            if (array == null) {
1487                return;
1488            }
1489            int i = 0;
1490            int j = array.length - 1;
1491            char tmp;
1492            while (j > i) {
1493                tmp = array[j];
1494                array[j] = array[i];
1495                array[i] = tmp;
1496                j--;
1497                i++;
1498            }
1499        }
1500    
1501        /**
1502         * <p>Reverses the order of the given array.</p>
1503         *
1504         * <p>This method does nothing for a <code>null</code> input array.</p>
1505         *
1506         * @param array  the array to reverse, may be <code>null</code>
1507         */
1508        public static void reverse(byte[] array) {
1509            if (array == null) {
1510                return;
1511            }
1512            int i = 0;
1513            int j = array.length - 1;
1514            byte tmp;
1515            while (j > i) {
1516                tmp = array[j];
1517                array[j] = array[i];
1518                array[i] = tmp;
1519                j--;
1520                i++;
1521            }
1522        }
1523    
1524        /**
1525         * <p>Reverses the order of the given array.</p>
1526         *
1527         * <p>This method does nothing for a <code>null</code> input array.</p>
1528         *
1529         * @param array  the array to reverse, may be <code>null</code>
1530         */
1531        public static void reverse(double[] array) {
1532            if (array == null) {
1533                return;
1534            }
1535            int i = 0;
1536            int j = array.length - 1;
1537            double tmp;
1538            while (j > i) {
1539                tmp = array[j];
1540                array[j] = array[i];
1541                array[i] = tmp;
1542                j--;
1543                i++;
1544            }
1545        }
1546    
1547        /**
1548         * <p>Reverses the order of the given array.</p>
1549         *
1550         * <p>This method does nothing for a <code>null</code> input array.</p>
1551         *
1552         * @param array  the array to reverse, may be <code>null</code>
1553         */
1554        public static void reverse(float[] array) {
1555            if (array == null) {
1556                return;
1557            }
1558            int i = 0;
1559            int j = array.length - 1;
1560            float tmp;
1561            while (j > i) {
1562                tmp = array[j];
1563                array[j] = array[i];
1564                array[i] = tmp;
1565                j--;
1566                i++;
1567            }
1568        }
1569    
1570        /**
1571         * <p>Reverses the order of the given array.</p>
1572         *
1573         * <p>This method does nothing for a <code>null</code> input array.</p>
1574         *
1575         * @param array  the array to reverse, may be <code>null</code>
1576         */
1577        public static void reverse(boolean[] array) {
1578            if (array == null) {
1579                return;
1580            }
1581            int i = 0;
1582            int j = array.length - 1;
1583            boolean tmp;
1584            while (j > i) {
1585                tmp = array[j];
1586                array[j] = array[i];
1587                array[i] = tmp;
1588                j--;
1589                i++;
1590            }
1591        }
1592    
1593        // IndexOf search
1594        // ----------------------------------------------------------------------
1595    
1596        // Object IndexOf
1597        //-----------------------------------------------------------------------
1598        /**
1599         * <p>Finds the index of the given object in the array.</p>
1600         *
1601         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1602         *
1603         * @param array  the array to search through for the object, may be <code>null</code>
1604         * @param objectToFind  the object to find, may be <code>null</code>
1605         * @return the index of the object within the array,
1606         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1607         */
1608        public static int indexOf(Object[] array, Object objectToFind) {
1609            return indexOf(array, objectToFind, 0);
1610        }
1611    
1612        /**
1613         * <p>Finds the index of the given object in the array starting at the given index.</p>
1614         *
1615         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1616         *
1617         * <p>A negative startIndex is treated as zero. A startIndex larger than the array
1618         * length will return {@link #INDEX_NOT_FOUND} (<code>-1</code>).</p>
1619         *
1620         * @param array  the array to search through for the object, may be <code>null</code>
1621         * @param objectToFind  the object to find, may be <code>null</code>
1622         * @param startIndex  the index to start searching at
1623         * @return the index of the object within the array starting at the index,
1624         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1625         */
1626        public static int indexOf(Object[] array, Object objectToFind, int startIndex) {
1627            if (array == null) {
1628                return INDEX_NOT_FOUND;
1629            }
1630            if (startIndex < 0) {
1631                startIndex = 0;
1632            }
1633            if (objectToFind == null) {
1634                for (int i = startIndex; i < array.length; i++) {
1635                    if (array[i] == null) {
1636                        return i;
1637                    }
1638                }
1639            } else if (array.getClass().getComponentType().isInstance(objectToFind)) {
1640                for (int i = startIndex; i < array.length; i++) {
1641                    if (objectToFind.equals(array[i])) {
1642                        return i;
1643                    }
1644                }
1645            }
1646            return INDEX_NOT_FOUND;
1647        }
1648    
1649        /**
1650         * <p>Finds the last index of the given object within the array.</p>
1651         *
1652         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1653         *
1654         * @param array  the array to travers backwords looking for the object, may be <code>null</code>
1655         * @param objectToFind  the object to find, may be <code>null</code>
1656         * @return the last index of the object within the array,
1657         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1658         */
1659        public static int lastIndexOf(Object[] array, Object objectToFind) {
1660            return lastIndexOf(array, objectToFind, Integer.MAX_VALUE);
1661        }
1662    
1663        /**
1664         * <p>Finds the last index of the given object in the array starting at the given index.</p>
1665         *
1666         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1667         *
1668         * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} (<code>-1</code>). A startIndex larger than
1669         * the array length will search from the end of the array.</p>
1670         *
1671         * @param array  the array to traverse for looking for the object, may be <code>null</code>
1672         * @param objectToFind  the object to find, may be <code>null</code>
1673         * @param startIndex  the start index to travers backwards from
1674         * @return the last index of the object within the array,
1675         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1676         */
1677        public static int lastIndexOf(Object[] array, Object objectToFind, int startIndex) {
1678            if (array == null) {
1679                return INDEX_NOT_FOUND;
1680            }
1681            if (startIndex < 0) {
1682                return INDEX_NOT_FOUND;
1683            } else if (startIndex >= array.length) {
1684                startIndex = array.length - 1;
1685            }
1686            if (objectToFind == null) {
1687                for (int i = startIndex; i >= 0; i--) {
1688                    if (array[i] == null) {
1689                        return i;
1690                    }
1691                }
1692            } else if (array.getClass().getComponentType().isInstance(objectToFind)) {
1693                for (int i = startIndex; i >= 0; i--) {
1694                    if (objectToFind.equals(array[i])) {
1695                        return i;
1696                    }
1697                }
1698            }
1699            return INDEX_NOT_FOUND;
1700        }
1701    
1702        /**
1703         * <p>Checks if the object is in the given array.</p>
1704         *
1705         * <p>The method returns <code>false</code> if a <code>null</code> array is passed in.</p>
1706         *
1707         * @param array  the array to search through
1708         * @param objectToFind  the object to find
1709         * @return <code>true</code> if the array contains the object
1710         */
1711        public static boolean contains(Object[] array, Object objectToFind) {
1712            return indexOf(array, objectToFind) != INDEX_NOT_FOUND;
1713        }
1714    
1715        // long IndexOf
1716        //-----------------------------------------------------------------------
1717        /**
1718         * <p>Finds the index of the given value in the array.</p>
1719         *
1720         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1721         *
1722         * @param array  the array to search through for the object, may be <code>null</code>
1723         * @param valueToFind  the value to find
1724         * @return the index of the value within the array,
1725         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1726         */
1727        public static int indexOf(long[] array, long valueToFind) {
1728            return indexOf(array, valueToFind, 0);
1729        }
1730    
1731        /**
1732         * <p>Finds the index of the given value in the array starting at the given index.</p>
1733         *
1734         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1735         *
1736         * <p>A negative startIndex is treated as zero. A startIndex larger than the array
1737         * length will return {@link #INDEX_NOT_FOUND} (<code>-1</code>).</p>
1738         *
1739         * @param array  the array to search through for the object, may be <code>null</code>
1740         * @param valueToFind  the value to find
1741         * @param startIndex  the index to start searching at
1742         * @return the index of the value within the array,
1743         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1744         */
1745        public static int indexOf(long[] array, long valueToFind, int startIndex) {
1746            if (array == null) {
1747                return INDEX_NOT_FOUND;
1748            }
1749            if (startIndex < 0) {
1750                startIndex = 0;
1751            }
1752            for (int i = startIndex; i < array.length; i++) {
1753                if (valueToFind == array[i]) {
1754                    return i;
1755                }
1756            }
1757            return INDEX_NOT_FOUND;
1758        }
1759    
1760        /**
1761         * <p>Finds the last index of the given value within the array.</p>
1762         *
1763         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1764         *
1765         * @param array  the array to travers backwords looking for the object, may be <code>null</code>
1766         * @param valueToFind  the object to find
1767         * @return the last index of the value within the array,
1768         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1769         */
1770        public static int lastIndexOf(long[] array, long valueToFind) {
1771            return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
1772        }
1773    
1774        /**
1775         * <p>Finds the last index of the given value in the array starting at the given index.</p>
1776         *
1777         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1778         *
1779         * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} (<code>-1</code>). A startIndex larger than the
1780         * array length will search from the end of the array.</p>
1781         *
1782         * @param array  the array to traverse for looking for the object, may be <code>null</code>
1783         * @param valueToFind  the value to find
1784         * @param startIndex  the start index to travers backwards from
1785         * @return the last index of the value within the array,
1786         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1787         */
1788        public static int lastIndexOf(long[] array, long valueToFind, int startIndex) {
1789            if (array == null) {
1790                return INDEX_NOT_FOUND;
1791            }
1792            if (startIndex < 0) {
1793                return INDEX_NOT_FOUND;
1794            } else if (startIndex >= array.length) {
1795                startIndex = array.length - 1;
1796            }
1797            for (int i = startIndex; i >= 0; i--) {
1798                if (valueToFind == array[i]) {
1799                    return i;
1800                }
1801            }
1802            return INDEX_NOT_FOUND;
1803        }
1804    
1805        /**
1806         * <p>Checks if the value is in the given array.</p>
1807         *
1808         * <p>The method returns <code>false</code> if a <code>null</code> array is passed in.</p>
1809         *
1810         * @param array  the array to search through
1811         * @param valueToFind  the value to find
1812         * @return <code>true</code> if the array contains the object
1813         */
1814        public static boolean contains(long[] array, long valueToFind) {
1815            return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
1816        }
1817    
1818        // int IndexOf
1819        //-----------------------------------------------------------------------
1820        /**
1821         * <p>Finds the index of the given value in the array.</p>
1822         *
1823         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1824         *
1825         * @param array  the array to search through for the object, may be <code>null</code>
1826         * @param valueToFind  the value to find
1827         * @return the index of the value within the array,
1828         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1829         */
1830        public static int indexOf(int[] array, int valueToFind) {
1831            return indexOf(array, valueToFind, 0);
1832        }
1833    
1834        /**
1835         * <p>Finds the index of the given value in the array starting at the given index.</p>
1836         *
1837         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1838         *
1839         * <p>A negative startIndex is treated as zero. A startIndex larger than the array
1840         * length will return {@link #INDEX_NOT_FOUND} (<code>-1</code>).</p>
1841         *
1842         * @param array  the array to search through for the object, may be <code>null</code>
1843         * @param valueToFind  the value to find
1844         * @param startIndex  the index to start searching at
1845         * @return the index of the value within the array,
1846         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1847         */
1848        public static int indexOf(int[] array, int valueToFind, int startIndex) {
1849            if (array == null) {
1850                return INDEX_NOT_FOUND;
1851            }
1852            if (startIndex < 0) {
1853                startIndex = 0;
1854            }
1855            for (int i = startIndex; i < array.length; i++) {
1856                if (valueToFind == array[i]) {
1857                    return i;
1858                }
1859            }
1860            return INDEX_NOT_FOUND;
1861        }
1862    
1863        /**
1864         * <p>Finds the last index of the given value within the array.</p>
1865         *
1866         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1867         *
1868         * @param array  the array to travers backwords looking for the object, may be <code>null</code>
1869         * @param valueToFind  the object to find
1870         * @return the last index of the value within the array,
1871         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1872         */
1873        public static int lastIndexOf(int[] array, int valueToFind) {
1874            return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
1875        }
1876    
1877        /**
1878         * <p>Finds the last index of the given value in the array starting at the given index.</p>
1879         *
1880         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1881         *
1882         * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} (<code>-1</code>). A startIndex larger than the
1883         * array length will search from the end of the array.</p>
1884         *
1885         * @param array  the array to traverse for looking for the object, may be <code>null</code>
1886         * @param valueToFind  the value to find
1887         * @param startIndex  the start index to travers backwards from
1888         * @return the last index of the value within the array,
1889         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1890         */
1891        public static int lastIndexOf(int[] array, int valueToFind, int startIndex) {
1892            if (array == null) {
1893                return INDEX_NOT_FOUND;
1894            }
1895            if (startIndex < 0) {
1896                return INDEX_NOT_FOUND;
1897            } else if (startIndex >= array.length) {
1898                startIndex = array.length - 1;
1899            }
1900            for (int i = startIndex; i >= 0; i--) {
1901                if (valueToFind == array[i]) {
1902                    return i;
1903                }
1904            }
1905            return INDEX_NOT_FOUND;
1906        }
1907    
1908        /**
1909         * <p>Checks if the value is in the given array.</p>
1910         *
1911         * <p>The method returns <code>false</code> if a <code>null</code> array is passed in.</p>
1912         *
1913         * @param array  the array to search through
1914         * @param valueToFind  the value to find
1915         * @return <code>true</code> if the array contains the object
1916         */
1917        public static boolean contains(int[] array, int valueToFind) {
1918            return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
1919        }
1920    
1921        // short IndexOf
1922        //-----------------------------------------------------------------------
1923        /**
1924         * <p>Finds the index of the given value in the array.</p>
1925         *
1926         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1927         *
1928         * @param array  the array to search through for the object, may be <code>null</code>
1929         * @param valueToFind  the value to find
1930         * @return the index of the value within the array,
1931         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1932         */
1933        public static int indexOf(short[] array, short valueToFind) {
1934            return indexOf(array, valueToFind, 0);
1935        }
1936    
1937        /**
1938         * <p>Finds the index of the given value in the array starting at the given index.</p>
1939         *
1940         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1941         *
1942         * <p>A negative startIndex is treated as zero. A startIndex larger than the array
1943         * length will return {@link #INDEX_NOT_FOUND} (<code>-1</code>).</p>
1944         *
1945         * @param array  the array to search through for the object, may be <code>null</code>
1946         * @param valueToFind  the value to find
1947         * @param startIndex  the index to start searching at
1948         * @return the index of the value within the array,
1949         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1950         */
1951        public static int indexOf(short[] array, short valueToFind, int startIndex) {
1952            if (array == null) {
1953                return INDEX_NOT_FOUND;
1954            }
1955            if (startIndex < 0) {
1956                startIndex = 0;
1957            }
1958            for (int i = startIndex; i < array.length; i++) {
1959                if (valueToFind == array[i]) {
1960                    return i;
1961                }
1962            }
1963            return INDEX_NOT_FOUND;
1964        }
1965    
1966        /**
1967         * <p>Finds the last index of the given value within the array.</p>
1968         *
1969         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1970         *
1971         * @param array  the array to travers backwords looking for the object, may be <code>null</code>
1972         * @param valueToFind  the object to find
1973         * @return the last index of the value within the array,
1974         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1975         */
1976        public static int lastIndexOf(short[] array, short valueToFind) {
1977            return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
1978        }
1979    
1980        /**
1981         * <p>Finds the last index of the given value in the array starting at the given index.</p>
1982         *
1983         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1984         *
1985         * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} (<code>-1</code>). A startIndex larger than the
1986         * array length will search from the end of the array.</p>
1987         *
1988         * @param array  the array to traverse for looking for the object, may be <code>null</code>
1989         * @param valueToFind  the value to find
1990         * @param startIndex  the start index to travers backwards from
1991         * @return the last index of the value within the array,
1992         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1993         */
1994        public static int lastIndexOf(short[] array, short valueToFind, int startIndex) {
1995            if (array == null) {
1996                return INDEX_NOT_FOUND;
1997            }
1998            if (startIndex < 0) {
1999                return INDEX_NOT_FOUND;
2000            } else if (startIndex >= array.length) {
2001                startIndex = array.length - 1;
2002            }
2003            for (int i = startIndex; i >= 0; i--) {
2004                if (valueToFind == array[i]) {
2005                    return i;
2006                }
2007            }
2008            return INDEX_NOT_FOUND;
2009        }
2010    
2011        /**
2012         * <p>Checks if the value is in the given array.</p>
2013         *
2014         * <p>The method returns <code>false</code> if a <code>null</code> array is passed in.</p>
2015         *
2016         * @param array  the array to search through
2017         * @param valueToFind  the value to find
2018         * @return <code>true</code> if the array contains the object
2019         */
2020        public static boolean contains(short[] array, short valueToFind) {
2021            return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2022        }
2023    
2024        // char IndexOf
2025        //-----------------------------------------------------------------------
2026        /**
2027         * <p>Finds the index of the given value in the array.</p>
2028         *
2029         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2030         *
2031         * @param array  the array to search through for the object, may be <code>null</code>
2032         * @param valueToFind  the value to find
2033         * @return the index of the value within the array,
2034         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2035         * @since 2.1
2036         */
2037        public static int indexOf(char[] array, char valueToFind) {
2038            return indexOf(array, valueToFind, 0);
2039        }
2040    
2041        /**
2042         * <p>Finds the index of the given value in the array starting at the given index.</p>
2043         *
2044         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2045         *
2046         * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2047         * length will return {@link #INDEX_NOT_FOUND} (<code>-1</code>).</p>
2048         *
2049         * @param array  the array to search through for the object, may be <code>null</code>
2050         * @param valueToFind  the value to find
2051         * @param startIndex  the index to start searching at
2052         * @return the index of the value within the array,
2053         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2054         * @since 2.1
2055         */
2056        public static int indexOf(char[] array, char valueToFind, int startIndex) {
2057            if (array == null) {
2058                return INDEX_NOT_FOUND;
2059            }
2060            if (startIndex < 0) {
2061                startIndex = 0;
2062            }
2063            for (int i = startIndex; i < array.length; i++) {
2064                if (valueToFind == array[i]) {
2065                    return i;
2066                }
2067            }
2068            return INDEX_NOT_FOUND;
2069        }
2070    
2071        /**
2072         * <p>Finds the last index of the given value within the array.</p>
2073         *
2074         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2075         *
2076         * @param array  the array to travers backwords looking for the object, may be <code>null</code>
2077         * @param valueToFind  the object to find
2078         * @return the last index of the value within the array,
2079         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2080         * @since 2.1
2081         */
2082        public static int lastIndexOf(char[] array, char valueToFind) {
2083            return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
2084        }
2085    
2086        /**
2087         * <p>Finds the last index of the given value in the array starting at the given index.</p>
2088         *
2089         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2090         *
2091         * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} (<code>-1</code>). A startIndex larger than the
2092         * array length will search from the end of the array.</p>
2093         *
2094         * @param array  the array to traverse for looking for the object, may be <code>null</code>
2095         * @param valueToFind  the value to find
2096         * @param startIndex  the start index to travers backwards from
2097         * @return the last index of the value within the array,
2098         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2099         * @since 2.1
2100         */
2101        public static int lastIndexOf(char[] array, char valueToFind, int startIndex) {
2102            if (array == null) {
2103                return INDEX_NOT_FOUND;
2104            }
2105            if (startIndex < 0) {
2106                return INDEX_NOT_FOUND;
2107            } else if (startIndex >= array.length) {
2108                startIndex = array.length - 1;
2109            }
2110            for (int i = startIndex; i >= 0; i--) {
2111                if (valueToFind == array[i]) {
2112                    return i;
2113                }
2114            }
2115            return INDEX_NOT_FOUND;
2116        }
2117    
2118        /**
2119         * <p>Checks if the value is in the given array.</p>
2120         *
2121         * <p>The method returns <code>false</code> if a <code>null</code> array is passed in.</p>
2122         *
2123         * @param array  the array to search through
2124         * @param valueToFind  the value to find
2125         * @return <code>true</code> if the array contains the object
2126         * @since 2.1
2127         */
2128        public static boolean contains(char[] array, char valueToFind) {
2129            return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2130        }
2131    
2132        // byte IndexOf
2133        //-----------------------------------------------------------------------
2134        /**
2135         * <p>Finds the index of the given value in the array.</p>
2136         *
2137         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2138         *
2139         * @param array  the array to search through for the object, may be <code>null</code>
2140         * @param valueToFind  the value to find
2141         * @return the index of the value within the array,
2142         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2143         */
2144        public static int indexOf(byte[] array, byte valueToFind) {
2145            return indexOf(array, valueToFind, 0);
2146        }
2147    
2148        /**
2149         * <p>Finds the index of the given value in the array starting at the given index.</p>
2150         *
2151         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2152         *
2153         * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2154         * length will return {@link #INDEX_NOT_FOUND} (<code>-1</code>).</p>
2155         *
2156         * @param array  the array to search through for the object, may be <code>null</code>
2157         * @param valueToFind  the value to find
2158         * @param startIndex  the index to start searching at
2159         * @return the index of the value within the array,
2160         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2161         */
2162        public static int indexOf(byte[] array, byte valueToFind, int startIndex) {
2163            if (array == null) {
2164                return INDEX_NOT_FOUND;
2165            }
2166            if (startIndex < 0) {
2167                startIndex = 0;
2168            }
2169            for (int i = startIndex; i < array.length; i++) {
2170                if (valueToFind == array[i]) {
2171                    return i;
2172                }
2173            }
2174            return INDEX_NOT_FOUND;
2175        }
2176    
2177        /**
2178         * <p>Finds the last index of the given value within the array.</p>
2179         *
2180         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2181         *
2182         * @param array  the array to travers backwords looking for the object, may be <code>null</code>
2183         * @param valueToFind  the object to find
2184         * @return the last index of the value within the array,
2185         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2186         */
2187        public static int lastIndexOf(byte[] array, byte valueToFind) {
2188            return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
2189        }
2190    
2191        /**
2192         * <p>Finds the last index of the given value in the array starting at the given index.</p>
2193         *
2194         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2195         *
2196         * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} (<code>-1</code>). A startIndex larger than the
2197         * array length will search from the end of the array.</p>
2198         *
2199         * @param array  the array to traverse for looking for the object, may be <code>null</code>
2200         * @param valueToFind  the value to find
2201         * @param startIndex  the start index to travers backwards from
2202         * @return the last index of the value within the array,
2203         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2204         */
2205        public static int lastIndexOf(byte[] array, byte valueToFind, int startIndex) {
2206            if (array == null) {
2207                return INDEX_NOT_FOUND;
2208            }
2209            if (startIndex < 0) {
2210                return INDEX_NOT_FOUND;
2211            } else if (startIndex >= array.length) {
2212                startIndex = array.length - 1;
2213            }
2214            for (int i = startIndex; i >= 0; i--) {
2215                if (valueToFind == array[i]) {
2216                    return i;
2217                }
2218            }
2219            return INDEX_NOT_FOUND;
2220        }
2221    
2222        /**
2223         * <p>Checks if the value is in the given array.</p>
2224         *
2225         * <p>The method returns <code>false</code> if a <code>null</code> array is passed in.</p>
2226         *
2227         * @param array  the array to search through
2228         * @param valueToFind  the value to find
2229         * @return <code>true</code> if the array contains the object
2230         */
2231        public static boolean contains(byte[] array, byte valueToFind) {
2232            return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2233        }
2234    
2235        // double IndexOf
2236        //-----------------------------------------------------------------------
2237        /**
2238         * <p>Finds the index of the given value in the array.</p>
2239         *
2240         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2241         *
2242         * @param array  the array to search through for the object, may be <code>null</code>
2243         * @param valueToFind  the value to find
2244         * @return the index of the value within the array,
2245         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2246         */
2247        public static int indexOf(double[] array, double valueToFind) {
2248            return indexOf(array, valueToFind, 0);
2249        }
2250    
2251        /**
2252         * <p>Finds the index of the given value within a given tolerance in the array.
2253         * This method will return the index of the first value which falls between the region
2254         * defined by valueToFind - tolerance and valueToFind + tolerance.</p>
2255         *
2256         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2257         *
2258         * @param array  the array to search through for the object, may be <code>null</code>
2259         * @param valueToFind  the value to find
2260         * @param tolerance tolerance of the search
2261         * @return the index of the value within the array,
2262         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2263         */
2264        public static int indexOf(double[] array, double valueToFind, double tolerance) {
2265            return indexOf(array, valueToFind, 0, tolerance);
2266        }
2267    
2268        /**
2269         * <p>Finds the index of the given value in the array starting at the given index.</p>
2270         *
2271         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2272         *
2273         * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2274         * length will return {@link #INDEX_NOT_FOUND} (<code>-1</code>).</p>
2275         *
2276         * @param array  the array to search through for the object, may be <code>null</code>
2277         * @param valueToFind  the value to find
2278         * @param startIndex  the index to start searching at
2279         * @return the index of the value within the array,
2280         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2281         */
2282        public static int indexOf(double[] array, double valueToFind, int startIndex) {
2283            if (ArrayUtils.isEmpty(array)) {
2284                return INDEX_NOT_FOUND;
2285            }
2286            if (startIndex < 0) {
2287                startIndex = 0;
2288            }
2289            for (int i = startIndex; i < array.length; i++) {
2290                if (valueToFind == array[i]) {
2291                    return i;
2292                }
2293            }
2294            return INDEX_NOT_FOUND;
2295        }
2296    
2297        /**
2298         * <p>Finds the index of the given value in the array starting at the given index.
2299         * This method will return the index of the first value which falls between the region
2300         * defined by valueToFind - tolerance and valueToFind + tolerance.</p>
2301         *
2302         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2303         *
2304         * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2305         * length will return {@link #INDEX_NOT_FOUND} (<code>-1</code>).</p>
2306         *
2307         * @param array  the array to search through for the object, may be <code>null</code>
2308         * @param valueToFind  the value to find
2309         * @param startIndex  the index to start searching at
2310         * @param tolerance tolerance of the search
2311         * @return the index of the value within the array,
2312         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2313         */
2314        public static int indexOf(double[] array, double valueToFind, int startIndex, double tolerance) {
2315            if (ArrayUtils.isEmpty(array)) {
2316                return INDEX_NOT_FOUND;
2317            }
2318            if (startIndex < 0) {
2319                startIndex = 0;
2320            }
2321            double min = valueToFind - tolerance;
2322            double max = valueToFind + tolerance;
2323            for (int i = startIndex; i < array.length; i++) {
2324                if (array[i] >= min && array[i] <= max) {
2325                    return i;
2326                }
2327            }
2328            return INDEX_NOT_FOUND;
2329        }
2330    
2331        /**
2332         * <p>Finds the last index of the given value within the array.</p>
2333         *
2334         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2335         *
2336         * @param array  the array to travers backwords looking for the object, may be <code>null</code>
2337         * @param valueToFind  the object to find
2338         * @return the last index of the value within the array,
2339         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2340         */
2341        public static int lastIndexOf(double[] array, double valueToFind) {
2342            return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
2343        }
2344    
2345        /**
2346         * <p>Finds the last index of the given value within a given tolerance in the array.
2347         * This method will return the index of the last value which falls between the region
2348         * defined by valueToFind - tolerance and valueToFind + tolerance.</p>
2349         *
2350         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2351         *
2352         * @param array  the array to search through for the object, may be <code>null</code>
2353         * @param valueToFind  the value to find
2354         * @param tolerance tolerance of the search
2355         * @return the index of the value within the array,
2356         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2357         */
2358        public static int lastIndexOf(double[] array, double valueToFind, double tolerance) {
2359            return lastIndexOf(array, valueToFind, Integer.MAX_VALUE, tolerance);
2360        }
2361    
2362        /**
2363         * <p>Finds the last index of the given value in the array starting at the given index.</p>
2364         *
2365         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2366         *
2367         * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} (<code>-1</code>). A startIndex larger than the
2368         * array length will search from the end of the array.</p>
2369         *
2370         * @param array  the array to traverse for looking for the object, may be <code>null</code>
2371         * @param valueToFind  the value to find
2372         * @param startIndex  the start index to travers backwards from
2373         * @return the last index of the value within the array,
2374         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2375         */
2376        public static int lastIndexOf(double[] array, double valueToFind, int startIndex) {
2377            if (ArrayUtils.isEmpty(array)) {
2378                return INDEX_NOT_FOUND;
2379            }
2380            if (startIndex < 0) {
2381                return INDEX_NOT_FOUND;
2382            } else if (startIndex >= array.length) {
2383                startIndex = array.length - 1;
2384            }
2385            for (int i = startIndex; i >= 0; i--) {
2386                if (valueToFind == array[i]) {
2387                    return i;
2388                }
2389            }
2390            return INDEX_NOT_FOUND;
2391        }
2392    
2393        /**
2394         * <p>Finds the last index of the given value in the array starting at the given index.
2395         * This method will return the index of the last value which falls between the region
2396         * defined by valueToFind - tolerance and valueToFind + tolerance.</p>
2397         *
2398         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2399         *
2400         * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} (<code>-1</code>). A startIndex larger than the
2401         * array length will search from the end of the array.</p>
2402         *
2403         * @param array  the array to traverse for looking for the object, may be <code>null</code>
2404         * @param valueToFind  the value to find
2405         * @param startIndex  the start index to travers backwards from
2406         * @param tolerance  search for value within plus/minus this amount
2407         * @return the last index of the value within the array,
2408         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2409         */
2410        public static int lastIndexOf(double[] array, double valueToFind, int startIndex, double tolerance) {
2411            if (ArrayUtils.isEmpty(array)) {
2412                return INDEX_NOT_FOUND;
2413            }
2414            if (startIndex < 0) {
2415                return INDEX_NOT_FOUND;
2416            } else if (startIndex >= array.length) {
2417                startIndex = array.length - 1;
2418            }
2419            double min = valueToFind - tolerance;
2420            double max = valueToFind + tolerance;
2421            for (int i = startIndex; i >= 0; i--) {
2422                if (array[i] >= min && array[i] <= max) {
2423                    return i;
2424                }
2425            }
2426            return INDEX_NOT_FOUND;
2427        }
2428    
2429        /**
2430         * <p>Checks if the value is in the given array.</p>
2431         *
2432         * <p>The method returns <code>false</code> if a <code>null</code> array is passed in.</p>
2433         *
2434         * @param array  the array to search through
2435         * @param valueToFind  the value to find
2436         * @return <code>true</code> if the array contains the object
2437         */
2438        public static boolean contains(double[] array, double valueToFind) {
2439            return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2440        }
2441    
2442        /**
2443         * <p>Checks if a value falling within the given tolerance is in the
2444         * given array.  If the array contains a value within the inclusive range
2445         * defined by (value - tolerance) to (value + tolerance).</p>
2446         *
2447         * <p>The method returns <code>false</code> if a <code>null</code> array
2448         * is passed in.</p>
2449         *
2450         * @param array  the array to search
2451         * @param valueToFind  the value to find
2452         * @param tolerance  the array contains the tolerance of the search
2453         * @return true if value falling within tolerance is in array
2454         */
2455        public static boolean contains(double[] array, double valueToFind, double tolerance) {
2456            return indexOf(array, valueToFind, 0, tolerance) != INDEX_NOT_FOUND;
2457        }
2458    
2459        // float IndexOf
2460        //-----------------------------------------------------------------------
2461        /**
2462         * <p>Finds the index of the given value in the array.</p>
2463         *
2464         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2465         *
2466         * @param array  the array to search through for the object, may be <code>null</code>
2467         * @param valueToFind  the value to find
2468         * @return the index of the value within the array,
2469         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2470         */
2471        public static int indexOf(float[] array, float valueToFind) {
2472            return indexOf(array, valueToFind, 0);
2473        }
2474    
2475        /**
2476         * <p>Finds the index of the given value in the array starting at the given index.</p>
2477         *
2478         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2479         *
2480         * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2481         * length will return {@link #INDEX_NOT_FOUND} (<code>-1</code>).</p>
2482         *
2483         * @param array  the array to search through for the object, may be <code>null</code>
2484         * @param valueToFind  the value to find
2485         * @param startIndex  the index to start searching at
2486         * @return the index of the value within the array,
2487         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2488         */
2489        public static int indexOf(float[] array, float valueToFind, int startIndex) {
2490            if (ArrayUtils.isEmpty(array)) {
2491                return INDEX_NOT_FOUND;
2492            }
2493            if (startIndex < 0) {
2494                startIndex = 0;
2495            }
2496            for (int i = startIndex; i < array.length; i++) {
2497                if (valueToFind == array[i]) {
2498                    return i;
2499                }
2500            }
2501            return INDEX_NOT_FOUND;
2502        }
2503    
2504        /**
2505         * <p>Finds the last index of the given value within the array.</p>
2506         *
2507         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2508         *
2509         * @param array  the array to travers backwords looking for the object, may be <code>null</code>
2510         * @param valueToFind  the object to find
2511         * @return the last index of the value within the array,
2512         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2513         */
2514        public static int lastIndexOf(float[] array, float valueToFind) {
2515            return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
2516        }
2517    
2518        /**
2519         * <p>Finds the last index of the given value in the array starting at the given index.</p>
2520         *
2521         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2522         *
2523         * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} (<code>-1</code>). A startIndex larger than the
2524         * array length will search from the end of the array.</p>
2525         *
2526         * @param array  the array to traverse for looking for the object, may be <code>null</code>
2527         * @param valueToFind  the value to find
2528         * @param startIndex  the start index to travers backwards from
2529         * @return the last index of the value within the array,
2530         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2531         */
2532        public static int lastIndexOf(float[] array, float valueToFind, int startIndex) {
2533            if (ArrayUtils.isEmpty(array)) {
2534                return INDEX_NOT_FOUND;
2535            }
2536            if (startIndex < 0) {
2537                return INDEX_NOT_FOUND;
2538            } else if (startIndex >= array.length) {
2539                startIndex = array.length - 1;
2540            }
2541            for (int i = startIndex; i >= 0; i--) {
2542                if (valueToFind == array[i]) {
2543                    return i;
2544                }
2545            }
2546            return INDEX_NOT_FOUND;
2547        }
2548    
2549        /**
2550         * <p>Checks if the value is in the given array.</p>
2551         *
2552         * <p>The method returns <code>false</code> if a <code>null</code> array is passed in.</p>
2553         *
2554         * @param array  the array to search through
2555         * @param valueToFind  the value to find
2556         * @return <code>true</code> if the array contains the object
2557         */
2558        public static boolean contains(float[] array, float valueToFind) {
2559            return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2560        }
2561    
2562        // boolean IndexOf
2563        //-----------------------------------------------------------------------
2564        /**
2565         * <p>Finds the index of the given value in the array.</p>
2566         *
2567         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2568         *
2569         * @param array  the array to search through for the object, may be <code>null</code>
2570         * @param valueToFind  the value to find
2571         * @return the index of the value within the array,
2572         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2573         */
2574        public static int indexOf(boolean[] array, boolean valueToFind) {
2575            return indexOf(array, valueToFind, 0);
2576        }
2577    
2578        /**
2579         * <p>Finds the index of the given value in the array starting at the given index.</p>
2580         *
2581         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2582         *
2583         * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2584         * length will return {@link #INDEX_NOT_FOUND} (<code>-1</code>).</p>
2585         *
2586         * @param array  the array to search through for the object, may be <code>null</code>
2587         * @param valueToFind  the value to find
2588         * @param startIndex  the index to start searching at
2589         * @return the index of the value within the array,
2590         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code>
2591         *  array input
2592         */
2593        public static int indexOf(boolean[] array, boolean valueToFind, int startIndex) {
2594            if (ArrayUtils.isEmpty(array)) {
2595                return INDEX_NOT_FOUND;
2596            }
2597            if (startIndex < 0) {
2598                startIndex = 0;
2599            }
2600            for (int i = startIndex; i < array.length; i++) {
2601                if (valueToFind == array[i]) {
2602                    return i;
2603                }
2604            }
2605            return INDEX_NOT_FOUND;
2606        }
2607    
2608        /**
2609         * <p>Finds the last index of the given value within the array.</p>
2610         *
2611         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) if
2612         * <code>null</code> array input.</p>
2613         *
2614         * @param array  the array to travers backwords looking for the object, may be <code>null</code>
2615         * @param valueToFind  the object to find
2616         * @return the last index of the value within the array,
2617         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2618         */
2619        public static int lastIndexOf(boolean[] array, boolean valueToFind) {
2620            return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
2621        }
2622    
2623        /**
2624         * <p>Finds the last index of the given value in the array starting at the given index.</p>
2625         *
2626         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2627         *
2628         * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} (<code>-1</code>). A startIndex larger than
2629         * the array length will search from the end of the array.</p>
2630         *
2631         * @param array  the array to traverse for looking for the object, may be <code>null</code>
2632         * @param valueToFind  the value to find
2633         * @param startIndex  the start index to travers backwards from
2634         * @return the last index of the value within the array,
2635         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2636         */
2637        public static int lastIndexOf(boolean[] array, boolean valueToFind, int startIndex) {
2638            if (ArrayUtils.isEmpty(array)) {
2639                return INDEX_NOT_FOUND;
2640            }
2641            if (startIndex < 0) {
2642                return INDEX_NOT_FOUND;
2643            } else if (startIndex >= array.length) {
2644                startIndex = array.length - 1;
2645            }
2646            for (int i = startIndex; i >= 0; i--) {
2647                if (valueToFind == array[i]) {
2648                    return i;
2649                }
2650            }
2651            return INDEX_NOT_FOUND;
2652        }
2653    
2654        /**
2655         * <p>Checks if the value is in the given array.</p>
2656         *
2657         * <p>The method returns <code>false</code> if a <code>null</code> array is passed in.</p>
2658         *
2659         * @param array  the array to search through
2660         * @param valueToFind  the value to find
2661         * @return <code>true</code> if the array contains the object
2662         */
2663        public static boolean contains(boolean[] array, boolean valueToFind) {
2664            return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2665        }
2666    
2667        // Primitive/Object array converters
2668        // ----------------------------------------------------------------------
2669    
2670        // Character array converters
2671        // ----------------------------------------------------------------------
2672        /**
2673         * <p>Converts an array of object Characters to primitives.</p>
2674         *
2675         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2676         *
2677         * @param array  a <code>Character</code> array, may be <code>null</code>
2678         * @return a <code>char</code> array, <code>null</code> if null array input
2679         * @throws NullPointerException if array content is <code>null</code>
2680         */
2681        public static char[] toPrimitive(Character[] array) {
2682            if (array == null) {
2683                return null;
2684            } else if (array.length == 0) {
2685                return EMPTY_CHAR_ARRAY;
2686            }
2687            final char[] result = new char[array.length];
2688            for (int i = 0; i < array.length; i++) {
2689                result[i] = array[i].charValue();
2690            }
2691            return result;
2692        }
2693    
2694        /**
2695         * <p>Converts an array of object Character to primitives handling <code>null</code>.</p>
2696         *
2697         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2698         *
2699         * @param array  a <code>Character</code> array, may be <code>null</code>
2700         * @param valueForNull  the value to insert if <code>null</code> found
2701         * @return a <code>char</code> array, <code>null</code> if null array input
2702         */
2703        public static char[] toPrimitive(Character[] array, char valueForNull) {
2704            if (array == null) {
2705                return null;
2706            } else if (array.length == 0) {
2707                return EMPTY_CHAR_ARRAY;
2708            }
2709            final char[] result = new char[array.length];
2710            for (int i = 0; i < array.length; i++) {
2711                Character b = array[i];
2712                result[i] = (b == null ? valueForNull : b.charValue());
2713            }
2714            return result;
2715        }
2716    
2717        /**
2718         * <p>Converts an array of primitive chars to objects.</p>
2719         *
2720         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2721         *
2722         * @param array a <code>char</code> array
2723         * @return a <code>Character</code> array, <code>null</code> if null array input
2724         */
2725        public static Character[] toObject(char[] array) {
2726            if (array == null) {
2727                return null;
2728            } else if (array.length == 0) {
2729                return EMPTY_CHARACTER_OBJECT_ARRAY;
2730            }
2731            final Character[] result = new Character[array.length];
2732            for (int i = 0; i < array.length; i++) {
2733                result[i] = Character.valueOf(array[i]);
2734            }
2735            return result;
2736         }
2737    
2738        // Long array converters
2739        // ----------------------------------------------------------------------
2740        /**
2741         * <p>Converts an array of object Longs to primitives.</p>
2742         *
2743         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2744         *
2745         * @param array  a <code>Long</code> array, may be <code>null</code>
2746         * @return a <code>long</code> array, <code>null</code> if null array input
2747         * @throws NullPointerException if array content is <code>null</code>
2748         */
2749        public static long[] toPrimitive(Long[] array) {
2750            if (array == null) {
2751                return null;
2752            } else if (array.length == 0) {
2753                return EMPTY_LONG_ARRAY;
2754            }
2755            final long[] result = new long[array.length];
2756            for (int i = 0; i < array.length; i++) {
2757                result[i] = array[i].longValue();
2758            }
2759            return result;
2760        }
2761    
2762        /**
2763         * <p>Converts an array of object Long to primitives handling <code>null</code>.</p>
2764         *
2765         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2766         *
2767         * @param array  a <code>Long</code> array, may be <code>null</code>
2768         * @param valueForNull  the value to insert if <code>null</code> found
2769         * @return a <code>long</code> array, <code>null</code> if null array input
2770         */
2771        public static long[] toPrimitive(Long[] array, long valueForNull) {
2772            if (array == null) {
2773                return null;
2774            } else if (array.length == 0) {
2775                return EMPTY_LONG_ARRAY;
2776            }
2777            final long[] result = new long[array.length];
2778            for (int i = 0; i < array.length; i++) {
2779                Long b = array[i];
2780                result[i] = (b == null ? valueForNull : b.longValue());
2781            }
2782            return result;
2783        }
2784    
2785        /**
2786         * <p>Converts an array of primitive longs to objects.</p>
2787         *
2788         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2789         *
2790         * @param array  a <code>long</code> array
2791         * @return a <code>Long</code> array, <code>null</code> if null array input
2792         */
2793        public static Long[] toObject(long[] array) {
2794            if (array == null) {
2795                return null;
2796            } else if (array.length == 0) {
2797                return EMPTY_LONG_OBJECT_ARRAY;
2798            }
2799            final Long[] result = new Long[array.length];
2800            for (int i = 0; i < array.length; i++) {
2801                result[i] = Long.valueOf(array[i]);
2802            }
2803            return result;
2804        }
2805    
2806        // Int array converters
2807        // ----------------------------------------------------------------------
2808        /**
2809         * <p>Converts an array of object Integers to primitives.</p>
2810         *
2811         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2812         *
2813         * @param array  a <code>Integer</code> array, may be <code>null</code>
2814         * @return an <code>int</code> array, <code>null</code> if null array input
2815         * @throws NullPointerException if array content is <code>null</code>
2816         */
2817        public static int[] toPrimitive(Integer[] array) {
2818            if (array == null) {
2819                return null;
2820            } else if (array.length == 0) {
2821                return EMPTY_INT_ARRAY;
2822            }
2823            final int[] result = new int[array.length];
2824            for (int i = 0; i < array.length; i++) {
2825                result[i] = array[i].intValue();
2826            }
2827            return result;
2828        }
2829    
2830        /**
2831         * <p>Converts an array of object Integer to primitives handling <code>null</code>.</p>
2832         *
2833         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2834         *
2835         * @param array  a <code>Integer</code> array, may be <code>null</code>
2836         * @param valueForNull  the value to insert if <code>null</code> found
2837         * @return an <code>int</code> array, <code>null</code> if null array input
2838         */
2839        public static int[] toPrimitive(Integer[] array, int valueForNull) {
2840            if (array == null) {
2841                return null;
2842            } else if (array.length == 0) {
2843                return EMPTY_INT_ARRAY;
2844            }
2845            final int[] result = new int[array.length];
2846            for (int i = 0; i < array.length; i++) {
2847                Integer b = array[i];
2848                result[i] = (b == null ? valueForNull : b.intValue());
2849            }
2850            return result;
2851        }
2852    
2853        /**
2854         * <p>Converts an array of primitive ints to objects.</p>
2855         *
2856         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2857         *
2858         * @param array  an <code>int</code> array
2859         * @return an <code>Integer</code> array, <code>null</code> if null array input
2860         */
2861        public static Integer[] toObject(int[] array) {
2862            if (array == null) {
2863                return null;
2864            } else if (array.length == 0) {
2865                return EMPTY_INTEGER_OBJECT_ARRAY;
2866            }
2867            final Integer[] result = new Integer[array.length];
2868            for (int i = 0; i < array.length; i++) {
2869                result[i] = Integer.valueOf(array[i]);
2870            }
2871            return result;
2872        }
2873    
2874        // Short array converters
2875        // ----------------------------------------------------------------------
2876        /**
2877         * <p>Converts an array of object Shorts to primitives.</p>
2878         *
2879         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2880         *
2881         * @param array  a <code>Short</code> array, may be <code>null</code>
2882         * @return a <code>byte</code> array, <code>null</code> if null array input
2883         * @throws NullPointerException if array content is <code>null</code>
2884         */
2885        public static short[] toPrimitive(Short[] array) {
2886            if (array == null) {
2887                return null;
2888            } else if (array.length == 0) {
2889                return EMPTY_SHORT_ARRAY;
2890            }
2891            final short[] result = new short[array.length];
2892            for (int i = 0; i < array.length; i++) {
2893                result[i] = array[i].shortValue();
2894            }
2895            return result;
2896        }
2897    
2898        /**
2899         * <p>Converts an array of object Short to primitives handling <code>null</code>.</p>
2900         *
2901         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2902         *
2903         * @param array  a <code>Short</code> array, may be <code>null</code>
2904         * @param valueForNull  the value to insert if <code>null</code> found
2905         * @return a <code>byte</code> array, <code>null</code> if null array input
2906         */
2907        public static short[] toPrimitive(Short[] array, short valueForNull) {
2908            if (array == null) {
2909                return null;
2910            } else if (array.length == 0) {
2911                return EMPTY_SHORT_ARRAY;
2912            }
2913            final short[] result = new short[array.length];
2914            for (int i = 0; i < array.length; i++) {
2915                Short b = array[i];
2916                result[i] = (b == null ? valueForNull : b.shortValue());
2917            }
2918            return result;
2919        }
2920    
2921        /**
2922         * <p>Converts an array of primitive shorts to objects.</p>
2923         *
2924         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2925         *
2926         * @param array  a <code>short</code> array
2927         * @return a <code>Short</code> array, <code>null</code> if null array input
2928         */
2929        public static Short[] toObject(short[] array) {
2930            if (array == null) {
2931                return null;
2932            } else if (array.length == 0) {
2933                return EMPTY_SHORT_OBJECT_ARRAY;
2934            }
2935            final Short[] result = new Short[array.length];
2936            for (int i = 0; i < array.length; i++) {
2937                result[i] = Short.valueOf(array[i]);
2938            }
2939            return result;
2940        }
2941    
2942        // Byte array converters
2943        // ----------------------------------------------------------------------
2944        /**
2945         * <p>Converts an array of object Bytes to primitives.</p>
2946         *
2947         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2948         *
2949         * @param array  a <code>Byte</code> array, may be <code>null</code>
2950         * @return a <code>byte</code> array, <code>null</code> if null array input
2951         * @throws NullPointerException if array content is <code>null</code>
2952         */
2953        public static byte[] toPrimitive(Byte[] array) {
2954            if (array == null) {
2955                return null;
2956            } else if (array.length == 0) {
2957                return EMPTY_BYTE_ARRAY;
2958            }
2959            final byte[] result = new byte[array.length];
2960            for (int i = 0; i < array.length; i++) {
2961                result[i] = array[i].byteValue();
2962            }
2963            return result;
2964        }
2965    
2966        /**
2967         * <p>Converts an array of object Bytes to primitives handling <code>null</code>.</p>
2968         *
2969         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2970         *
2971         * @param array  a <code>Byte</code> array, may be <code>null</code>
2972         * @param valueForNull  the value to insert if <code>null</code> found
2973         * @return a <code>byte</code> array, <code>null</code> if null array input
2974         */
2975        public static byte[] toPrimitive(Byte[] array, byte valueForNull) {
2976            if (array == null) {
2977                return null;
2978            } else if (array.length == 0) {
2979                return EMPTY_BYTE_ARRAY;
2980            }
2981            final byte[] result = new byte[array.length];
2982            for (int i = 0; i < array.length; i++) {
2983                Byte b = array[i];
2984                result[i] = (b == null ? valueForNull : b.byteValue());
2985            }
2986            return result;
2987        }
2988    
2989        /**
2990         * <p>Converts an array of primitive bytes to objects.</p>
2991         *
2992         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2993         *
2994         * @param array  a <code>byte</code> array
2995         * @return a <code>Byte</code> array, <code>null</code> if null array input
2996         */
2997        public static Byte[] toObject(byte[] array) {
2998            if (array == null) {
2999                return null;
3000            } else if (array.length == 0) {
3001                return EMPTY_BYTE_OBJECT_ARRAY;
3002            }
3003            final Byte[] result = new Byte[array.length];
3004            for (int i = 0; i < array.length; i++) {
3005                result[i] = Byte.valueOf(array[i]);
3006            }
3007            return result;
3008        }
3009    
3010        // Double array converters
3011        // ----------------------------------------------------------------------
3012        /**
3013         * <p>Converts an array of object Doubles to primitives.</p>
3014         *
3015         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
3016         *
3017         * @param array  a <code>Double</code> array, may be <code>null</code>
3018         * @return a <code>double</code> array, <code>null</code> if null array input
3019         * @throws NullPointerException if array content is <code>null</code>
3020         */
3021        public static double[] toPrimitive(Double[] array) {
3022            if (array == null) {
3023                return null;
3024            } else if (array.length == 0) {
3025                return EMPTY_DOUBLE_ARRAY;
3026            }
3027            final double[] result = new double[array.length];
3028            for (int i = 0; i < array.length; i++) {
3029                result[i] = array[i].doubleValue();
3030            }
3031            return result;
3032        }
3033    
3034        /**
3035         * <p>Converts an array of object Doubles to primitives handling <code>null</code>.</p>
3036         *
3037         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
3038         *
3039         * @param array  a <code>Double</code> array, may be <code>null</code>
3040         * @param valueForNull  the value to insert if <code>null</code> found
3041         * @return a <code>double</code> array, <code>null</code> if null array input
3042         */
3043        public static double[] toPrimitive(Double[] array, double valueForNull) {
3044            if (array == null) {
3045                return null;
3046            } else if (array.length == 0) {
3047                return EMPTY_DOUBLE_ARRAY;
3048            }
3049            final double[] result = new double[array.length];
3050            for (int i = 0; i < array.length; i++) {
3051                Double b = array[i];
3052                result[i] = (b == null ? valueForNull : b.doubleValue());
3053            }
3054            return result;
3055        }
3056    
3057        /**
3058         * <p>Converts an array of primitive doubles to objects.</p>
3059         *
3060         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
3061         *
3062         * @param array  a <code>double</code> array
3063         * @return a <code>Double</code> array, <code>null</code> if null array input
3064         */
3065        public static Double[] toObject(double[] array) {
3066            if (array == null) {
3067                return null;
3068            } else if (array.length == 0) {
3069                return EMPTY_DOUBLE_OBJECT_ARRAY;
3070            }
3071            final Double[] result = new Double[array.length];
3072            for (int i = 0; i < array.length; i++) {
3073                result[i] = Double.valueOf(array[i]);
3074            }
3075            return result;
3076        }
3077    
3078        //   Float array converters
3079        // ----------------------------------------------------------------------
3080        /**
3081         * <p>Converts an array of object Floats to primitives.</p>
3082         *
3083         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
3084         *
3085         * @param array  a <code>Float</code> array, may be <code>null</code>
3086         * @return a <code>float</code> array, <code>null</code> if null array input
3087         * @throws NullPointerException if array content is <code>null</code>
3088         */
3089        public static float[] toPrimitive(Float[] array) {
3090            if (array == null) {
3091                return null;
3092            } else if (array.length == 0) {
3093                return EMPTY_FLOAT_ARRAY;
3094            }
3095            final float[] result = new float[array.length];
3096            for (int i = 0; i < array.length; i++) {
3097                result[i] = array[i].floatValue();
3098            }
3099            return result;
3100        }
3101    
3102        /**
3103         * <p>Converts an array of object Floats to primitives handling <code>null</code>.</p>
3104         *
3105         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
3106         *
3107         * @param array  a <code>Float</code> array, may be <code>null</code>
3108         * @param valueForNull  the value to insert if <code>null</code> found
3109         * @return a <code>float</code> array, <code>null</code> if null array input
3110         */
3111        public static float[] toPrimitive(Float[] array, float valueForNull) {
3112            if (array == null) {
3113                return null;
3114            } else if (array.length == 0) {
3115                return EMPTY_FLOAT_ARRAY;
3116            }
3117            final float[] result = new float[array.length];
3118            for (int i = 0; i < array.length; i++) {
3119                Float b = array[i];
3120                result[i] = (b == null ? valueForNull : b.floatValue());
3121            }
3122            return result;
3123        }
3124    
3125        /**
3126         * <p>Converts an array of primitive floats to objects.</p>
3127         *
3128         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
3129         *
3130         * @param array  a <code>float</code> array
3131         * @return a <code>Float</code> array, <code>null</code> if null array input
3132         */
3133        public static Float[] toObject(float[] array) {
3134            if (array == null) {
3135                return null;
3136            } else if (array.length == 0) {
3137                return EMPTY_FLOAT_OBJECT_ARRAY;
3138            }
3139            final Float[] result = new Float[array.length];
3140            for (int i = 0; i < array.length; i++) {
3141                result[i] = Float.valueOf(array[i]);
3142            }
3143            return result;
3144        }
3145    
3146        // Boolean array converters
3147        // ----------------------------------------------------------------------
3148        /**
3149         * <p>Converts an array of object Booleans to primitives.</p>
3150         *
3151         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
3152         *
3153         * @param array  a <code>Boolean</code> array, may be <code>null</code>
3154         * @return a <code>boolean</code> array, <code>null</code> if null array input
3155         * @throws NullPointerException if array content is <code>null</code>
3156         */
3157        public static boolean[] toPrimitive(Boolean[] array) {
3158            if (array == null) {
3159                return null;
3160            } else if (array.length == 0) {
3161                return EMPTY_BOOLEAN_ARRAY;
3162            }
3163            final boolean[] result = new boolean[array.length];
3164            for (int i = 0; i < array.length; i++) {
3165                result[i] = array[i].booleanValue();
3166            }
3167            return result;
3168        }
3169    
3170        /**
3171         * <p>Converts an array of object Booleans to primitives handling <code>null</code>.</p>
3172         *
3173         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
3174         *
3175         * @param array  a <code>Boolean</code> array, may be <code>null</code>
3176         * @param valueForNull  the value to insert if <code>null</code> found
3177         * @return a <code>boolean</code> array, <code>null</code> if null array input
3178         */
3179        public static boolean[] toPrimitive(Boolean[] array, boolean valueForNull) {
3180            if (array == null) {
3181                return null;
3182            } else if (array.length == 0) {
3183                return EMPTY_BOOLEAN_ARRAY;
3184            }
3185            final boolean[] result = new boolean[array.length];
3186            for (int i = 0; i < array.length; i++) {
3187                Boolean b = array[i];
3188                result[i] = (b == null ? valueForNull : b.booleanValue());
3189            }
3190            return result;
3191        }
3192    
3193        /**
3194         * <p>Converts an array of primitive booleans to objects.</p>
3195         *
3196         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
3197         *
3198         * @param array  a <code>boolean</code> array
3199         * @return a <code>Boolean</code> array, <code>null</code> if null array input
3200         */
3201        public static Boolean[] toObject(boolean[] array) {
3202            if (array == null) {
3203                return null;
3204            } else if (array.length == 0) {
3205                return EMPTY_BOOLEAN_OBJECT_ARRAY;
3206            }
3207            final Boolean[] result = new Boolean[array.length];
3208            for (int i = 0; i < array.length; i++) {
3209                result[i] = (array[i] ? Boolean.TRUE : Boolean.FALSE);
3210            }
3211            return result;
3212        }
3213    
3214        // ----------------------------------------------------------------------
3215        /**
3216         * <p>Checks if an array of Objects is empty or <code>null</code>.</p>
3217         *
3218         * @param array  the array to test
3219         * @return <code>true</code> if the array is empty or <code>null</code>
3220         * @since 2.1
3221         */
3222        public static <T> boolean isEmpty(T[] array) {
3223            if (array == null || array.length == 0) {
3224                return true;
3225            }
3226            return false;
3227        }
3228    
3229        /**
3230         * <p>Checks if an array of primitive longs is empty or <code>null</code>.</p>
3231         *
3232         * @param array  the array to test
3233         * @return <code>true</code> if the array is empty or <code>null</code>
3234         * @since 2.1
3235         */
3236        public static boolean isEmpty(long[] array) {
3237            if (array == null || array.length == 0) {
3238                return true;
3239            }
3240            return false;
3241        }
3242    
3243        /**
3244         * <p>Checks if an array of primitive ints is empty or <code>null</code>.</p>
3245         *
3246         * @param array  the array to test
3247         * @return <code>true</code> if the array is empty or <code>null</code>
3248         * @since 2.1
3249         */
3250        public static boolean isEmpty(int[] array) {
3251            if (array == null || array.length == 0) {
3252                return true;
3253            }
3254            return false;
3255        }
3256    
3257        /**
3258         * <p>Checks if an array of primitive shorts is empty or <code>null</code>.</p>
3259         *
3260         * @param array  the array to test
3261         * @return <code>true</code> if the array is empty or <code>null</code>
3262         * @since 2.1
3263         */
3264        public static boolean isEmpty(short[] array) {
3265            if (array == null || array.length == 0) {
3266                return true;
3267            }
3268            return false;
3269        }
3270    
3271        /**
3272         * <p>Checks if an array of primitive chars is empty or <code>null</code>.</p>
3273         *
3274         * @param array  the array to test
3275         * @return <code>true</code> if the array is empty or <code>null</code>
3276         * @since 2.1
3277         */
3278        public static boolean isEmpty(char[] array) {
3279            if (array == null || array.length == 0) {
3280                return true;
3281            }
3282            return false;
3283        }
3284    
3285        /**
3286         * <p>Checks if an array of primitive bytes is empty or <code>null</code>.</p>
3287         *
3288         * @param array  the array to test
3289         * @return <code>true</code> if the array is empty or <code>null</code>
3290         * @since 2.1
3291         */
3292        public static boolean isEmpty(byte[] array) {
3293            if (array == null || array.length == 0) {
3294                return true;
3295            }
3296            return false;
3297        }
3298    
3299        /**
3300         * <p>Checks if an array of primitive doubles is empty or <code>null</code>.</p>
3301         *
3302         * @param array  the array to test
3303         * @return <code>true</code> if the array is empty or <code>null</code>
3304         * @since 2.1
3305         */
3306        public static boolean isEmpty(double[] array) {
3307            if (array == null || array.length == 0) {
3308                return true;
3309            }
3310            return false;
3311        }
3312    
3313        /**
3314         * <p>Checks if an array of primitive floats is empty or <code>null</code>.</p>
3315         *
3316         * @param array  the array to test
3317         * @return <code>true</code> if the array is empty or <code>null</code>
3318         * @since 2.1
3319         */
3320        public static boolean isEmpty(float[] array) {
3321            if (array == null || array.length == 0) {
3322                return true;
3323            }
3324            return false;
3325        }
3326    
3327        /**
3328         * <p>Checks if an array of primitive booleans is empty or <code>null</code>.</p>
3329         *
3330         * @param array  the array to test
3331         * @return <code>true</code> if the array is empty or <code>null</code>
3332         * @since 2.1
3333         */
3334        public static boolean isEmpty(boolean[] array) {
3335            if (array == null || array.length == 0) {
3336                return true;
3337            }
3338            return false;
3339        }
3340    
3341        // ----------------------------------------------------------------------
3342        /**
3343         * <p>Checks if an array of Objects is not empty or not <code>null</code>.</p>
3344         *
3345         * @param array  the array to test
3346         * @return <code>true</code> if the array is not empty or not <code>null</code>
3347         * @since 2.5
3348         */
3349         public static <T> boolean isNotEmpty(T[] array) {
3350             return (array != null && array.length != 0);
3351         }
3352    
3353        /**
3354         * <p>Checks if an array of primitive longs is not empty or not <code>null</code>.</p>
3355         *
3356         * @param array  the array to test
3357         * @return <code>true</code> if the array is not empty or not <code>null</code>
3358         * @since 2.5
3359         */
3360        public static boolean isNotEmpty(long[] array) {
3361            return (array != null && array.length != 0);
3362        }
3363    
3364        /**
3365         * <p>Checks if an array of primitive ints is not empty or not <code>null</code>.</p>
3366         *
3367         * @param array  the array to test
3368         * @return <code>true</code> if the array is not empty or not <code>null</code>
3369         * @since 2.5
3370         */
3371        public static boolean isNotEmpty(int[] array) {
3372            return (array != null && array.length != 0);
3373        }
3374    
3375        /**
3376         * <p>Checks if an array of primitive shorts is not empty or not <code>null</code>.</p>
3377         *
3378         * @param array  the array to test
3379         * @return <code>true</code> if the array is not empty or not <code>null</code>
3380         * @since 2.5
3381         */
3382        public static boolean isNotEmpty(short[] array) {
3383            return (array != null && array.length != 0);
3384        }
3385    
3386        /**
3387         * <p>Checks if an array of primitive chars is not empty or not <code>null</code>.</p>
3388         *
3389         * @param array  the array to test
3390         * @return <code>true</code> if the array is not empty or not <code>null</code>
3391         * @since 2.5
3392         */
3393        public static boolean isNotEmpty(char[] array) {
3394            return (array != null && array.length != 0);
3395        }
3396    
3397        /**
3398         * <p>Checks if an array of primitive bytes is not empty or not <code>null</code>.</p>
3399         *
3400         * @param array  the array to test
3401         * @return <code>true</code> if the array is not empty or not <code>null</code>
3402         * @since 2.5
3403         */
3404        public static boolean isNotEmpty(byte[] array) {
3405            return (array != null && array.length != 0);
3406        }
3407    
3408        /**
3409         * <p>Checks if an array of primitive doubles is not empty or not <code>null</code>.</p>
3410         *
3411         * @param array  the array to test
3412         * @return <code>true</code> if the array is not empty or not <code>null</code>
3413         * @since 2.5
3414         */
3415        public static boolean isNotEmpty(double[] array) {
3416            return (array != null && array.length != 0);
3417        }
3418    
3419        /**
3420         * <p>Checks if an array of primitive floats is not empty or not <code>null</code>.</p>
3421         *
3422         * @param array  the array to test
3423         * @return <code>true</code> if the array is not empty or not <code>null</code>
3424         * @since 2.5
3425         */
3426        public static boolean isNotEmpty(float[] array) {
3427            return (array != null && array.length != 0);
3428        }
3429    
3430        /**
3431         * <p>Checks if an array of primitive booleans is not empty or not <code>null</code>.</p>
3432         *
3433         * @param array  the array to test
3434         * @return <code>true</code> if the array is not empty or not <code>null</code>
3435         * @since 2.5
3436         */
3437        public static boolean isNotEmpty(boolean[] array) {
3438            return (array != null && array.length != 0);
3439        }
3440    
3441        /**
3442         * <p>Adds all the elements of the given arrays into a new array.</p>
3443         * <p>The new array contains all of the element of <code>array1</code> followed
3444         * by all of the elements <code>array2</code>. When an array is returned, it is always
3445         * a new array.</p>
3446         *
3447         * <pre>
3448         * ArrayUtils.addAll(null, null)     = null
3449         * ArrayUtils.addAll(array1, null)   = cloned copy of array1
3450         * ArrayUtils.addAll(null, array2)   = cloned copy of array2
3451         * ArrayUtils.addAll([], [])         = []
3452         * ArrayUtils.addAll([null], [null]) = [null, null]
3453         * ArrayUtils.addAll(["a", "b", "c"], ["1", "2", "3"]) = ["a", "b", "c", "1", "2", "3"]
3454         * </pre>
3455         *
3456         * @param array1  the first array whose elements are added to the new array, may be <code>null</code>
3457         * @param array2  the second array whose elements are added to the new array, may be <code>null</code>
3458         * @return The new array, <code>null</code> if both arrays are <code>null</code>.
3459         *      The type of the new array is the type of the first array,
3460         *      unless the first array is null, in which case the type is the same as the second array.
3461         * @since 2.1
3462         * @throws IllegalArgumentException if the array types are incompatible
3463         */
3464        public static <T> T[] addAll(T[] array1, T... array2) {
3465            if (array1 == null) {
3466                return clone(array2);
3467            } else if (array2 == null) {
3468                return clone(array1);
3469            }
3470            final Class<?> type1 = array1.getClass().getComponentType();
3471            @SuppressWarnings("unchecked") // OK, because array is of type T
3472            T[] joinedArray = (T[]) Array.newInstance(type1, array1.length + array2.length);
3473            System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3474            try {
3475                System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3476            } catch (ArrayStoreException ase) {
3477                // Check if problem was due to incompatible types
3478                /*
3479                 * We do this here, rather than before the copy because:
3480                 * - it would be a wasted check most of the time
3481                 * - safer, in case check turns out to be too strict
3482                 */
3483                final Class<?> type2 = array2.getClass().getComponentType();
3484                if (!type1.isAssignableFrom(type2)){
3485                    throw new IllegalArgumentException("Cannot store "+type2.getName()+" in an array of "+type1.getName(), ase);
3486                }
3487                throw ase; // No, so rethrow original
3488            }
3489            return joinedArray;
3490        }
3491    
3492        /**
3493         * <p>Adds all the elements of the given arrays into a new array.</p>
3494         * <p>The new array contains all of the element of <code>array1</code> followed
3495         * by all of the elements <code>array2</code>. When an array is returned, it is always
3496         * a new array.</p>
3497         *
3498         * <pre>
3499         * ArrayUtils.addAll(array1, null)   = cloned copy of array1
3500         * ArrayUtils.addAll(null, array2)   = cloned copy of array2
3501         * ArrayUtils.addAll([], [])         = []
3502         * </pre>
3503         *
3504         * @param array1  the first array whose elements are added to the new array.
3505         * @param array2  the second array whose elements are added to the new array.
3506         * @return The new boolean[] array.
3507         * @since 2.1
3508         */
3509        public static boolean[] addAll(boolean[] array1, boolean... array2) {
3510            if (array1 == null) {
3511                return clone(array2);
3512            } else if (array2 == null) {
3513                return clone(array1);
3514            }
3515            boolean[] joinedArray = new boolean[array1.length + array2.length];
3516            System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3517            System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3518            return joinedArray;
3519        }
3520    
3521        /**
3522         * <p>Adds all the elements of the given arrays into a new array.</p>
3523         * <p>The new array contains all of the element of <code>array1</code> followed
3524         * by all of the elements <code>array2</code>. When an array is returned, it is always
3525         * a new array.</p>
3526         *
3527         * <pre>
3528         * ArrayUtils.addAll(array1, null)   = cloned copy of array1
3529         * ArrayUtils.addAll(null, array2)   = cloned copy of array2
3530         * ArrayUtils.addAll([], [])         = []
3531         * </pre>
3532         *
3533         * @param array1  the first array whose elements are added to the new array.
3534         * @param array2  the second array whose elements are added to the new array.
3535         * @return The new char[] array.
3536         * @since 2.1
3537         */
3538        public static char[] addAll(char[] array1, char... array2) {
3539            if (array1 == null) {
3540                return clone(array2);
3541            } else if (array2 == null) {
3542                return clone(array1);
3543            }
3544            char[] joinedArray = new char[array1.length + array2.length];
3545            System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3546            System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3547            return joinedArray;
3548        }
3549    
3550        /**
3551         * <p>Adds all the elements of the given arrays into a new array.</p>
3552         * <p>The new array contains all of the element of <code>array1</code> followed
3553         * by all of the elements <code>array2</code>. When an array is returned, it is always
3554         * a new array.</p>
3555         *
3556         * <pre>
3557         * ArrayUtils.addAll(array1, null)   = cloned copy of array1
3558         * ArrayUtils.addAll(null, array2)   = cloned copy of array2
3559         * ArrayUtils.addAll([], [])         = []
3560         * </pre>
3561         *
3562         * @param array1  the first array whose elements are added to the new array.
3563         * @param array2  the second array whose elements are added to the new array.
3564         * @return The new byte[] array.
3565         * @since 2.1
3566         */
3567        public static byte[] addAll(byte[] array1, byte... array2) {
3568            if (array1 == null) {
3569                return clone(array2);
3570            } else if (array2 == null) {
3571                return clone(array1);
3572            }
3573            byte[] joinedArray = new byte[array1.length + array2.length];
3574            System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3575            System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3576            return joinedArray;
3577        }
3578    
3579        /**
3580         * <p>Adds all the elements of the given arrays into a new array.</p>
3581         * <p>The new array contains all of the element of <code>array1</code> followed
3582         * by all of the elements <code>array2</code>. When an array is returned, it is always
3583         * a new array.</p>
3584         *
3585         * <pre>
3586         * ArrayUtils.addAll(array1, null)   = cloned copy of array1
3587         * ArrayUtils.addAll(null, array2)   = cloned copy of array2
3588         * ArrayUtils.addAll([], [])         = []
3589         * </pre>
3590         *
3591         * @param array1  the first array whose elements are added to the new array.
3592         * @param array2  the second array whose elements are added to the new array.
3593         * @return The new short[] array.
3594         * @since 2.1
3595         */
3596        public static short[] addAll(short[] array1, short... array2) {
3597            if (array1 == null) {
3598                return clone(array2);
3599            } else if (array2 == null) {
3600                return clone(array1);
3601            }
3602            short[] joinedArray = new short[array1.length + array2.length];
3603            System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3604            System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3605            return joinedArray;
3606        }
3607    
3608        /**
3609         * <p>Adds all the elements of the given arrays into a new array.</p>
3610         * <p>The new array contains all of the element of <code>array1</code> followed
3611         * by all of the elements <code>array2</code>. When an array is returned, it is always
3612         * a new array.</p>
3613         *
3614         * <pre>
3615         * ArrayUtils.addAll(array1, null)   = cloned copy of array1
3616         * ArrayUtils.addAll(null, array2)   = cloned copy of array2
3617         * ArrayUtils.addAll([], [])         = []
3618         * </pre>
3619         *
3620         * @param array1  the first array whose elements are added to the new array.
3621         * @param array2  the second array whose elements are added to the new array.
3622         * @return The new int[] array.
3623         * @since 2.1
3624         */
3625        public static int[] addAll(int[] array1, int... array2) {
3626            if (array1 == null) {
3627                return clone(array2);
3628            } else if (array2 == null) {
3629                return clone(array1);
3630            }
3631            int[] joinedArray = new int[array1.length + array2.length];
3632            System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3633            System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3634            return joinedArray;
3635        }
3636    
3637        /**
3638         * <p>Adds all the elements of the given arrays into a new array.</p>
3639         * <p>The new array contains all of the element of <code>array1</code> followed
3640         * by all of the elements <code>array2</code>. When an array is returned, it is always
3641         * a new array.</p>
3642         *
3643         * <pre>
3644         * ArrayUtils.addAll(array1, null)   = cloned copy of array1
3645         * ArrayUtils.addAll(null, array2)   = cloned copy of array2
3646         * ArrayUtils.addAll([], [])         = []
3647         * </pre>
3648         *
3649         * @param array1  the first array whose elements are added to the new array.
3650         * @param array2  the second array whose elements are added to the new array.
3651         * @return The new long[] array.
3652         * @since 2.1
3653         */
3654        public static long[] addAll(long[] array1, long... array2) {
3655            if (array1 == null) {
3656                return clone(array2);
3657            } else if (array2 == null) {
3658                return clone(array1);
3659            }
3660            long[] joinedArray = new long[array1.length + array2.length];
3661            System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3662            System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3663            return joinedArray;
3664        }
3665    
3666        /**
3667         * <p>Adds all the elements of the given arrays into a new array.</p>
3668         * <p>The new array contains all of the element of <code>array1</code> followed
3669         * by all of the elements <code>array2</code>. When an array is returned, it is always
3670         * a new array.</p>
3671         *
3672         * <pre>
3673         * ArrayUtils.addAll(array1, null)   = cloned copy of array1
3674         * ArrayUtils.addAll(null, array2)   = cloned copy of array2
3675         * ArrayUtils.addAll([], [])         = []
3676         * </pre>
3677         *
3678         * @param array1  the first array whose elements are added to the new array.
3679         * @param array2  the second array whose elements are added to the new array.
3680         * @return The new float[] array.
3681         * @since 2.1
3682         */
3683        public static float[] addAll(float[] array1, float... array2) {
3684            if (array1 == null) {
3685                return clone(array2);
3686            } else if (array2 == null) {
3687                return clone(array1);
3688            }
3689            float[] joinedArray = new float[array1.length + array2.length];
3690            System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3691            System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3692            return joinedArray;
3693        }
3694    
3695        /**
3696         * <p>Adds all the elements of the given arrays into a new array.</p>
3697         * <p>The new array contains all of the element of <code>array1</code> followed
3698         * by all of the elements <code>array2</code>. When an array is returned, it is always
3699         * a new array.</p>
3700         *
3701         * <pre>
3702         * ArrayUtils.addAll(array1, null)   = cloned copy of array1
3703         * ArrayUtils.addAll(null, array2)   = cloned copy of array2
3704         * ArrayUtils.addAll([], [])         = []
3705         * </pre>
3706         *
3707         * @param array1  the first array whose elements are added to the new array.
3708         * @param array2  the second array whose elements are added to the new array.
3709         * @return The new double[] array.
3710         * @since 2.1
3711         */
3712        public static double[] addAll(double[] array1, double... array2) {
3713            if (array1 == null) {
3714                return clone(array2);
3715            } else if (array2 == null) {
3716                return clone(array1);
3717            }
3718            double[] joinedArray = new double[array1.length + array2.length];
3719            System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3720            System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3721            return joinedArray;
3722        }
3723    
3724        /**
3725         * <p>Copies the given array and adds the given element at the end of the new array.</p>
3726         *
3727         * <p>The new array contains the same elements of the input
3728         * array plus the given element in the last position. The component type of
3729         * the new array is the same as that of the input array.</p>
3730         *
3731         * <p>If the input array is <code>null</code>, a new one element array is returned
3732         *  whose component type is the same as the element, unless the element itself is null,
3733         *  in which case the return type is Object[]</p>
3734         *
3735         * <pre>
3736         * ArrayUtils.add(null, null)      = [null]
3737         * ArrayUtils.add(null, "a")       = ["a"]
3738         * ArrayUtils.add(["a"], null)     = ["a", null]
3739         * ArrayUtils.add(["a"], "b")      = ["a", "b"]
3740         * ArrayUtils.add(["a", "b"], "c") = ["a", "b", "c"]
3741         * </pre>
3742         *
3743         * @param array  the array to "add" the element to, may be <code>null</code>
3744         * @param element  the object to add, may be <code>null</code>
3745         * @return A new array containing the existing elements plus the new element
3746         * The returned array type will be that of the input array (unless null),
3747         * in which case it will have the same type as the element.
3748         * If both are null, an IllegalArgumentException is thrown
3749         * @since 2.1
3750         * @throws IllegalArgumentException if both arguments are null
3751         */
3752        public static <T> T[] add(T[] array, T element) {
3753            Class<?> type;
3754            if (array != null){
3755                type = array.getClass();
3756            } else if (element != null) {
3757                type = element.getClass();
3758            } else {
3759                throw new IllegalArgumentException("Arguments cannot both be null");            
3760            }
3761            @SuppressWarnings("unchecked") // type must be T
3762            T[] newArray = (T[]) copyArrayGrow1(array, type);
3763            newArray[newArray.length - 1] = element;
3764            return newArray;
3765        }
3766    
3767        /**
3768         * <p>Copies the given array and adds the given element at the end of the new array.</p>
3769         *
3770         * <p>The new array contains the same elements of the input
3771         * array plus the given element in the last position. The component type of
3772         * the new array is the same as that of the input array.</p>
3773         *
3774         * <p>If the input array is <code>null</code>, a new one element array is returned
3775         *  whose component type is the same as the element.</p>
3776         *
3777         * <pre>
3778         * ArrayUtils.add(null, true)          = [true]
3779         * ArrayUtils.add([true], false)       = [true, false]
3780         * ArrayUtils.add([true, false], true) = [true, false, true]
3781         * </pre>
3782         *
3783         * @param array  the array to copy and add the element to, may be <code>null</code>
3784         * @param element  the object to add at the last index of the new array
3785         * @return A new array containing the existing elements plus the new element
3786         * @since 2.1
3787         */
3788        public static boolean[] add(boolean[] array, boolean element) {
3789            boolean[] newArray = (boolean[])copyArrayGrow1(array, Boolean.TYPE);
3790            newArray[newArray.length - 1] = element;
3791            return newArray;
3792        }
3793    
3794        /**
3795         * <p>Copies the given array and adds the given element at the end of the new array.</p>
3796         *
3797         * <p>The new array contains the same elements of the input
3798         * array plus the given element in the last position. The component type of
3799         * the new array is the same as that of the input array.</p>
3800         *
3801         * <p>If the input array is <code>null</code>, a new one element array is returned
3802         *  whose component type is the same as the element.</p>
3803         *
3804         * <pre>
3805         * ArrayUtils.add(null, 0)   = [0]
3806         * ArrayUtils.add([1], 0)    = [1, 0]
3807         * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
3808         * </pre>
3809         *
3810         * @param array  the array to copy and add the element to, may be <code>null</code>
3811         * @param element  the object to add at the last index of the new array
3812         * @return A new array containing the existing elements plus the new element
3813         * @since 2.1
3814         */
3815        public static byte[] add(byte[] array, byte element) {
3816            byte[] newArray = (byte[])copyArrayGrow1(array, Byte.TYPE);
3817            newArray[newArray.length - 1] = element;
3818            return newArray;
3819        }
3820    
3821        /**
3822         * <p>Copies the given array and adds the given element at the end of the new array.</p>
3823         *
3824         * <p>The new array contains the same elements of the input
3825         * array plus the given element in the last position. The component type of
3826         * the new array is the same as that of the input array.</p>
3827         *
3828         * <p>If the input array is <code>null</code>, a new one element array is returned
3829         *  whose component type is the same as the element.</p>
3830         *
3831         * <pre>
3832         * ArrayUtils.add(null, '0')       = ['0']
3833         * ArrayUtils.add(['1'], '0')      = ['1', '0']
3834         * ArrayUtils.add(['1', '0'], '1') = ['1', '0', '1']
3835         * </pre>
3836         *
3837         * @param array  the array to copy and add the element to, may be <code>null</code>
3838         * @param element  the object to add at the last index of the new array
3839         * @return A new array containing the existing elements plus the new element
3840         * @since 2.1
3841         */
3842        public static char[] add(char[] array, char element) {
3843            char[] newArray = (char[])copyArrayGrow1(array, Character.TYPE);
3844            newArray[newArray.length - 1] = element;
3845            return newArray;
3846        }
3847    
3848        /**
3849         * <p>Copies the given array and adds the given element at the end of the new array.</p>
3850         *
3851         * <p>The new array contains the same elements of the input
3852         * array plus the given element in the last position. The component type of
3853         * the new array is the same as that of the input array.</p>
3854         *
3855         * <p>If the input array is <code>null</code>, a new one element array is returned
3856         *  whose component type is the same as the element.</p>
3857         *
3858         * <pre>
3859         * ArrayUtils.add(null, 0)   = [0]
3860         * ArrayUtils.add([1], 0)    = [1, 0]
3861         * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
3862         * </pre>
3863         *
3864         * @param array  the array to copy and add the element to, may be <code>null</code>
3865         * @param element  the object to add at the last index of the new array
3866         * @return A new array containing the existing elements plus the new element
3867         * @since 2.1
3868         */
3869        public static double[] add(double[] array, double element) {
3870            double[] newArray = (double[])copyArrayGrow1(array, Double.TYPE);
3871            newArray[newArray.length - 1] = element;
3872            return newArray;
3873        }
3874    
3875        /**
3876         * <p>Copies the given array and adds the given element at the end of the new array.</p>
3877         *
3878         * <p>The new array contains the same elements of the input
3879         * array plus the given element in the last position. The component type of
3880         * the new array is the same as that of the input array.</p>
3881         *
3882         * <p>If the input array is <code>null</code>, a new one element array is returned
3883         *  whose component type is the same as the element.</p>
3884         *
3885         * <pre>
3886         * ArrayUtils.add(null, 0)   = [0]
3887         * ArrayUtils.add([1], 0)    = [1, 0]
3888         * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
3889         * </pre>
3890         *
3891         * @param array  the array to copy and add the element to, may be <code>null</code>
3892         * @param element  the object to add at the last index of the new array
3893         * @return A new array containing the existing elements plus the new element
3894         * @since 2.1
3895         */
3896        public static float[] add(float[] array, float element) {
3897            float[] newArray = (float[])copyArrayGrow1(array, Float.TYPE);
3898            newArray[newArray.length - 1] = element;
3899            return newArray;
3900        }
3901    
3902        /**
3903         * <p>Copies the given array and adds the given element at the end of the new array.</p>
3904         *
3905         * <p>The new array contains the same elements of the input
3906         * array plus the given element in the last position. The component type of
3907         * the new array is the same as that of the input array.</p>
3908         *
3909         * <p>If the input array is <code>null</code>, a new one element array is returned
3910         *  whose component type is the same as the element.</p>
3911         *
3912         * <pre>
3913         * ArrayUtils.add(null, 0)   = [0]
3914         * ArrayUtils.add([1], 0)    = [1, 0]
3915         * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
3916         * </pre>
3917         *
3918         * @param array  the array to copy and add the element to, may be <code>null</code>
3919         * @param element  the object to add at the last index of the new array
3920         * @return A new array containing the existing elements plus the new element
3921         * @since 2.1
3922         */
3923        public static int[] add(int[] array, int element) {
3924            int[] newArray = (int[])copyArrayGrow1(array, Integer.TYPE);
3925            newArray[newArray.length - 1] = element;
3926            return newArray;
3927        }
3928    
3929        /**
3930         * <p>Copies the given array and adds the given element at the end of the new array.</p>
3931         *
3932         * <p>The new array contains the same elements of the input
3933         * array plus the given element in the last position. The component type of
3934         * the new array is the same as that of the input array.</p>
3935         *
3936         * <p>If the input array is <code>null</code>, a new one element array is returned
3937         *  whose component type is the same as the element.</p>
3938         *
3939         * <pre>
3940         * ArrayUtils.add(null, 0)   = [0]
3941         * ArrayUtils.add([1], 0)    = [1, 0]
3942         * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
3943         * </pre>
3944         *
3945         * @param array  the array to copy and add the element to, may be <code>null</code>
3946         * @param element  the object to add at the last index of the new array
3947         * @return A new array containing the existing elements plus the new element
3948         * @since 2.1
3949         */
3950        public static long[] add(long[] array, long element) {
3951            long[] newArray = (long[])copyArrayGrow1(array, Long.TYPE);
3952            newArray[newArray.length - 1] = element;
3953            return newArray;
3954        }
3955    
3956        /**
3957         * <p>Copies the given array and adds the given element at the end of the new array.</p>
3958         *
3959         * <p>The new array contains the same elements of the input
3960         * array plus the given element in the last position. The component type of
3961         * the new array is the same as that of the input array.</p>
3962         *
3963         * <p>If the input array is <code>null</code>, a new one element array is returned
3964         *  whose component type is the same as the element.</p>
3965         *
3966         * <pre>
3967         * ArrayUtils.add(null, 0)   = [0]
3968         * ArrayUtils.add([1], 0)    = [1, 0]
3969         * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
3970         * </pre>
3971         *
3972         * @param array  the array to copy and add the element to, may be <code>null</code>
3973         * @param element  the object to add at the last index of the new array
3974         * @return A new array containing the existing elements plus the new element
3975         * @since 2.1
3976         */
3977        public static short[] add(short[] array, short element) {
3978            short[] newArray = (short[])copyArrayGrow1(array, Short.TYPE);
3979            newArray[newArray.length - 1] = element;
3980            return newArray;
3981        }
3982    
3983        /**
3984         * Returns a copy of the given array of size 1 greater than the argument.
3985         * The last value of the array is left to the default value.
3986         *
3987         * @param array The array to copy, must not be <code>null</code>.
3988         * @param newArrayComponentType If <code>array</code> is <code>null</code>, create a
3989         * size 1 array of this type.
3990         * @return A new copy of the array of size 1 greater than the input.
3991         */
3992        private static Object copyArrayGrow1(Object array, Class<?> newArrayComponentType) {
3993            if (array != null) {
3994                int arrayLength = Array.getLength(array);
3995                Object newArray = Array.newInstance(array.getClass().getComponentType(), arrayLength + 1);
3996                System.arraycopy(array, 0, newArray, 0, arrayLength);
3997                return newArray;
3998            }
3999            return Array.newInstance(newArrayComponentType, 1);
4000        }
4001    
4002        /**
4003         * <p>Inserts the specified element at the specified position in the array.
4004         * Shifts the element currently at that position (if any) and any subsequent
4005         * elements to the right (adds one to their indices).</p>
4006         *
4007         * <p>This method returns a new array with the same elements of the input
4008         * array plus the given element on the specified position. The component
4009         * type of the returned array is always the same as that of the input
4010         * array.</p>
4011         *
4012         * <p>If the input array is <code>null</code>, a new one element array is returned
4013         *  whose component type is the same as the element.</p>
4014         *
4015         * <pre>
4016         * ArrayUtils.add(null, 0, null)      = [null]
4017         * ArrayUtils.add(null, 0, "a")       = ["a"]
4018         * ArrayUtils.add(["a"], 1, null)     = ["a", null]
4019         * ArrayUtils.add(["a"], 1, "b")      = ["a", "b"]
4020         * ArrayUtils.add(["a", "b"], 3, "c") = ["a", "b", "c"]
4021         * </pre>
4022         *
4023         * @param array  the array to add the element to, may be <code>null</code>
4024         * @param index  the position of the new object
4025         * @param element  the object to add
4026         * @return A new array containing the existing elements and the new element
4027         * @throws IndexOutOfBoundsException if the index is out of range
4028         * (index < 0 || index > array.length).
4029         * @throws IllegalArgumentException if both array and element are null
4030         */
4031        public static <T> T[] add(T[] array, int index, T element) {
4032            Class<?> clss = null;
4033            if (array != null) {
4034                clss = array.getClass().getComponentType();
4035            } else if (element != null) {
4036                clss = element.getClass();
4037            } else {
4038                throw new IllegalArgumentException("Array and element cannot both be null");            
4039            }
4040            @SuppressWarnings("unchecked") // the add method creates an array of type clss, which is type T
4041            final T[] newArray = (T[]) add(array, index, element, clss);
4042            return newArray;
4043        }
4044    
4045        /**
4046         * <p>Inserts the specified element at the specified position in the array.
4047         * Shifts the element currently at that position (if any) and any subsequent
4048         * elements to the right (adds one to their indices).</p>
4049         *
4050         * <p>This method returns a new array with the same elements of the input
4051         * array plus the given element on the specified position. The component
4052         * type of the returned array is always the same as that of the input
4053         * array.</p>
4054         *
4055         * <p>If the input array is <code>null</code>, a new one element array is returned
4056         *  whose component type is the same as the element.</p>
4057         *
4058         * <pre>
4059         * ArrayUtils.add(null, 0, true)          = [true]
4060         * ArrayUtils.add([true], 0, false)       = [false, true]
4061         * ArrayUtils.add([false], 1, true)       = [false, true]
4062         * ArrayUtils.add([true, false], 1, true) = [true, true, false]
4063         * </pre>
4064         *
4065         * @param array  the array to add the element to, may be <code>null</code>
4066         * @param index  the position of the new object
4067         * @param element  the object to add
4068         * @return A new array containing the existing elements and the new element
4069         * @throws IndexOutOfBoundsException if the index is out of range
4070         * (index < 0 || index > array.length).
4071         */
4072        public static boolean[] add(boolean[] array, int index, boolean element) {
4073            return (boolean[]) add(array, index, Boolean.valueOf(element), Boolean.TYPE);
4074        }
4075    
4076        /**
4077         * <p>Inserts the specified element at the specified position in the array.
4078         * Shifts the element currently at that position (if any) and any subsequent
4079         * elements to the right (adds one to their indices).</p>
4080         *
4081         * <p>This method returns a new array with the same elements of the input
4082         * array plus the given element on the specified position. The component
4083         * type of the returned array is always the same as that of the input
4084         * array.</p>
4085         *
4086         * <p>If the input array is <code>null</code>, a new one element array is returned
4087         *  whose component type is the same as the element.</p>
4088         *
4089         * <pre>
4090         * ArrayUtils.add(null, 0, 'a')            = ['a']
4091         * ArrayUtils.add(['a'], 0, 'b')           = ['b', 'a']
4092         * ArrayUtils.add(['a', 'b'], 0, 'c')      = ['c', 'a', 'b']
4093         * ArrayUtils.add(['a', 'b'], 1, 'k')      = ['a', 'k', 'b']
4094         * ArrayUtils.add(['a', 'b', 'c'], 1, 't') = ['a', 't', 'b', 'c']
4095         * </pre>
4096         *
4097         * @param array  the array to add the element to, may be <code>null</code>
4098         * @param index  the position of the new object
4099         * @param element  the object to add
4100         * @return A new array containing the existing elements and the new element
4101         * @throws IndexOutOfBoundsException if the index is out of range
4102         * (index < 0 || index > array.length).
4103         */
4104        public static char[] add(char[] array, int index, char element) {
4105            return (char[]) add(array, index, Character.valueOf(element), Character.TYPE);
4106        }
4107    
4108        /**
4109         * <p>Inserts the specified element at the specified position in the array.
4110         * Shifts the element currently at that position (if any) and any subsequent
4111         * elements to the right (adds one to their indices).</p>
4112         *
4113         * <p>This method returns a new array with the same elements of the input
4114         * array plus the given element on the specified position. The component
4115         * type of the returned array is always the same as that of the input
4116         * array.</p>
4117         *
4118         * <p>If the input array is <code>null</code>, a new one element array is returned
4119         *  whose component type is the same as the element.</p>
4120         *
4121         * <pre>
4122         * ArrayUtils.add([1], 0, 2)         = [2, 1]
4123         * ArrayUtils.add([2, 6], 2, 3)      = [2, 6, 3]
4124         * ArrayUtils.add([2, 6], 0, 1)      = [1, 2, 6]
4125         * ArrayUtils.add([2, 6, 3], 2, 1)   = [2, 6, 1, 3]
4126         * </pre>
4127         *
4128         * @param array  the array to add the element to, may be <code>null</code>
4129         * @param index  the position of the new object
4130         * @param element  the object to add
4131         * @return A new array containing the existing elements and the new element
4132         * @throws IndexOutOfBoundsException if the index is out of range
4133         * (index < 0 || index > array.length).
4134         */
4135        public static byte[] add(byte[] array, int index, byte element) {
4136            return (byte[]) add(array, index, Byte.valueOf(element), Byte.TYPE);
4137        }
4138    
4139        /**
4140         * <p>Inserts the specified element at the specified position in the array.
4141         * Shifts the element currently at that position (if any) and any subsequent
4142         * elements to the right (adds one to their indices).</p>
4143         *
4144         * <p>This method returns a new array with the same elements of the input
4145         * array plus the given element on the specified position. The component
4146         * type of the returned array is always the same as that of the input
4147         * array.</p>
4148         *
4149         * <p>If the input array is <code>null</code>, a new one element array is returned
4150         *  whose component type is the same as the element.</p>
4151         *
4152         * <pre>
4153         * ArrayUtils.add([1], 0, 2)         = [2, 1]
4154         * ArrayUtils.add([2, 6], 2, 10)     = [2, 6, 10]
4155         * ArrayUtils.add([2, 6], 0, -4)     = [-4, 2, 6]
4156         * ArrayUtils.add([2, 6, 3], 2, 1)   = [2, 6, 1, 3]
4157         * </pre>
4158         *
4159         * @param array  the array to add the element to, may be <code>null</code>
4160         * @param index  the position of the new object
4161         * @param element  the object to add
4162         * @return A new array containing the existing elements and the new element
4163         * @throws IndexOutOfBoundsException if the index is out of range
4164         * (index < 0 || index > array.length).
4165         */
4166        public static short[] add(short[] array, int index, short element) {
4167            return (short[]) add(array, index, Short.valueOf(element), Short.TYPE);
4168        }
4169    
4170        /**
4171         * <p>Inserts the specified element at the specified position in the array.
4172         * Shifts the element currently at that position (if any) and any subsequent
4173         * elements to the right (adds one to their indices).</p>
4174         *
4175         * <p>This method returns a new array with the same elements of the input
4176         * array plus the given element on the specified position. The component
4177         * type of the returned array is always the same as that of the input
4178         * array.</p>
4179         *
4180         * <p>If the input array is <code>null</code>, a new one element array is returned
4181         *  whose component type is the same as the element.</p>
4182         *
4183         * <pre>
4184         * ArrayUtils.add([1], 0, 2)         = [2, 1]
4185         * ArrayUtils.add([2, 6], 2, 10)     = [2, 6, 10]
4186         * ArrayUtils.add([2, 6], 0, -4)     = [-4, 2, 6]
4187         * ArrayUtils.add([2, 6, 3], 2, 1)   = [2, 6, 1, 3]
4188         * </pre>
4189         *
4190         * @param array  the array to add the element to, may be <code>null</code>
4191         * @param index  the position of the new object
4192         * @param element  the object to add
4193         * @return A new array containing the existing elements and the new element
4194         * @throws IndexOutOfBoundsException if the index is out of range
4195         * (index < 0 || index > array.length).
4196         */
4197        public static int[] add(int[] array, int index, int element) {
4198            return (int[]) add(array, index, Integer.valueOf(element), Integer.TYPE);
4199        }
4200    
4201        /**
4202         * <p>Inserts the specified element at the specified position in the array.
4203         * Shifts the element currently at that position (if any) and any subsequent
4204         * elements to the right (adds one to their indices).</p>
4205         *
4206         * <p>This method returns a new array with the same elements of the input
4207         * array plus the given element on the specified position. The component
4208         * type of the returned array is always the same as that of the input
4209         * array.</p>
4210         *
4211         * <p>If the input array is <code>null</code>, a new one element array is returned
4212         *  whose component type is the same as the element.</p>
4213         *
4214         * <pre>
4215         * ArrayUtils.add([1L], 0, 2L)           = [2L, 1L]
4216         * ArrayUtils.add([2L, 6L], 2, 10L)      = [2L, 6L, 10L]
4217         * ArrayUtils.add([2L, 6L], 0, -4L)      = [-4L, 2L, 6L]
4218         * ArrayUtils.add([2L, 6L, 3L], 2, 1L)   = [2L, 6L, 1L, 3L]
4219         * </pre>
4220         *
4221         * @param array  the array to add the element to, may be <code>null</code>
4222         * @param index  the position of the new object
4223         * @param element  the object to add
4224         * @return A new array containing the existing elements and the new element
4225         * @throws IndexOutOfBoundsException if the index is out of range
4226         * (index < 0 || index > array.length).
4227         */
4228        public static long[] add(long[] array, int index, long element) {
4229            return (long[]) add(array, index, Long.valueOf(element), Long.TYPE);
4230        }
4231    
4232        /**
4233         * <p>Inserts the specified element at the specified position in the array.
4234         * Shifts the element currently at that position (if any) and any subsequent
4235         * elements to the right (adds one to their indices).</p>
4236         *
4237         * <p>This method returns a new array with the same elements of the input
4238         * array plus the given element on the specified position. The component
4239         * type of the returned array is always the same as that of the input
4240         * array.</p>
4241         *
4242         * <p>If the input array is <code>null</code>, a new one element array is returned
4243         *  whose component type is the same as the element.</p>
4244         *
4245         * <pre>
4246         * ArrayUtils.add([1.1f], 0, 2.2f)               = [2.2f, 1.1f]
4247         * ArrayUtils.add([2.3f, 6.4f], 2, 10.5f)        = [2.3f, 6.4f, 10.5f]
4248         * ArrayUtils.add([2.6f, 6.7f], 0, -4.8f)        = [-4.8f, 2.6f, 6.7f]
4249         * ArrayUtils.add([2.9f, 6.0f, 0.3f], 2, 1.0f)   = [2.9f, 6.0f, 1.0f, 0.3f]
4250         * </pre>
4251         *
4252         * @param array  the array to add the element to, may be <code>null</code>
4253         * @param index  the position of the new object
4254         * @param element  the object to add
4255         * @return A new array containing the existing elements and the new element
4256         * @throws IndexOutOfBoundsException if the index is out of range
4257         * (index < 0 || index > array.length).
4258         */
4259        public static float[] add(float[] array, int index, float element) {
4260            return (float[]) add(array, index, Float.valueOf(element), Float.TYPE);
4261        }
4262    
4263        /**
4264         * <p>Inserts the specified element at the specified position in the array.
4265         * Shifts the element currently at that position (if any) and any subsequent
4266         * elements to the right (adds one to their indices).</p>
4267         *
4268         * <p>This method returns a new array with the same elements of the input
4269         * array plus the given element on the specified position. The component
4270         * type of the returned array is always the same as that of the input
4271         * array.</p>
4272         *
4273         * <p>If the input array is <code>null</code>, a new one element array is returned
4274         *  whose component type is the same as the element.</p>
4275         *
4276         * <pre>
4277         * ArrayUtils.add([1.1], 0, 2.2)              = [2.2, 1.1]
4278         * ArrayUtils.add([2.3, 6.4], 2, 10.5)        = [2.3, 6.4, 10.5]
4279         * ArrayUtils.add([2.6, 6.7], 0, -4.8)        = [-4.8, 2.6, 6.7]
4280         * ArrayUtils.add([2.9, 6.0, 0.3], 2, 1.0)    = [2.9, 6.0, 1.0, 0.3]
4281         * </pre>
4282         *
4283         * @param array  the array to add the element to, may be <code>null</code>
4284         * @param index  the position of the new object
4285         * @param element  the object to add
4286         * @return A new array containing the existing elements and the new element
4287         * @throws IndexOutOfBoundsException if the index is out of range
4288         * (index < 0 || index > array.length).
4289         */
4290        public static double[] add(double[] array, int index, double element) {
4291            return (double[]) add(array, index, Double.valueOf(element), Double.TYPE);
4292        }
4293    
4294        /**
4295         * Underlying implementation of add(array, index, element) methods.
4296         * The last parameter is the class, which may not equal element.getClass
4297         * for primitives.
4298         *
4299         * @param array  the array to add the element to, may be <code>null</code>
4300         * @param index  the position of the new object
4301         * @param element  the object to add
4302         * @param clss the type of the element being added
4303         * @return A new array containing the existing elements and the new element
4304         */
4305        private static Object add(Object array, int index, Object element, Class<?> clss) {
4306            if (array == null) {
4307                if (index != 0) {
4308                    throw new IndexOutOfBoundsException("Index: " + index + ", Length: 0");
4309                }
4310                Object joinedArray = Array.newInstance(clss, 1);
4311                Array.set(joinedArray, 0, element);
4312                return joinedArray;
4313            }
4314            int length = Array.getLength(array);
4315            if (index > length || index < 0) {
4316                throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
4317            }
4318            Object result = Array.newInstance(clss, length + 1);
4319            System.arraycopy(array, 0, result, 0, index);
4320            Array.set(result, index, element);
4321            if (index < length) {
4322                System.arraycopy(array, index, result, index + 1, length - index);
4323            }
4324            return result;
4325        }
4326    
4327        /**
4328         * <p>Removes the element at the specified position from the specified array.
4329         * All subsequent elements are shifted to the left (substracts one from
4330         * their indices).</p>
4331         *
4332         * <p>This method returns a new array with the same elements of the input
4333         * array except the element on the specified position. The component
4334         * type of the returned array is always the same as that of the input
4335         * array.</p>
4336         *
4337         * <p>If the input array is <code>null</code>, an IndexOutOfBoundsException
4338         * will be thrown, because in that case no valid index can be specified.</p>
4339         *
4340         * <pre>
4341         * ArrayUtils.remove(["a"], 0)           = []
4342         * ArrayUtils.remove(["a", "b"], 0)      = ["b"]
4343         * ArrayUtils.remove(["a", "b"], 1)      = ["a"]
4344         * ArrayUtils.remove(["a", "b", "c"], 1) = ["a", "c"]
4345         * </pre>
4346         *
4347         * @param array  the array to remove the element from, may not be <code>null</code>
4348         * @param index  the position of the element to be removed
4349         * @return A new array containing the existing elements except the element
4350         *         at the specified position.
4351         * @throws IndexOutOfBoundsException if the index is out of range
4352         * (index < 0 || index >= array.length), or if the array is <code>null</code>.
4353         * @since 2.1
4354         */
4355        @SuppressWarnings("unchecked") // remove() always creates an array of the same type as its input
4356        public static <T> T[] remove(T[] array, int index) {
4357            return (T[]) remove((Object) array, index);
4358        }
4359    
4360        /**
4361         * <p>Removes the first occurrence of the specified element from the
4362         * specified array. All subsequent elements are shifted to the left
4363         * (substracts one from their indices). If the array doesn't contains
4364         * such an element, no elements are removed from the array.</p>
4365         *
4366         * <p>This method returns a new array with the same elements of the input
4367         * array except the first occurrence of the specified element. The component
4368         * type of the returned array is always the same as that of the input
4369         * array.</p>
4370         *
4371         * <pre>
4372         * ArrayUtils.removeElement(null, "a")            = null
4373         * ArrayUtils.removeElement([], "a")              = []
4374         * ArrayUtils.removeElement(["a"], "b")           = ["a"]
4375         * ArrayUtils.removeElement(["a", "b"], "a")      = ["b"]
4376         * ArrayUtils.removeElement(["a", "b", "a"], "a") = ["b", "a"]
4377         * </pre>
4378         *
4379         * @param array  the array to remove the element from, may be <code>null</code>
4380         * @param element  the element to be removed
4381         * @return A new array containing the existing elements except the first
4382         *         occurrence of the specified element.
4383         * @since 2.1
4384         */
4385        public static <T> T[] removeElement(T[] array, Object element) {
4386            int index = indexOf(array, element);
4387            if (index == INDEX_NOT_FOUND) {
4388                return clone(array);
4389            }
4390            return remove(array, index);
4391        }
4392    
4393        /**
4394         * <p>Removes the element at the specified position from the specified array.
4395         * All subsequent elements are shifted to the left (substracts one from
4396         * their indices).</p>
4397         *
4398         * <p>This method returns a new array with the same elements of the input
4399         * array except the element on the specified position. The component
4400         * type of the returned array is always the same as that of the input
4401         * array.</p>
4402         *
4403         * <p>If the input array is <code>null</code>, an IndexOutOfBoundsException
4404         * will be thrown, because in that case no valid index can be specified.</p>
4405         *
4406         * <pre>
4407         * ArrayUtils.remove([true], 0)              = []
4408         * ArrayUtils.remove([true, false], 0)       = [false]
4409         * ArrayUtils.remove([true, false], 1)       = [true]
4410         * ArrayUtils.remove([true, true, false], 1) = [true, false]
4411         * </pre>
4412         *
4413         * @param array  the array to remove the element from, may not be <code>null</code>
4414         * @param index  the position of the element to be removed
4415         * @return A new array containing the existing elements except the element
4416         *         at the specified position.
4417         * @throws IndexOutOfBoundsException if the index is out of range
4418         * (index < 0 || index >= array.length), or if the array is <code>null</code>.
4419         * @since 2.1
4420         */
4421        public static boolean[] remove(boolean[] array, int index) {
4422            return (boolean[]) remove((Object) array, index);
4423        }
4424    
4425        /**
4426         * <p>Removes the first occurrence of the specified element from the
4427         * specified array. All subsequent elements are shifted to the left
4428         * (substracts one from their indices). If the array doesn't contains
4429         * such an element, no elements are removed from the array.</p>
4430         *
4431         * <p>This method returns a new array with the same elements of the input
4432         * array except the first occurrence of the specified element. The component
4433         * type of the returned array is always the same as that of the input
4434         * array.</p>
4435         *
4436         * <pre>
4437         * ArrayUtils.removeElement(null, true)                = null
4438         * ArrayUtils.removeElement([], true)                  = []
4439         * ArrayUtils.removeElement([true], false)             = [true]
4440         * ArrayUtils.removeElement([true, false], false)      = [true]
4441         * ArrayUtils.removeElement([true, false, true], true) = [false, true]
4442         * </pre>
4443         *
4444         * @param array  the array to remove the element from, may be <code>null</code>
4445         * @param element  the element to be removed
4446         * @return A new array containing the existing elements except the first
4447         *         occurrence of the specified element.
4448         * @since 2.1
4449         */
4450        public static boolean[] removeElement(boolean[] array, boolean element) {
4451            int index = indexOf(array, element);
4452            if (index == INDEX_NOT_FOUND) {
4453                return clone(array);
4454            }
4455            return remove(array, index);
4456        }
4457    
4458        /**
4459         * <p>Removes the element at the specified position from the specified array.
4460         * All subsequent elements are shifted to the left (substracts one from
4461         * their indices).</p>
4462         *
4463         * <p>This method returns a new array with the same elements of the input
4464         * array except the element on the specified position. The component
4465         * type of the returned array is always the same as that of the input
4466         * array.</p>
4467         *
4468         * <p>If the input array is <code>null</code>, an IndexOutOfBoundsException
4469         * will be thrown, because in that case no valid index can be specified.</p>
4470         *
4471         * <pre>
4472         * ArrayUtils.remove([1], 0)          = []
4473         * ArrayUtils.remove([1, 0], 0)       = [0]
4474         * ArrayUtils.remove([1, 0], 1)       = [1]
4475         * ArrayUtils.remove([1, 0, 1], 1)    = [1, 1]
4476         * </pre>
4477         *
4478         * @param array  the array to remove the element from, may not be <code>null</code>
4479         * @param index  the position of the element to be removed
4480         * @return A new array containing the existing elements except the element
4481         *         at the specified position.
4482         * @throws IndexOutOfBoundsException if the index is out of range
4483         * (index < 0 || index >= array.length), or if the array is <code>null</code>.
4484         * @since 2.1
4485         */
4486        public static byte[] remove(byte[] array, int index) {
4487            return (byte[]) remove((Object) array, index);
4488        }
4489    
4490        /**
4491         * <p>Removes the first occurrence of the specified element from the
4492         * specified array. All subsequent elements are shifted to the left
4493         * (substracts one from their indices). If the array doesn't contains
4494         * such an element, no elements are removed from the array.</p>
4495         *
4496         * <p>This method returns a new array with the same elements of the input
4497         * array except the first occurrence of the specified element. The component
4498         * type of the returned array is always the same as that of the input
4499         * array.</p>
4500         *
4501         * <pre>
4502         * ArrayUtils.removeElement(null, 1)        = null
4503         * ArrayUtils.removeElement([], 1)          = []
4504         * ArrayUtils.removeElement([1], 0)         = [1]
4505         * ArrayUtils.removeElement([1, 0], 0)      = [1]
4506         * ArrayUtils.removeElement([1, 0, 1], 1)   = [0, 1]
4507         * </pre>
4508         *
4509         * @param array  the array to remove the element from, may be <code>null</code>
4510         * @param element  the element to be removed
4511         * @return A new array containing the existing elements except the first
4512         *         occurrence of the specified element.
4513         * @since 2.1
4514         */
4515        public static byte[] removeElement(byte[] array, byte element) {
4516            int index = indexOf(array, element);
4517            if (index == INDEX_NOT_FOUND) {
4518                return clone(array);
4519            }
4520            return remove(array, index);
4521        }
4522    
4523        /**
4524         * <p>Removes the element at the specified position from the specified array.
4525         * All subsequent elements are shifted to the left (substracts one from
4526         * their indices).</p>
4527         *
4528         * <p>This method returns a new array with the same elements of the input
4529         * array except the element on the specified position. The component
4530         * type of the returned array is always the same as that of the input
4531         * array.</p>
4532         *
4533         * <p>If the input array is <code>null</code>, an IndexOutOfBoundsException
4534         * will be thrown, because in that case no valid index can be specified.</p>
4535         *
4536         * <pre>
4537         * ArrayUtils.remove(['a'], 0)           = []
4538         * ArrayUtils.remove(['a', 'b'], 0)      = ['b']
4539         * ArrayUtils.remove(['a', 'b'], 1)      = ['a']
4540         * ArrayUtils.remove(['a', 'b', 'c'], 1) = ['a', 'c']
4541         * </pre>
4542         *
4543         * @param array  the array to remove the element from, may not be <code>null</code>
4544         * @param index  the position of the element to be removed
4545         * @return A new array containing the existing elements except the element
4546         *         at the specified position.
4547         * @throws IndexOutOfBoundsException if the index is out of range
4548         * (index < 0 || index >= array.length), or if the array is <code>null</code>.
4549         * @since 2.1
4550         */
4551        public static char[] remove(char[] array, int index) {
4552            return (char[]) remove((Object) array, index);
4553        }
4554    
4555        /**
4556         * <p>Removes the first occurrence of the specified element from the
4557         * specified array. All subsequent elements are shifted to the left
4558         * (substracts one from their indices). If the array doesn't contains
4559         * such an element, no elements are removed from the array.</p>
4560         *
4561         * <p>This method returns a new array with the same elements of the input
4562         * array except the first occurrence of the specified element. The component
4563         * type of the returned array is always the same as that of the input
4564         * array.</p>
4565         *
4566         * <pre>
4567         * ArrayUtils.removeElement(null, 'a')            = null
4568         * ArrayUtils.removeElement([], 'a')              = []
4569         * ArrayUtils.removeElement(['a'], 'b')           = ['a']
4570         * ArrayUtils.removeElement(['a', 'b'], 'a')      = ['b']
4571         * ArrayUtils.removeElement(['a', 'b', 'a'], 'a') = ['b', 'a']
4572         * </pre>
4573         *
4574         * @param array  the array to remove the element from, may be <code>null</code>
4575         * @param element  the element to be removed
4576         * @return A new array containing the existing elements except the first
4577         *         occurrence of the specified element.
4578         * @since 2.1
4579         */
4580        public static char[] removeElement(char[] array, char element) {
4581            int index = indexOf(array, element);
4582            if (index == INDEX_NOT_FOUND) {
4583                return clone(array);
4584            }
4585            return remove(array, index);
4586        }
4587    
4588        /**
4589         * <p>Removes the element at the specified position from the specified array.
4590         * All subsequent elements are shifted to the left (substracts one from
4591         * their indices).</p>
4592         *
4593         * <p>This method returns a new array with the same elements of the input
4594         * array except the element on the specified position. The component
4595         * type of the returned array is always the same as that of the input
4596         * array.</p>
4597         *
4598         * <p>If the input array is <code>null</code>, an IndexOutOfBoundsException
4599         * will be thrown, because in that case no valid index can be specified.</p>
4600         *
4601         * <pre>
4602         * ArrayUtils.remove([1.1], 0)           = []
4603         * ArrayUtils.remove([2.5, 6.0], 0)      = [6.0]
4604         * ArrayUtils.remove([2.5, 6.0], 1)      = [2.5]
4605         * ArrayUtils.remove([2.5, 6.0, 3.8], 1) = [2.5, 3.8]
4606         * </pre>
4607         *
4608         * @param array  the array to remove the element from, may not be <code>null</code>
4609         * @param index  the position of the element to be removed
4610         * @return A new array containing the existing elements except the element
4611         *         at the specified position.
4612         * @throws IndexOutOfBoundsException if the index is out of range
4613         * (index < 0 || index >= array.length), or if the array is <code>null</code>.
4614         * @since 2.1
4615         */
4616        public static double[] remove(double[] array, int index) {
4617            return (double[]) remove((Object) array, index);
4618        }
4619    
4620        /**
4621         * <p>Removes the first occurrence of the specified element from the
4622         * specified array. All subsequent elements are shifted to the left
4623         * (substracts one from their indices). If the array doesn't contains
4624         * such an element, no elements are removed from the array.</p>
4625         *
4626         * <p>This method returns a new array with the same elements of the input
4627         * array except the first occurrence of the specified element. The component
4628         * type of the returned array is always the same as that of the input
4629         * array.</p>
4630         *
4631         * <pre>
4632         * ArrayUtils.removeElement(null, 1.1)            = null
4633         * ArrayUtils.removeElement([], 1.1)              = []
4634         * ArrayUtils.removeElement([1.1], 1.2)           = [1.1]
4635         * ArrayUtils.removeElement([1.1, 2.3], 1.1)      = [2.3]
4636         * ArrayUtils.removeElement([1.1, 2.3, 1.1], 1.1) = [2.3, 1.1]
4637         * </pre>
4638         *
4639         * @param array  the array to remove the element from, may be <code>null</code>
4640         * @param element  the element to be removed
4641         * @return A new array containing the existing elements except the first
4642         *         occurrence of the specified element.
4643         * @since 2.1
4644         */
4645        public static double[] removeElement(double[] array, double element) {
4646            int index = indexOf(array, element);
4647            if (index == INDEX_NOT_FOUND) {
4648                return clone(array);
4649            }
4650            return remove(array, index);
4651        }
4652    
4653        /**
4654         * <p>Removes the element at the specified position from the specified array.
4655         * All subsequent elements are shifted to the left (substracts one from
4656         * their indices).</p>
4657         *
4658         * <p>This method returns a new array with the same elements of the input
4659         * array except the element on the specified position. The component
4660         * type of the returned array is always the same as that of the input
4661         * array.</p>
4662         *
4663         * <p>If the input array is <code>null</code>, an IndexOutOfBoundsException
4664         * will be thrown, because in that case no valid index can be specified.</p>
4665         *
4666         * <pre>
4667         * ArrayUtils.remove([1.1], 0)           = []
4668         * ArrayUtils.remove([2.5, 6.0], 0)      = [6.0]
4669         * ArrayUtils.remove([2.5, 6.0], 1)      = [2.5]
4670         * ArrayUtils.remove([2.5, 6.0, 3.8], 1) = [2.5, 3.8]
4671         * </pre>
4672         *
4673         * @param array  the array to remove the element from, may not be <code>null</code>
4674         * @param index  the position of the element to be removed
4675         * @return A new array containing the existing elements except the element
4676         *         at the specified position.
4677         * @throws IndexOutOfBoundsException if the index is out of range
4678         * (index < 0 || index >= array.length), or if the array is <code>null</code>.
4679         * @since 2.1
4680         */
4681        public static float[] remove(float[] array, int index) {
4682            return (float[]) remove((Object) array, index);
4683        }
4684    
4685        /**
4686         * <p>Removes the first occurrence of the specified element from the
4687         * specified array. All subsequent elements are shifted to the left
4688         * (substracts one from their indices). If the array doesn't contains
4689         * such an element, no elements are removed from the array.</p>
4690         *
4691         * <p>This method returns a new array with the same elements of the input
4692         * array except the first occurrence of the specified element. The component
4693         * type of the returned array is always the same as that of the input
4694         * array.</p>
4695         *
4696         * <pre>
4697         * ArrayUtils.removeElement(null, 1.1)            = null
4698         * ArrayUtils.removeElement([], 1.1)              = []
4699         * ArrayUtils.removeElement([1.1], 1.2)           = [1.1]
4700         * ArrayUtils.removeElement([1.1, 2.3], 1.1)      = [2.3]
4701         * ArrayUtils.removeElement([1.1, 2.3, 1.1], 1.1) = [2.3, 1.1]
4702         * </pre>
4703         *
4704         * @param array  the array to remove the element from, may be <code>null</code>
4705         * @param element  the element to be removed
4706         * @return A new array containing the existing elements except the first
4707         *         occurrence of the specified element.
4708         * @since 2.1
4709         */
4710        public static float[] removeElement(float[] array, float element) {
4711            int index = indexOf(array, element);
4712            if (index == INDEX_NOT_FOUND) {
4713                return clone(array);
4714            }
4715            return remove(array, index);
4716        }
4717    
4718        /**
4719         * <p>Removes the element at the specified position from the specified array.
4720         * All subsequent elements are shifted to the left (substracts one from
4721         * their indices).</p>
4722         *
4723         * <p>This method returns a new array with the same elements of the input
4724         * array except the element on the specified position. The component
4725         * type of the returned array is always the same as that of the input
4726         * array.</p>
4727         *
4728         * <p>If the input array is <code>null</code>, an IndexOutOfBoundsException
4729         * will be thrown, because in that case no valid index can be specified.</p>
4730         *
4731         * <pre>
4732         * ArrayUtils.remove([1], 0)         = []
4733         * ArrayUtils.remove([2, 6], 0)      = [6]
4734         * ArrayUtils.remove([2, 6], 1)      = [2]
4735         * ArrayUtils.remove([2, 6, 3], 1)   = [2, 3]
4736         * </pre>
4737         *
4738         * @param array  the array to remove the element from, may not be <code>null</code>
4739         * @param index  the position of the element to be removed
4740         * @return A new array containing the existing elements except the element
4741         *         at the specified position.
4742         * @throws IndexOutOfBoundsException if the index is out of range
4743         * (index < 0 || index >= array.length), or if the array is <code>null</code>.
4744         * @since 2.1
4745         */
4746        public static int[] remove(int[] array, int index) {
4747            return (int[]) remove((Object) array, index);
4748        }
4749    
4750        /**
4751         * <p>Removes the first occurrence of the specified element from the
4752         * specified array. All subsequent elements are shifted to the left
4753         * (substracts one from their indices). If the array doesn't contains
4754         * such an element, no elements are removed from the array.</p>
4755         *
4756         * <p>This method returns a new array with the same elements of the input
4757         * array except the first occurrence of the specified element. The component
4758         * type of the returned array is always the same as that of the input
4759         * array.</p>
4760         *
4761         * <pre>
4762         * ArrayUtils.removeElement(null, 1)      = null
4763         * ArrayUtils.removeElement([], 1)        = []
4764         * ArrayUtils.removeElement([1], 2)       = [1]
4765         * ArrayUtils.removeElement([1, 3], 1)    = [3]
4766         * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
4767         * </pre>
4768         *
4769         * @param array  the array to remove the element from, may be <code>null</code>
4770         * @param element  the element to be removed
4771         * @return A new array containing the existing elements except the first
4772         *         occurrence of the specified element.
4773         * @since 2.1
4774         */
4775        public static int[] removeElement(int[] array, int element) {
4776            int index = indexOf(array, element);
4777            if (index == INDEX_NOT_FOUND) {
4778                return clone(array);
4779            }
4780            return remove(array, index);
4781        }
4782    
4783        /**
4784         * <p>Removes the element at the specified position from the specified array.
4785         * All subsequent elements are shifted to the left (substracts one from
4786         * their indices).</p>
4787         *
4788         * <p>This method returns a new array with the same elements of the input
4789         * array except the element on the specified position. The component
4790         * type of the returned array is always the same as that of the input
4791         * array.</p>
4792         *
4793         * <p>If the input array is <code>null</code>, an IndexOutOfBoundsException
4794         * will be thrown, because in that case no valid index can be specified.</p>
4795         *
4796         * <pre>
4797         * ArrayUtils.remove([1], 0)         = []
4798         * ArrayUtils.remove([2, 6], 0)      = [6]
4799         * ArrayUtils.remove([2, 6], 1)      = [2]
4800         * ArrayUtils.remove([2, 6, 3], 1)   = [2, 3]
4801         * </pre>
4802         *
4803         * @param array  the array to remove the element from, may not be <code>null</code>
4804         * @param index  the position of the element to be removed
4805         * @return A new array containing the existing elements except the element
4806         *         at the specified position.
4807         * @throws IndexOutOfBoundsException if the index is out of range
4808         * (index < 0 || index >= array.length), or if the array is <code>null</code>.
4809         * @since 2.1
4810         */
4811        public static long[] remove(long[] array, int index) {
4812            return (long[]) remove((Object) array, index);
4813        }
4814    
4815        /**
4816         * <p>Removes the first occurrence of the specified element from the
4817         * specified array. All subsequent elements are shifted to the left
4818         * (substracts one from their indices). If the array doesn't contains
4819         * such an element, no elements are removed from the array.</p>
4820         *
4821         * <p>This method returns a new array with the same elements of the input
4822         * array except the first occurrence of the specified element. The component
4823         * type of the returned array is always the same as that of the input
4824         * array.</p>
4825         *
4826         * <pre>
4827         * ArrayUtils.removeElement(null, 1)      = null
4828         * ArrayUtils.removeElement([], 1)        = []
4829         * ArrayUtils.removeElement([1], 2)       = [1]
4830         * ArrayUtils.removeElement([1, 3], 1)    = [3]
4831         * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
4832         * </pre>
4833         *
4834         * @param array  the array to remove the element from, may be <code>null</code>
4835         * @param element  the element to be removed
4836         * @return A new array containing the existing elements except the first
4837         *         occurrence of the specified element.
4838         * @since 2.1
4839         */
4840        public static long[] removeElement(long[] array, long element) {
4841            int index = indexOf(array, element);
4842            if (index == INDEX_NOT_FOUND) {
4843                return clone(array);
4844            }
4845            return remove(array, index);
4846        }
4847    
4848        /**
4849         * <p>Removes the element at the specified position from the specified array.
4850         * All subsequent elements are shifted to the left (substracts one from
4851         * their indices).</p>
4852         *
4853         * <p>This method returns a new array with the same elements of the input
4854         * array except the element on the specified position. The component
4855         * type of the returned array is always the same as that of the input
4856         * array.</p>
4857         *
4858         * <p>If the input array is <code>null</code>, an IndexOutOfBoundsException
4859         * will be thrown, because in that case no valid index can be specified.</p>
4860         *
4861         * <pre>
4862         * ArrayUtils.remove([1], 0)         = []
4863         * ArrayUtils.remove([2, 6], 0)      = [6]
4864         * ArrayUtils.remove([2, 6], 1)      = [2]
4865         * ArrayUtils.remove([2, 6, 3], 1)   = [2, 3]
4866         * </pre>
4867         *
4868         * @param array  the array to remove the element from, may not be <code>null</code>
4869         * @param index  the position of the element to be removed
4870         * @return A new array containing the existing elements except the element
4871         *         at the specified position.
4872         * @throws IndexOutOfBoundsException if the index is out of range
4873         * (index < 0 || index >= array.length), or if the array is <code>null</code>.
4874         * @since 2.1
4875         */
4876        public static short[] remove(short[] array, int index) {
4877            return (short[]) remove((Object) array, index);
4878        }
4879    
4880        /**
4881         * <p>Removes the first occurrence of the specified element from the
4882         * specified array. All subsequent elements are shifted to the left
4883         * (substracts one from their indices). If the array doesn't contains
4884         * such an element, no elements are removed from the array.</p>
4885         *
4886         * <p>This method returns a new array with the same elements of the input
4887         * array except the first occurrence of the specified element. The component
4888         * type of the returned array is always the same as that of the input
4889         * array.</p>
4890         *
4891         * <pre>
4892         * ArrayUtils.removeElement(null, 1)      = null
4893         * ArrayUtils.removeElement([], 1)        = []
4894         * ArrayUtils.removeElement([1], 2)       = [1]
4895         * ArrayUtils.removeElement([1, 3], 1)    = [3]
4896         * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
4897         * </pre>
4898         *
4899         * @param array  the array to remove the element from, may be <code>null</code>
4900         * @param element  the element to be removed
4901         * @return A new array containing the existing elements except the first
4902         *         occurrence of the specified element.
4903         * @since 2.1
4904         */
4905        public static short[] removeElement(short[] array, short element) {
4906            int index = indexOf(array, element);
4907            if (index == INDEX_NOT_FOUND) {
4908                return clone(array);
4909            }
4910            return remove(array, index);
4911        }
4912    
4913        /**
4914         * <p>Removes the element at the specified position from the specified array.
4915         * All subsequent elements are shifted to the left (substracts one from
4916         * their indices).</p>
4917         *
4918         * <p>This method returns a new array with the same elements of the input
4919         * array except the element on the specified position. The component
4920         * type of the returned array is always the same as that of the input
4921         * array.</p>
4922         *
4923         * <p>If the input array is <code>null</code>, an IndexOutOfBoundsException
4924         * will be thrown, because in that case no valid index can be specified.</p>
4925         *
4926         * @param array  the array to remove the element from, may not be <code>null</code>
4927         * @param index  the position of the element to be removed
4928         * @return A new array containing the existing elements except the element
4929         *         at the specified position.
4930         * @throws IndexOutOfBoundsException if the index is out of range
4931         * (index < 0 || index >= array.length), or if the array is <code>null</code>.
4932         * @since 2.1
4933         */
4934        private static Object remove(Object array, int index) {
4935            int length = getLength(array);
4936            if (index < 0 || index >= length) {
4937                throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
4938            }
4939    
4940            Object result = Array.newInstance(array.getClass().getComponentType(), length - 1);
4941            System.arraycopy(array, 0, result, 0, index);
4942            if (index < length - 1) {
4943                System.arraycopy(array, index + 1, result, index, length - index - 1);
4944            }
4945    
4946            return result;
4947        }
4948    
4949    }