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