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