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