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