ArrayUtils.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      https://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.apache.commons.lang3;

  18. import java.lang.reflect.Array;
  19. import java.lang.reflect.Field;
  20. import java.lang.reflect.Method;
  21. import java.lang.reflect.Type;
  22. import java.security.SecureRandom;
  23. import java.util.Arrays;
  24. import java.util.BitSet;
  25. import java.util.Comparator;
  26. import java.util.Date;
  27. import java.util.HashMap;
  28. import java.util.Map;
  29. import java.util.Objects;
  30. import java.util.Random;
  31. import java.util.concurrent.ThreadLocalRandom;
  32. import java.util.function.Function;
  33. import java.util.function.IntFunction;
  34. import java.util.function.Supplier;

  35. import org.apache.commons.lang3.builder.EqualsBuilder;
  36. import org.apache.commons.lang3.builder.HashCodeBuilder;
  37. import org.apache.commons.lang3.builder.ToStringBuilder;
  38. import org.apache.commons.lang3.builder.ToStringStyle;
  39. import org.apache.commons.lang3.function.FailableFunction;
  40. import org.apache.commons.lang3.math.NumberUtils;
  41. import org.apache.commons.lang3.mutable.MutableInt;
  42. import org.apache.commons.lang3.stream.IntStreams;
  43. import org.apache.commons.lang3.stream.Streams;

  44. /**
  45.  * Operations on arrays, primitive arrays (like {@code int[]}) and
  46.  * primitive wrapper arrays (like {@code Integer[]}).
  47.  * <p>
  48.  * This class tries to handle {@code null} input gracefully.
  49.  * An exception will not be thrown for a {@code null}
  50.  * array input. However, an Object array that contains a {@code null}
  51.  * element may throw an exception. Each method documents its behavior.
  52.  * </p>
  53.  * <p>
  54.  * #ThreadSafe#
  55.  * </p>
  56.  * @since 2.0
  57.  */
  58. public class ArrayUtils {

  59.     /**
  60.      * An empty immutable {@code boolean} array.
  61.      */
  62.     public static final boolean[] EMPTY_BOOLEAN_ARRAY = {};

  63.     /**
  64.      * An empty immutable {@link Boolean} array.
  65.      */
  66.     public static final Boolean[] EMPTY_BOOLEAN_OBJECT_ARRAY = {};

  67.     /**
  68.      * An empty immutable {@code byte} array.
  69.      */
  70.     public static final byte[] EMPTY_BYTE_ARRAY = {};

  71.     /**
  72.      * An empty immutable {@link Byte} array.
  73.      */
  74.     public static final Byte[] EMPTY_BYTE_OBJECT_ARRAY = {};

  75.     /**
  76.      * An empty immutable {@code char} array.
  77.      */
  78.     public static final char[] EMPTY_CHAR_ARRAY = {};

  79.     /**
  80.      * An empty immutable {@link Character} array.
  81.      */
  82.     public static final Character[] EMPTY_CHARACTER_OBJECT_ARRAY = {};

  83.     /**
  84.      * An empty immutable {@link Class} array.
  85.      */
  86.     public static final Class<?>[] EMPTY_CLASS_ARRAY = {};

  87.     /**
  88.      * An empty immutable {@code double} array.
  89.      */
  90.     public static final double[] EMPTY_DOUBLE_ARRAY = {};

  91.     /**
  92.      * An empty immutable {@link Double} array.
  93.      */
  94.     public static final Double[] EMPTY_DOUBLE_OBJECT_ARRAY = {};

  95.     /**
  96.      * An empty immutable {@link Field} array.
  97.      *
  98.      * @since 3.10
  99.      */
  100.     public static final Field[] EMPTY_FIELD_ARRAY = {};

  101.     /**
  102.      * An empty immutable {@code float} array.
  103.      */
  104.     public static final float[] EMPTY_FLOAT_ARRAY = {};

  105.     /**
  106.      * An empty immutable {@link Float} array.
  107.      */
  108.     public static final Float[] EMPTY_FLOAT_OBJECT_ARRAY = {};

  109.     /**
  110.      * An empty immutable {@code int} array.
  111.      */
  112.     public static final int[] EMPTY_INT_ARRAY = {};

  113.     /**
  114.      * An empty immutable {@link Integer} array.
  115.      */
  116.     public static final Integer[] EMPTY_INTEGER_OBJECT_ARRAY = {};

  117.     /**
  118.      * An empty immutable {@code long} array.
  119.      */
  120.     public static final long[] EMPTY_LONG_ARRAY = {};

  121.     /**
  122.      * An empty immutable {@link Long} array.
  123.      */
  124.     public static final Long[] EMPTY_LONG_OBJECT_ARRAY = {};

  125.     /**
  126.      * An empty immutable {@link Method} array.
  127.      *
  128.      * @since 3.10
  129.      */
  130.     public static final Method[] EMPTY_METHOD_ARRAY = {};

  131.     /**
  132.      * An empty immutable {@link Object} array.
  133.      */
  134.     public static final Object[] EMPTY_OBJECT_ARRAY = {};

  135.     /**
  136.      * An empty immutable {@code short} array.
  137.      */
  138.     public static final short[] EMPTY_SHORT_ARRAY = {};

  139.     /**
  140.      * An empty immutable {@link Short} array.
  141.      */
  142.     public static final Short[] EMPTY_SHORT_OBJECT_ARRAY = {};

  143.     /**
  144.      * An empty immutable {@link String} array.
  145.      */
  146.     public static final String[] EMPTY_STRING_ARRAY = {};

  147.     /**
  148.      * An empty immutable {@link Throwable} array.
  149.      *
  150.      * @since 3.10
  151.      */
  152.     public static final Throwable[] EMPTY_THROWABLE_ARRAY = {};

  153.     /**
  154.      * An empty immutable {@link Type} array.
  155.      *
  156.      * @since 3.10
  157.      */
  158.     public static final Type[] EMPTY_TYPE_ARRAY = {};

  159.     /**
  160.      * The index value when an element is not found in a list or array: {@code -1}.
  161.      * This value is returned by methods in this class and can also be used in comparisons with values returned by
  162.      * various method from {@link java.util.List}.
  163.      */
  164.     public static final int INDEX_NOT_FOUND = -1;

  165.     /**
  166.      * Copies the given array and adds the given element at the end of the new array.
  167.      * <p>
  168.      * The new array contains the same elements of the input
  169.      * array plus the given element in the last position. The component type of
  170.      * the new array is the same as that of the input array.
  171.      * </p>
  172.      * <p>
  173.      * If the input array is {@code null}, a new one element array is returned
  174.      * whose component type is the same as the element.
  175.      * </p>
  176.      * <pre>
  177.      * ArrayUtils.add(null, true)          = [true]
  178.      * ArrayUtils.add([true], false)       = [true, false]
  179.      * ArrayUtils.add([true, false], true) = [true, false, true]
  180.      * </pre>
  181.      *
  182.      * @param array  the array to copy and add the element to, may be {@code null}
  183.      * @param element  the object to add at the last index of the new array
  184.      * @return A new array containing the existing elements plus the new element
  185.      * @since 2.1
  186.      */
  187.     public static boolean[] add(final boolean[] array, final boolean element) {
  188.         final boolean[] newArray = (boolean[]) copyArrayGrow1(array, Boolean.TYPE);
  189.         newArray[newArray.length - 1] = element;
  190.         return newArray;
  191.     }

  192.     /**
  193.      * Inserts the specified element at the specified position in the array.
  194.      * Shifts the element currently at that position (if any) and any subsequent
  195.      * elements to the right (adds one to their indices).
  196.      * <p>
  197.      * This method returns a new array with the same elements of the input
  198.      * array plus the given element on the specified position. The component
  199.      * type of the returned array is always the same as that of the input
  200.      * array.
  201.      * </p>
  202.      * <p>
  203.      * If the input array is {@code null}, a new one element array is returned
  204.      * whose component type is the same as the element.
  205.      * </p>
  206.      * <pre>
  207.      * ArrayUtils.add(null, 0, true)          = [true]
  208.      * ArrayUtils.add([true], 0, false)       = [false, true]
  209.      * ArrayUtils.add([false], 1, true)       = [false, true]
  210.      * ArrayUtils.add([true, false], 1, true) = [true, true, false]
  211.      * </pre>
  212.      *
  213.      * @param array  the array to add the element to, may be {@code null}
  214.      * @param index  the position of the new object
  215.      * @param element  the object to add
  216.      * @return A new array containing the existing elements and the new element
  217.      * @throws IndexOutOfBoundsException if the index is out of range (index &lt; 0 || index &gt; array.length).
  218.      * @deprecated this method has been superseded by {@link #insert(int, boolean[], boolean...)} and
  219.      * may be removed in a future release. Please note the handling of {@code null} input arrays differs
  220.      * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
  221.      */
  222.     @Deprecated
  223.     public static boolean[] add(final boolean[] array, final int index, final boolean element) {
  224.         return (boolean[]) add(array, index, Boolean.valueOf(element), Boolean.TYPE);
  225.     }

  226.     /**
  227.      * Copies the given array and adds the given element at the end of the new array.
  228.      * <p>
  229.      * The new array contains the same elements of the input
  230.      * array plus the given element in the last position. The component type of
  231.      * the new array is the same as that of the input array.
  232.      * </p>
  233.      * <p>
  234.      * If the input array is {@code null}, a new one element array is returned
  235.      * whose component type is the same as the element.
  236.      * </p>
  237.      * <pre>
  238.      * ArrayUtils.add(null, 0)   = [0]
  239.      * ArrayUtils.add([1], 0)    = [1, 0]
  240.      * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
  241.      * </pre>
  242.      *
  243.      * @param array  the array to copy and add the element to, may be {@code null}
  244.      * @param element  the object to add at the last index of the new array
  245.      * @return A new array containing the existing elements plus the new element
  246.      * @since 2.1
  247.      */
  248.     public static byte[] add(final byte[] array, final byte element) {
  249.         final byte[] newArray = (byte[]) copyArrayGrow1(array, Byte.TYPE);
  250.         newArray[newArray.length - 1] = element;
  251.         return newArray;
  252.     }

  253.     /**
  254.      * Inserts the specified element at the specified position in the array.
  255.      * Shifts the element currently at that position (if any) and any subsequent
  256.      * elements to the right (adds one to their indices).
  257.      * <p>
  258.      * This method returns a new array with the same elements of the input
  259.      * array plus the given element on the specified position. The component
  260.      * type of the returned array is always the same as that of the input
  261.      * array.
  262.      * </p>
  263.      * <p>
  264.      * If the input array is {@code null}, a new one element array is returned
  265.      * whose component type is the same as the element.
  266.      * </p>
  267.      * <pre>
  268.      * ArrayUtils.add([1], 0, 2)         = [2, 1]
  269.      * ArrayUtils.add([2, 6], 2, 3)      = [2, 6, 3]
  270.      * ArrayUtils.add([2, 6], 0, 1)      = [1, 2, 6]
  271.      * ArrayUtils.add([2, 6, 3], 2, 1)   = [2, 6, 1, 3]
  272.      * </pre>
  273.      *
  274.      * @param array  the array to add the element to, may be {@code null}
  275.      * @param index  the position of the new object
  276.      * @param element  the object to add
  277.      * @return A new array containing the existing elements and the new element
  278.      * @throws IndexOutOfBoundsException if the index is out of range
  279.      * (index &lt; 0 || index &gt; array.length).
  280.      * @deprecated this method has been superseded by {@link #insert(int, byte[], byte...)} and
  281.      * may be removed in a future release. Please note the handling of {@code null} input arrays differs
  282.      * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
  283.      */
  284.     @Deprecated
  285.     public static byte[] add(final byte[] array, final int index, final byte element) {
  286.         return (byte[]) add(array, index, Byte.valueOf(element), Byte.TYPE);
  287.     }

  288.     /**
  289.      * Copies the given array and adds the given element at the end of the new array.
  290.      * <p>
  291.      * The new array contains the same elements of the input
  292.      * array plus the given element in the last position. The component type of
  293.      * the new array is the same as that of the input array.
  294.      * </p>
  295.      * <p>
  296.      * If the input array is {@code null}, a new one element array is returned
  297.      * whose component type is the same as the element.
  298.      * </p>
  299.      * <pre>
  300.      * ArrayUtils.add(null, '0')       = ['0']
  301.      * ArrayUtils.add(['1'], '0')      = ['1', '0']
  302.      * ArrayUtils.add(['1', '0'], '1') = ['1', '0', '1']
  303.      * </pre>
  304.      *
  305.      * @param array  the array to copy and add the element to, may be {@code null}
  306.      * @param element  the object to add at the last index of the new array
  307.      * @return A new array containing the existing elements plus the new element
  308.      * @since 2.1
  309.      */
  310.     public static char[] add(final char[] array, final char element) {
  311.         final char[] newArray = (char[]) copyArrayGrow1(array, Character.TYPE);
  312.         newArray[newArray.length - 1] = element;
  313.         return newArray;
  314.     }

  315.     /**
  316.      * Inserts the specified element at the specified position in the array.
  317.      * Shifts the element currently at that position (if any) and any subsequent
  318.      * elements to the right (adds one to their indices).
  319.      * <p>
  320.      * This method returns a new array with the same elements of the input
  321.      * array plus the given element on the specified position. The component
  322.      * type of the returned array is always the same as that of the input
  323.      * array.
  324.      * </p>
  325.      * <p>
  326.      * If the input array is {@code null}, a new one element array is returned
  327.      * whose component type is the same as the element.
  328.      * </p>
  329.      * <pre>
  330.      * ArrayUtils.add(null, 0, 'a')            = ['a']
  331.      * ArrayUtils.add(['a'], 0, 'b')           = ['b', 'a']
  332.      * ArrayUtils.add(['a', 'b'], 0, 'c')      = ['c', 'a', 'b']
  333.      * ArrayUtils.add(['a', 'b'], 1, 'k')      = ['a', 'k', 'b']
  334.      * ArrayUtils.add(['a', 'b', 'c'], 1, 't') = ['a', 't', 'b', 'c']
  335.      * </pre>
  336.      *
  337.      * @param array  the array to add the element to, may be {@code null}
  338.      * @param index  the position of the new object
  339.      * @param element  the object to add
  340.      * @return A new array containing the existing elements and the new element
  341.      * @throws IndexOutOfBoundsException if the index is out of range
  342.      * (index &lt; 0 || index &gt; array.length).
  343.      * @deprecated this method has been superseded by {@link #insert(int, char[], char...)} and
  344.      * may be removed in a future release. Please note the handling of {@code null} input arrays differs
  345.      * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
  346.      */
  347.     @Deprecated
  348.     public static char[] add(final char[] array, final int index, final char element) {
  349.         return (char[]) add(array, index, Character.valueOf(element), Character.TYPE);
  350.     }

  351.     /**
  352.      * Copies the given array and adds the given element at the end of the new array.
  353.      *
  354.      * <p>
  355.      * The new array contains the same elements of the input
  356.      * array plus the given element in the last position. The component type of
  357.      * the new array is the same as that of the input array.
  358.      * </p>
  359.      * <p>
  360.      * If the input array is {@code null}, a new one element array is returned
  361.      * whose component type is the same as the element.
  362.      * </p>
  363.      * <pre>
  364.      * ArrayUtils.add(null, 0)   = [0]
  365.      * ArrayUtils.add([1], 0)    = [1, 0]
  366.      * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
  367.      * </pre>
  368.      *
  369.      * @param array  the array to copy and add the element to, may be {@code null}
  370.      * @param element  the object to add at the last index of the new array
  371.      * @return A new array containing the existing elements plus the new element
  372.      * @since 2.1
  373.      */
  374.     public static double[] add(final double[] array, final double element) {
  375.         final double[] newArray = (double[]) copyArrayGrow1(array, Double.TYPE);
  376.         newArray[newArray.length - 1] = element;
  377.         return newArray;
  378.     }

  379.     /**
  380.      * Inserts the specified element at the specified position in the array.
  381.      * Shifts the element currently at that position (if any) and any subsequent
  382.      * elements to the right (adds one to their indices).
  383.      * <p>
  384.      * This method returns a new array with the same elements of the input
  385.      * array plus the given element on the specified position. The component
  386.      * type of the returned array is always the same as that of the input
  387.      * array.
  388.      * </p>
  389.      * <p>
  390.      * If the input array is {@code null}, a new one element array is returned
  391.      * whose component type is the same as the element.
  392.      * </p>
  393.      * <pre>
  394.      * ArrayUtils.add([1.1], 0, 2.2)              = [2.2, 1.1]
  395.      * ArrayUtils.add([2.3, 6.4], 2, 10.5)        = [2.3, 6.4, 10.5]
  396.      * ArrayUtils.add([2.6, 6.7], 0, -4.8)        = [-4.8, 2.6, 6.7]
  397.      * ArrayUtils.add([2.9, 6.0, 0.3], 2, 1.0)    = [2.9, 6.0, 1.0, 0.3]
  398.      * </pre>
  399.      *
  400.      * @param array  the array to add the element to, may be {@code null}
  401.      * @param index  the position of the new object
  402.      * @param element  the object to add
  403.      * @return A new array containing the existing elements and the new element
  404.      * @throws IndexOutOfBoundsException if the index is out of range
  405.      * (index &lt; 0 || index &gt; array.length).
  406.      * @deprecated this method has been superseded by {@link #insert(int, double[], double...)} and
  407.      * may be removed in a future release. Please note the handling of {@code null} input arrays differs
  408.      * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
  409.      */
  410.     @Deprecated
  411.     public static double[] add(final double[] array, final int index, final double element) {
  412.         return (double[]) add(array, index, Double.valueOf(element), Double.TYPE);
  413.     }

  414.     /**
  415.      * Copies the given array and adds the given element at the end of the new array.
  416.      * <p>
  417.      * The new array contains the same elements of the input
  418.      * array plus the given element in the last position. The component type of
  419.      * the new array is the same as that of the input array.
  420.      * </p>
  421.      * <p>
  422.      * If the input array is {@code null}, a new one element array is returned
  423.      * whose component type is the same as the element.
  424.      * </p>
  425.      * <pre>
  426.      * ArrayUtils.add(null, 0)   = [0]
  427.      * ArrayUtils.add([1], 0)    = [1, 0]
  428.      * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
  429.      * </pre>
  430.      *
  431.      * @param array  the array to copy and add the element to, may be {@code null}
  432.      * @param element  the object to add at the last index of the new array
  433.      * @return A new array containing the existing elements plus the new element
  434.      * @since 2.1
  435.      */
  436.     public static float[] add(final float[] array, final float element) {
  437.         final float[] newArray = (float[]) copyArrayGrow1(array, Float.TYPE);
  438.         newArray[newArray.length - 1] = element;
  439.         return newArray;
  440.     }

  441.     /**
  442.      * Inserts the specified element at the specified position in the array.
  443.      * Shifts the element currently at that position (if any) and any subsequent
  444.      * elements to the right (adds one to their indices).
  445.      * <p>
  446.      * This method returns a new array with the same elements of the input
  447.      * array plus the given element on the specified position. The component
  448.      * type of the returned array is always the same as that of the input
  449.      * array.
  450.      * </p>
  451.      * <p>
  452.      * If the input array is {@code null}, a new one element array is returned
  453.      * whose component type is the same as the element.
  454.      * </p>
  455.      * <pre>
  456.      * ArrayUtils.add([1.1f], 0, 2.2f)               = [2.2f, 1.1f]
  457.      * ArrayUtils.add([2.3f, 6.4f], 2, 10.5f)        = [2.3f, 6.4f, 10.5f]
  458.      * ArrayUtils.add([2.6f, 6.7f], 0, -4.8f)        = [-4.8f, 2.6f, 6.7f]
  459.      * ArrayUtils.add([2.9f, 6.0f, 0.3f], 2, 1.0f)   = [2.9f, 6.0f, 1.0f, 0.3f]
  460.      * </pre>
  461.      *
  462.      * @param array  the array to add the element to, may be {@code null}
  463.      * @param index  the position of the new object
  464.      * @param element  the object to add
  465.      * @return A new array containing the existing elements and the new element
  466.      * @throws IndexOutOfBoundsException if the index is out of range
  467.      * (index &lt; 0 || index &gt; array.length).
  468.      * @deprecated this method has been superseded by {@link #insert(int, float[], float...)} and
  469.      * may be removed in a future release. Please note the handling of {@code null} input arrays differs
  470.      * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
  471.      */
  472.     @Deprecated
  473.     public static float[] add(final float[] array, final int index, final float element) {
  474.         return (float[]) add(array, index, Float.valueOf(element), Float.TYPE);
  475.     }

  476.     /**
  477.      * Copies the given array and adds the given element at the end of the new array.
  478.      * <p>
  479.      * The new array contains the same elements of the input
  480.      * array plus the given element in the last position. The component type of
  481.      * the new array is the same as that of the input array.
  482.      * </p>
  483.      * <p>
  484.      * If the input array is {@code null}, a new one element array is returned
  485.      * whose component type is the same as the element.
  486.      * </p>
  487.      * <pre>
  488.      * ArrayUtils.add(null, 0)   = [0]
  489.      * ArrayUtils.add([1], 0)    = [1, 0]
  490.      * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
  491.      * </pre>
  492.      *
  493.      * @param array  the array to copy and add the element to, may be {@code null}
  494.      * @param element  the object to add at the last index of the new array
  495.      * @return A new array containing the existing elements plus the new element
  496.      * @since 2.1
  497.      */
  498.     public static int[] add(final int[] array, final int element) {
  499.         final int[] newArray = (int[]) copyArrayGrow1(array, Integer.TYPE);
  500.         newArray[newArray.length - 1] = element;
  501.         return newArray;
  502.     }

  503.     /**
  504.      * Inserts the specified element at the specified position in the array.
  505.      * Shifts the element currently at that position (if any) and any subsequent
  506.      * elements to the right (adds one to their indices).
  507.      * <p>
  508.      * This method returns a new array with the same elements of the input
  509.      * array plus the given element on the specified position. The component
  510.      * type of the returned array is always the same as that of the input
  511.      * array.
  512.      * </p>
  513.      * <p>
  514.      * If the input array is {@code null}, a new one element array is returned
  515.      * whose component type is the same as the element.
  516.      * </p>
  517.      * <pre>
  518.      * ArrayUtils.add([1], 0, 2)         = [2, 1]
  519.      * ArrayUtils.add([2, 6], 2, 10)     = [2, 6, 10]
  520.      * ArrayUtils.add([2, 6], 0, -4)     = [-4, 2, 6]
  521.      * ArrayUtils.add([2, 6, 3], 2, 1)   = [2, 6, 1, 3]
  522.      * </pre>
  523.      *
  524.      * @param array  the array to add the element to, may be {@code null}
  525.      * @param index  the position of the new object
  526.      * @param element  the object to add
  527.      * @return A new array containing the existing elements and the new element
  528.      * @throws IndexOutOfBoundsException if the index is out of range
  529.      * (index &lt; 0 || index &gt; array.length).
  530.      * @deprecated this method has been superseded by {@link #insert(int, int[], int...)} and
  531.      * may be removed in a future release. Please note the handling of {@code null} input arrays differs
  532.      * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
  533.      */
  534.     @Deprecated
  535.     public static int[] add(final int[] array, final int index, final int element) {
  536.         return (int[]) add(array, index, Integer.valueOf(element), Integer.TYPE);
  537.     }

  538.     /**
  539.      * Inserts the specified element at the specified position in the array.
  540.      * Shifts the element currently at that position (if any) and any subsequent
  541.      * elements to the right (adds one to their indices).
  542.      * <p>
  543.      * This method returns a new array with the same elements of the input
  544.      * array plus the given element on the specified position. The component
  545.      * type of the returned array is always the same as that of the input
  546.      * array.
  547.      * </p>
  548.      * <p>
  549.      * If the input array is {@code null}, a new one element array is returned
  550.      * whose component type is the same as the element.
  551.      * </p>
  552.      * <pre>
  553.      * ArrayUtils.add([1L], 0, 2L)           = [2L, 1L]
  554.      * ArrayUtils.add([2L, 6L], 2, 10L)      = [2L, 6L, 10L]
  555.      * ArrayUtils.add([2L, 6L], 0, -4L)      = [-4L, 2L, 6L]
  556.      * ArrayUtils.add([2L, 6L, 3L], 2, 1L)   = [2L, 6L, 1L, 3L]
  557.      * </pre>
  558.      *
  559.      * @param array  the array to add the element to, may be {@code null}
  560.      * @param index  the position of the new object
  561.      * @param element  the object to add
  562.      * @return A new array containing the existing elements and the new element
  563.      * @throws IndexOutOfBoundsException if the index is out of range
  564.      * (index &lt; 0 || index &gt; array.length).
  565.      * @deprecated this method has been superseded by {@link #insert(int, long[], long...)} and
  566.      * may be removed in a future release. Please note the handling of {@code null} input arrays differs
  567.      * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
  568.      */
  569.     @Deprecated
  570.     public static long[] add(final long[] array, final int index, final long element) {
  571.         return (long[]) add(array, index, Long.valueOf(element), Long.TYPE);
  572.     }

  573.     /**
  574.      * Copies the given array and adds the given element at the end of the new array.
  575.      * <p>
  576.      * The new array contains the same elements of the input
  577.      * array plus the given element in the last position. The component type of
  578.      * the new array is the same as that of the input array.
  579.      * </p>
  580.      * <p>
  581.      * If the input array is {@code null}, a new one element array is returned
  582.      * whose component type is the same as the element.
  583.      * </p>
  584.      * <pre>
  585.      * ArrayUtils.add(null, 0)   = [0]
  586.      * ArrayUtils.add([1], 0)    = [1, 0]
  587.      * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
  588.      * </pre>
  589.      *
  590.      * @param array  the array to copy and add the element to, may be {@code null}
  591.      * @param element  the object to add at the last index of the new array
  592.      * @return A new array containing the existing elements plus the new element
  593.      * @since 2.1
  594.      */
  595.     public static long[] add(final long[] array, final long element) {
  596.         final long[] newArray = (long[]) copyArrayGrow1(array, Long.TYPE);
  597.         newArray[newArray.length - 1] = element;
  598.         return newArray;
  599.     }

  600.     /**
  601.      * Underlying implementation of add(array, index, element) methods.
  602.      * The last parameter is the class, which may not equal element.getClass
  603.      * for primitives.
  604.      *
  605.      * @param array  the array to add the element to, may be {@code null}
  606.      * @param index  the position of the new object
  607.      * @param element  the object to add
  608.      * @param clazz the type of the element being added
  609.      * @return A new array containing the existing elements and the new element
  610.      */
  611.     private static Object add(final Object array, final int index, final Object element, final Class<?> clazz) {
  612.         if (array == null) {
  613.             if (index != 0) {
  614.                 throw new IndexOutOfBoundsException("Index: " + index + ", Length: 0");
  615.             }
  616.             final Object joinedArray = Array.newInstance(clazz, 1);
  617.             Array.set(joinedArray, 0, element);
  618.             return joinedArray;
  619.         }
  620.         final int length = Array.getLength(array);
  621.         if (index > length || index < 0) {
  622.             throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
  623.         }
  624.         final Object result = arraycopy(array, 0, 0, index, () -> Array.newInstance(clazz, length + 1));
  625.         Array.set(result, index, element);
  626.         if (index < length) {
  627.             System.arraycopy(array, index, result, index + 1, length - index);
  628.         }
  629.         return result;
  630.     }

  631.     /**
  632.      * Inserts the specified element at the specified position in the array.
  633.      * Shifts the element currently at that position (if any) and any subsequent
  634.      * elements to the right (adds one to their indices).
  635.      * <p>
  636.      * This method returns a new array with the same elements of the input
  637.      * array plus the given element on the specified position. The component
  638.      * type of the returned array is always the same as that of the input
  639.      * array.
  640.      * </p>
  641.      * <p>
  642.      * If the input array is {@code null}, a new one element array is returned
  643.      * whose component type is the same as the element.
  644.      * </p>
  645.      * <pre>
  646.      * ArrayUtils.add([1], 0, 2)         = [2, 1]
  647.      * ArrayUtils.add([2, 6], 2, 10)     = [2, 6, 10]
  648.      * ArrayUtils.add([2, 6], 0, -4)     = [-4, 2, 6]
  649.      * ArrayUtils.add([2, 6, 3], 2, 1)   = [2, 6, 1, 3]
  650.      * </pre>
  651.      *
  652.      * @param array  the array to add the element to, may be {@code null}
  653.      * @param index  the position of the new object
  654.      * @param element  the object to add
  655.      * @return A new array containing the existing elements and the new element
  656.      * @throws IndexOutOfBoundsException if the index is out of range
  657.      * (index &lt; 0 || index &gt; array.length).
  658.      * @deprecated this method has been superseded by {@link #insert(int, short[], short...)} and
  659.      * may be removed in a future release. Please note the handling of {@code null} input arrays differs
  660.      * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
  661.      */
  662.     @Deprecated
  663.     public static short[] add(final short[] array, final int index, final short element) {
  664.         return (short[]) add(array, index, Short.valueOf(element), Short.TYPE);
  665.     }

  666.     /**
  667.      * Copies the given array and adds the given element at the end of the new array.
  668.      * <p>
  669.      * The new array contains the same elements of the input
  670.      * array plus the given element in the last position. The component type of
  671.      * the new array is the same as that of the input array.
  672.      * </p>
  673.      * <p>
  674.      * If the input array is {@code null}, a new one element array is returned
  675.      * whose component type is the same as the element.
  676.      * </p>
  677.      * <pre>
  678.      * ArrayUtils.add(null, 0)   = [0]
  679.      * ArrayUtils.add([1], 0)    = [1, 0]
  680.      * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
  681.      * </pre>
  682.      *
  683.      * @param array  the array to copy and add the element to, may be {@code null}
  684.      * @param element  the object to add at the last index of the new array
  685.      * @return A new array containing the existing elements plus the new element
  686.      * @since 2.1
  687.      */
  688.     public static short[] add(final short[] array, final short element) {
  689.         final short[] newArray = (short[]) copyArrayGrow1(array, Short.TYPE);
  690.         newArray[newArray.length - 1] = element;
  691.         return newArray;
  692.     }

  693.     /**
  694.      * Inserts the specified element at the specified position in the array.
  695.      * Shifts the element currently at that position (if any) and any subsequent
  696.      * elements to the right (adds one to their indices).
  697.      * <p>
  698.      * This method returns a new array with the same elements of the input
  699.      * array plus the given element on the specified position. The component
  700.      * type of the returned array is always the same as that of the input
  701.      * array.
  702.      * </p>
  703.      * <p>
  704.      * If the input array is {@code null}, a new one element array is returned
  705.      * whose component type is the same as the element.
  706.      * </p>
  707.      * <pre>
  708.      * ArrayUtils.add(null, 0, null)      = IllegalArgumentException
  709.      * ArrayUtils.add(null, 0, "a")       = ["a"]
  710.      * ArrayUtils.add(["a"], 1, null)     = ["a", null]
  711.      * ArrayUtils.add(["a"], 1, "b")      = ["a", "b"]
  712.      * ArrayUtils.add(["a", "b"], 3, "c") = ["a", "b", "c"]
  713.      * </pre>
  714.      *
  715.      * @param <T> the component type of the array
  716.      * @param array  the array to add the element to, may be {@code null}
  717.      * @param index  the position of the new object
  718.      * @param element  the object to add
  719.      * @return A new array containing the existing elements and the new element
  720.      * @throws IndexOutOfBoundsException if the index is out of range (index &lt; 0 || index &gt; array.length).
  721.      * @throws IllegalArgumentException if both array and element are null
  722.      * @deprecated this method has been superseded by {@link #insert(int, Object[], Object...) insert(int, T[], T...)} and
  723.      * may be removed in a future release. Please note the handling of {@code null} input arrays differs
  724.      * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
  725.      */
  726.     @Deprecated
  727.     public static <T> T[] add(final T[] array, final int index, final T element) {
  728.         final Class<T> clazz;
  729.         if (array != null) {
  730.             clazz = getComponentType(array);
  731.         } else if (element != null) {
  732.             clazz = ObjectUtils.getClass(element);
  733.         } else {
  734.             throw new IllegalArgumentException("Array and element cannot both be null");
  735.         }
  736.         return (T[]) add(array, index, element, clazz);
  737.     }

  738.     /**
  739.      * Copies the given array and adds the given element at the end of the new array.
  740.      * <p>
  741.      * The new array contains the same elements of the input
  742.      * array plus the given element in the last position. The component type of
  743.      * the new array is the same as that of the input array.
  744.      * </p>
  745.      * <p>
  746.      * If the input array is {@code null}, a new one element array is returned
  747.      * whose component type is the same as the element, unless the element itself is null,
  748.      * in which case the return type is Object[]
  749.      * </p>
  750.      * <pre>
  751.      * ArrayUtils.add(null, null)      = IllegalArgumentException
  752.      * ArrayUtils.add(null, "a")       = ["a"]
  753.      * ArrayUtils.add(["a"], null)     = ["a", null]
  754.      * ArrayUtils.add(["a"], "b")      = ["a", "b"]
  755.      * ArrayUtils.add(["a", "b"], "c") = ["a", "b", "c"]
  756.      * </pre>
  757.      *
  758.      * @param <T> the component type of the array
  759.      * @param array  the array to "add" the element to, may be {@code null}
  760.      * @param element  the object to add, may be {@code null}
  761.      * @return A new array containing the existing elements plus the new element
  762.      * The returned array type will be that of the input array (unless null),
  763.      * in which case it will have the same type as the element.
  764.      * If both are null, an IllegalArgumentException is thrown
  765.      * @throws IllegalArgumentException if both arguments are null
  766.      * @since 2.1
  767.      */
  768.     public static <T> T[] add(final T[] array, final T element) {
  769.         final Class<?> type;
  770.         if (array != null) {
  771.             type = array.getClass().getComponentType();
  772.         } else if (element != null) {
  773.             type = element.getClass();
  774.         } else {
  775.             throw new IllegalArgumentException("Arguments cannot both be null");
  776.         }
  777.         @SuppressWarnings("unchecked") // type must be T
  778.         final
  779.         T[] newArray = (T[]) copyArrayGrow1(array, type);
  780.         newArray[newArray.length - 1] = element;
  781.         return newArray;
  782.     }

  783.     /**
  784.      * Adds all the elements of the given arrays into a new array.
  785.      * <p>
  786.      * The new array contains all of the element of {@code array1} followed
  787.      * by all of the elements {@code array2}. When an array is returned, it is always
  788.      * a new array.
  789.      * </p>
  790.      * <pre>
  791.      * ArrayUtils.addAll(array1, null)   = cloned copy of array1
  792.      * ArrayUtils.addAll(null, array2)   = cloned copy of array2
  793.      * ArrayUtils.addAll([], [])         = []
  794.      * ArrayUtils.addAll(null, null)     = null
  795.      * </pre>
  796.      *
  797.      * @param array1  the first array whose elements are added to the new array.
  798.      * @param array2  the second array whose elements are added to the new array.
  799.      * @return The new boolean[] array or {@code null}.
  800.      * @since 2.1
  801.      */
  802.     public static boolean[] addAll(final boolean[] array1, final boolean... array2) {
  803.         if (array1 == null) {
  804.             return clone(array2);
  805.         }
  806.         if (array2 == null) {
  807.             return clone(array1);
  808.         }
  809.         final boolean[] joinedArray = new boolean[array1.length + array2.length];
  810.         System.arraycopy(array1, 0, joinedArray, 0, array1.length);
  811.         System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
  812.         return joinedArray;
  813.     }

  814.     /**
  815.      * Adds all the elements of the given arrays into a new array.
  816.      * <p>
  817.      * The new array contains all of the element of {@code array1} followed
  818.      * by all of the elements {@code array2}. When an array is returned, it is always
  819.      * a new array.
  820.      * </p>
  821.      * <pre>
  822.      * ArrayUtils.addAll(array1, null)   = cloned copy of array1
  823.      * ArrayUtils.addAll(null, array2)   = cloned copy of array2
  824.      * ArrayUtils.addAll([], [])         = []
  825.      * ArrayUtils.addAll(null, null)     = null
  826.      * </pre>
  827.      *
  828.      * @param array1  the first array whose elements are added to the new array.
  829.      * @param array2  the second array whose elements are added to the new array.
  830.      * @return The new byte[] array or {@code null}.
  831.      * @since 2.1
  832.      */
  833.     public static byte[] addAll(final byte[] array1, final byte... array2) {
  834.         if (array1 == null) {
  835.             return clone(array2);
  836.         }
  837.         if (array2 == null) {
  838.             return clone(array1);
  839.         }
  840.         final byte[] joinedArray = new byte[array1.length + array2.length];
  841.         System.arraycopy(array1, 0, joinedArray, 0, array1.length);
  842.         System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
  843.         return joinedArray;
  844.     }

  845.     /**
  846.      * Adds all the elements of the given arrays into a new array.
  847.      * <p>
  848.      * The new array contains all of the element of {@code array1} followed
  849.      * by all of the elements {@code array2}. When an array is returned, it is always
  850.      * a new array.
  851.      * </p>
  852.      * <pre>
  853.      * ArrayUtils.addAll(array1, null)   = cloned copy of array1
  854.      * ArrayUtils.addAll(null, array2)   = cloned copy of array2
  855.      * ArrayUtils.addAll([], [])         = []
  856.      * ArrayUtils.addAll(null, null)     = null
  857.      * </pre>
  858.      *
  859.      * @param array1  the first array whose elements are added to the new array.
  860.      * @param array2  the second array whose elements are added to the new array.
  861.      * @return The new char[] array or {@code null}.
  862.      * @since 2.1
  863.      */
  864.     public static char[] addAll(final char[] array1, final char... array2) {
  865.         if (array1 == null) {
  866.             return clone(array2);
  867.         }
  868.         if (array2 == null) {
  869.             return clone(array1);
  870.         }
  871.         final char[] joinedArray = new char[array1.length + array2.length];
  872.         System.arraycopy(array1, 0, joinedArray, 0, array1.length);
  873.         System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
  874.         return joinedArray;
  875.     }

  876.     /**
  877.      * Adds all the elements of the given arrays into a new array.
  878.      * <p>
  879.      * The new array contains all of the element of {@code array1} followed
  880.      * by all of the elements {@code array2}. When an array is returned, it is always
  881.      * a new array.
  882.      * </p>
  883.      * <pre>
  884.      * ArrayUtils.addAll(array1, null)   = cloned copy of array1
  885.      * ArrayUtils.addAll(null, array2)   = cloned copy of array2
  886.      * ArrayUtils.addAll([], [])         = []
  887.      * ArrayUtils.addAll(null, null)     = null
  888.      * </pre>
  889.      *
  890.      * @param array1  the first array whose elements are added to the new array.
  891.      * @param array2  the second array whose elements are added to the new array.
  892.      * @return The new double[] array or {@code null}.
  893.      * @since 2.1
  894.      */
  895.     public static double[] addAll(final double[] array1, final double... array2) {
  896.         if (array1 == null) {
  897.             return clone(array2);
  898.         }
  899.         if (array2 == null) {
  900.             return clone(array1);
  901.         }
  902.         final double[] joinedArray = new double[array1.length + array2.length];
  903.         System.arraycopy(array1, 0, joinedArray, 0, array1.length);
  904.         System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
  905.         return joinedArray;
  906.     }

  907.     /**
  908.      * Adds all the elements of the given arrays into a new array.
  909.      * <p>
  910.      * The new array contains all of the element of {@code array1} followed
  911.      * by all of the elements {@code array2}. When an array is returned, it is always
  912.      * a new array.
  913.      * </p>
  914.      * <pre>
  915.      * ArrayUtils.addAll(array1, null)   = cloned copy of array1
  916.      * ArrayUtils.addAll(null, array2)   = cloned copy of array2
  917.      * ArrayUtils.addAll([], [])         = []
  918.      * ArrayUtils.addAll(null, null)     = null
  919.      * </pre>
  920.      *
  921.      * @param array1  the first array whose elements are added to the new array.
  922.      * @param array2  the second array whose elements are added to the new array.
  923.      * @return The new float[] array or {@code null}.
  924.      * @since 2.1
  925.      */
  926.     public static float[] addAll(final float[] array1, final float... array2) {
  927.         if (array1 == null) {
  928.             return clone(array2);
  929.         }
  930.         if (array2 == null) {
  931.             return clone(array1);
  932.         }
  933.         final float[] joinedArray = new float[array1.length + array2.length];
  934.         System.arraycopy(array1, 0, joinedArray, 0, array1.length);
  935.         System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
  936.         return joinedArray;
  937.     }

  938.     /**
  939.      * Adds all the elements of the given arrays into a new array.
  940.      * <p>
  941.      * The new array contains all of the element of {@code array1} followed
  942.      * by all of the elements {@code array2}. When an array is returned, it is always
  943.      * a new array.
  944.      * </p>
  945.      * <pre>
  946.      * ArrayUtils.addAll(array1, null)   = cloned copy of array1
  947.      * ArrayUtils.addAll(null, array2)   = cloned copy of array2
  948.      * ArrayUtils.addAll([], [])         = []
  949.      * ArrayUtils.addAll(null, null)     = null
  950.      * </pre>
  951.      *
  952.      * @param array1  the first array whose elements are added to the new array.
  953.      * @param array2  the second array whose elements are added to the new array.
  954.      * @return The new int[] array or {@code null}.
  955.      * @since 2.1
  956.      */
  957.     public static int[] addAll(final int[] array1, final int... array2) {
  958.         if (array1 == null) {
  959.             return clone(array2);
  960.         }
  961.         if (array2 == null) {
  962.             return clone(array1);
  963.         }
  964.         final int[] joinedArray = new int[array1.length + array2.length];
  965.         System.arraycopy(array1, 0, joinedArray, 0, array1.length);
  966.         System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
  967.         return joinedArray;
  968.     }

  969.     /**
  970.      * Adds all the elements of the given arrays into a new array.
  971.      * <p>
  972.      * The new array contains all of the element of {@code array1} followed
  973.      * by all of the elements {@code array2}. When an array is returned, it is always
  974.      * a new array.
  975.      * </p>
  976.      * <pre>
  977.      * ArrayUtils.addAll(array1, null)   = cloned copy of array1
  978.      * ArrayUtils.addAll(null, array2)   = cloned copy of array2
  979.      * ArrayUtils.addAll([], [])         = []
  980.      * ArrayUtils.addAll(null, null)     = null
  981.      * </pre>
  982.      *
  983.      * @param array1  the first array whose elements are added to the new array.
  984.      * @param array2  the second array whose elements are added to the new array.
  985.      * @return The new long[] array or {@code null}.
  986.      * @since 2.1
  987.      */
  988.     public static long[] addAll(final long[] array1, final long... array2) {
  989.         if (array1 == null) {
  990.             return clone(array2);
  991.         }
  992.         if (array2 == null) {
  993.             return clone(array1);
  994.         }
  995.         final long[] joinedArray = new long[array1.length + array2.length];
  996.         System.arraycopy(array1, 0, joinedArray, 0, array1.length);
  997.         System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
  998.         return joinedArray;
  999.     }

  1000.     /**
  1001.      * Adds all the elements of the given arrays into a new array.
  1002.      * <p>
  1003.      * The new array contains all of the element of {@code array1} followed
  1004.      * by all of the elements {@code array2}. When an array is returned, it is always
  1005.      * a new array.
  1006.      * </p>
  1007.      * <pre>
  1008.      * ArrayUtils.addAll(array1, null)   = cloned copy of array1
  1009.      * ArrayUtils.addAll(null, array2)   = cloned copy of array2
  1010.      * ArrayUtils.addAll([], [])         = []
  1011.      * ArrayUtils.addAll(null, null)     = null
  1012.      * </pre>
  1013.      *
  1014.      * @param array1  the first array whose elements are added to the new array.
  1015.      * @param array2  the second array whose elements are added to the new array.
  1016.      * @return The new short[] array or {@code null}.
  1017.      * @since 2.1
  1018.      */
  1019.     public static short[] addAll(final short[] array1, final short... array2) {
  1020.         if (array1 == null) {
  1021.             return clone(array2);
  1022.         }
  1023.         if (array2 == null) {
  1024.             return clone(array1);
  1025.         }
  1026.         final short[] joinedArray = new short[array1.length + array2.length];
  1027.         System.arraycopy(array1, 0, joinedArray, 0, array1.length);
  1028.         System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
  1029.         return joinedArray;
  1030.     }

  1031.     /**
  1032.      * Adds all the elements of the given arrays into a new array.
  1033.      * <p>
  1034.      * The new array contains all of the element of {@code array1} followed
  1035.      * by all of the elements {@code array2}. When an array is returned, it is always
  1036.      * a new array.
  1037.      * </p>
  1038.      * <pre>
  1039.      * ArrayUtils.addAll(null, null)     = null
  1040.      * ArrayUtils.addAll(array1, null)   = cloned copy of array1
  1041.      * ArrayUtils.addAll(null, array2)   = cloned copy of array2
  1042.      * ArrayUtils.addAll([], [])         = []
  1043.      * ArrayUtils.addAll(null, null)     = null
  1044.      * ArrayUtils.addAll([null], [null]) = [null, null]
  1045.      * ArrayUtils.addAll(["a", "b", "c"], ["1", "2", "3"]) = ["a", "b", "c", "1", "2", "3"]
  1046.      * </pre>
  1047.      *
  1048.      * @param <T> the component type of the array
  1049.      * @param array1  the first array whose elements are added to the new array, may be {@code null}
  1050.      * @param array2  the second array whose elements are added to the new array, may be {@code null}
  1051.      * @return The new array, {@code null} if both arrays are {@code null}.
  1052.      *      The type of the new array is the type of the first array,
  1053.      *      unless the first array is null, in which case the type is the same as the second array.
  1054.      * @throws IllegalArgumentException if the array types are incompatible
  1055.      * @since 2.1
  1056.      */
  1057.     public static <T> T[] addAll(final T[] array1, @SuppressWarnings("unchecked") final T... array2) {
  1058.         if (array1 == null) {
  1059.             return clone(array2);
  1060.         }
  1061.         if (array2 == null) {
  1062.             return clone(array1);
  1063.         }
  1064.         final Class<T> type1 = getComponentType(array1);
  1065.         final T[] joinedArray = arraycopy(array1, 0, 0, array1.length, () -> newInstance(type1, array1.length + array2.length));
  1066.         try {
  1067.             System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
  1068.         } catch (final ArrayStoreException ase) {
  1069.             // Check if problem was due to incompatible types
  1070.             /*
  1071.              * We do this here, rather than before the copy because: - it would be a wasted check most of the time - safer, in case check turns out to be too
  1072.              * strict
  1073.              */
  1074.             final Class<?> type2 = array2.getClass().getComponentType();
  1075.             if (!type1.isAssignableFrom(type2)) {
  1076.                 throw new IllegalArgumentException("Cannot store " + type2.getName() + " in an array of " + type1.getName(), ase);
  1077.             }
  1078.             throw ase; // No, so rethrow original
  1079.         }
  1080.         return joinedArray;
  1081.     }

  1082.     /**
  1083.      * Copies the given array and adds the given element at the beginning of the new array.
  1084.      * <p>
  1085.      * The new array contains the same elements of the input array plus the given element in the first position. The
  1086.      * component type of the new array is the same as that of the input array.
  1087.      * </p>
  1088.      * <p>
  1089.      * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
  1090.      * element.
  1091.      * </p>
  1092.      * <pre>
  1093.      * ArrayUtils.addFirst(null, true)          = [true]
  1094.      * ArrayUtils.addFirst([true], false)       = [false, true]
  1095.      * ArrayUtils.addFirst([true, false], true) = [true, true, false]
  1096.      * </pre>
  1097.      *
  1098.      * @param array the array to "add" the element to, may be {@code null}.
  1099.      * @param element the object to add.
  1100.      * @return A new array containing the existing elements plus the new element The returned array type will be that of
  1101.      *         the input array (unless null), in which case it will have the same type as the element.
  1102.      * @since 3.10
  1103.      */
  1104.     public static boolean[] addFirst(final boolean[] array, final boolean element) {
  1105.         return array == null ? add(array, element) : insert(0, array, element);
  1106.     }

  1107.     /**
  1108.      * Copies the given array and adds the given element at the beginning of the new array.
  1109.      * <p>
  1110.      * The new array contains the same elements of the input array plus the given element in the first position. The
  1111.      * component type of the new array is the same as that of the input array.
  1112.      * </p>
  1113.      * <p>
  1114.      * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
  1115.      * element.
  1116.      * </p>
  1117.      * <pre>
  1118.      * ArrayUtils.addFirst(null, 1)   = [1]
  1119.      * ArrayUtils.addFirst([1], 0)    = [0, 1]
  1120.      * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
  1121.      * </pre>
  1122.      *
  1123.      * @param array the array to "add" the element to, may be {@code null}.
  1124.      * @param element the object to add.
  1125.      * @return A new array containing the existing elements plus the new element The returned array type will be that of
  1126.      *         the input array (unless null), in which case it will have the same type as the element.
  1127.      * @since 3.10
  1128.      */
  1129.     public static byte[] addFirst(final byte[] array, final byte element) {
  1130.         return array == null ? add(array, element) : insert(0, array, element);
  1131.     }

  1132.     /**
  1133.      * Copies the given array and adds the given element at the beginning of the new array.
  1134.      * <p>
  1135.      * The new array contains the same elements of the input array plus the given element in the first position. The
  1136.      * component type of the new array is the same as that of the input array.
  1137.      * </p>
  1138.      * <p>
  1139.      * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
  1140.      * element.
  1141.      * </p>
  1142.      * <pre>
  1143.      * ArrayUtils.addFirst(null, '1')       = ['1']
  1144.      * ArrayUtils.addFirst(['1'], '0')      = ['0', '1']
  1145.      * ArrayUtils.addFirst(['1', '0'], '1') = ['1', '1', '0']
  1146.      * </pre>
  1147.      *
  1148.      * @param array the array to "add" the element to, may be {@code null}.
  1149.      * @param element the object to add.
  1150.      * @return A new array containing the existing elements plus the new element The returned array type will be that of
  1151.      *         the input array (unless null), in which case it will have the same type as the element.
  1152.      * @since 3.10
  1153.      */
  1154.     public static char[] addFirst(final char[] array, final char element) {
  1155.         return array == null ? add(array, element) : insert(0, array, element);
  1156.     }

  1157.     /**
  1158.      * Copies the given array and adds the given element at the beginning of the new array.
  1159.      * <p>
  1160.      * The new array contains the same elements of the input array plus the given element in the first position. The
  1161.      * component type of the new array is the same as that of the input array.
  1162.      * </p>
  1163.      * <p>
  1164.      * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
  1165.      * element.
  1166.      * </p>
  1167.      * <pre>
  1168.      * ArrayUtils.addFirst(null, 1)   = [1]
  1169.      * ArrayUtils.addFirst([1], 0)    = [0, 1]
  1170.      * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
  1171.      * </pre>
  1172.      *
  1173.      * @param array the array to "add" the element to, may be {@code null}.
  1174.      * @param element the object to add.
  1175.      * @return A new array containing the existing elements plus the new element The returned array type will be that of
  1176.      *         the input array (unless null), in which case it will have the same type as the element.
  1177.      * @since 3.10
  1178.      */
  1179.     public static double[] addFirst(final double[] array, final double element) {
  1180.         return array == null ? add(array, element) : insert(0, array, element);
  1181.     }

  1182.     /**
  1183.      * Copies the given array and adds the given element at the beginning of the new array.
  1184.      * <p>
  1185.      * The new array contains the same elements of the input array plus the given element in the first position. The
  1186.      * component type of the new array is the same as that of the input array.
  1187.      * </p>
  1188.      * <p>
  1189.      * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
  1190.      * element.
  1191.      * </p>
  1192.      * <pre>
  1193.      * ArrayUtils.addFirst(null, 1)   = [1]
  1194.      * ArrayUtils.addFirst([1], 0)    = [0, 1]
  1195.      * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
  1196.      * </pre>
  1197.      *
  1198.      * @param array the array to "add" the element to, may be {@code null}.
  1199.      * @param element the object to add.
  1200.      * @return A new array containing the existing elements plus the new element The returned array type will be that of
  1201.      *         the input array (unless null), in which case it will have the same type as the element.
  1202.      * @since 3.10
  1203.      */
  1204.     public static float[] addFirst(final float[] array, final float element) {
  1205.         return array == null ? add(array, element) : insert(0, array, element);
  1206.     }

  1207.     /**
  1208.      * Copies the given array and adds the given element at the beginning of the new array.
  1209.      * <p>
  1210.      * The new array contains the same elements of the input array plus the given element in the first position. The
  1211.      * component type of the new array is the same as that of the input array.
  1212.      * </p>
  1213.      * <p>
  1214.      * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
  1215.      * element.
  1216.      * </p>
  1217.      * <pre>
  1218.      * ArrayUtils.addFirst(null, 1)   = [1]
  1219.      * ArrayUtils.addFirst([1], 0)    = [0, 1]
  1220.      * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
  1221.      * </pre>
  1222.      *
  1223.      * @param array the array to "add" the element to, may be {@code null}.
  1224.      * @param element the object to add.
  1225.      * @return A new array containing the existing elements plus the new element The returned array type will be that of
  1226.      *         the input array (unless null), in which case it will have the same type as the element.
  1227.      * @since 3.10
  1228.      */
  1229.     public static int[] addFirst(final int[] array, final int element) {
  1230.         return array == null ? add(array, element) : insert(0, array, element);
  1231.     }

  1232.     /**
  1233.      * Copies the given array and adds the given element at the beginning of the new array.
  1234.      * <p>
  1235.      * The new array contains the same elements of the input array plus the given element in the first position. The
  1236.      * component type of the new array is the same as that of the input array.
  1237.      * </p>
  1238.      * <p>
  1239.      * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
  1240.      * element.
  1241.      * </p>
  1242.      * <pre>
  1243.      * ArrayUtils.addFirst(null, 1)   = [1]
  1244.      * ArrayUtils.addFirst([1], 0)    = [0, 1]
  1245.      * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
  1246.      * </pre>
  1247.      *
  1248.      * @param array the array to "add" the element to, may be {@code null}.
  1249.      * @param element the object to add.
  1250.      * @return A new array containing the existing elements plus the new element The returned array type will be that of
  1251.      *         the input array (unless null), in which case it will have the same type as the element.
  1252.      * @since 3.10
  1253.      */
  1254.     public static long[] addFirst(final long[] array, final long element) {
  1255.         return array == null ? add(array, element) : insert(0, array, element);
  1256.     }

  1257.     /**
  1258.      * Copies the given array and adds the given element at the beginning of the new array.
  1259.      * <p>
  1260.      * The new array contains the same elements of the input array plus the given element in the first position. The
  1261.      * component type of the new array is the same as that of the input array.
  1262.      * </p>
  1263.      * <p>
  1264.      * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
  1265.      * element.
  1266.      * </p>
  1267.      * <pre>
  1268.      * ArrayUtils.addFirst(null, 1)   = [1]
  1269.      * ArrayUtils.addFirst([1], 0)    = [0, 1]
  1270.      * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
  1271.      * </pre>
  1272.      *
  1273.      * @param array the array to "add" the element to, may be {@code null}.
  1274.      * @param element the object to add.
  1275.      * @return A new array containing the existing elements plus the new element The returned array type will be that of
  1276.      *         the input array (unless null), in which case it will have the same type as the element.
  1277.      * @since 3.10
  1278.      */
  1279.     public static short[] addFirst(final short[] array, final short element) {
  1280.         return array == null ? add(array, element) : insert(0, array, element);
  1281.     }

  1282.     /**
  1283.      * Copies the given array and adds the given element at the beginning of the new array.
  1284.      * <p>
  1285.      * The new array contains the same elements of the input array plus the given element in the first position. The
  1286.      * component type of the new array is the same as that of the input array.
  1287.      * </p>
  1288.      * <p>
  1289.      * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
  1290.      * element, unless the element itself is null, in which case the return type is Object[]
  1291.      * </p>
  1292.      * <pre>
  1293.      * ArrayUtils.addFirst(null, null)      = IllegalArgumentException
  1294.      * ArrayUtils.addFirst(null, "a")       = ["a"]
  1295.      * ArrayUtils.addFirst(["a"], null)     = [null, "a"]
  1296.      * ArrayUtils.addFirst(["a"], "b")      = ["b", "a"]
  1297.      * ArrayUtils.addFirst(["a", "b"], "c") = ["c", "a", "b"]
  1298.      * </pre>
  1299.      *
  1300.      * @param <T> the component type of the array
  1301.      * @param array the array to "add" the element to, may be {@code null}
  1302.      * @param element the object to add, may be {@code null}
  1303.      * @return A new array containing the existing elements plus the new element The returned array type will be that of
  1304.      *         the input array (unless null), in which case it will have the same type as the element. If both are null,
  1305.      *         an IllegalArgumentException is thrown
  1306.      * @throws IllegalArgumentException if both arguments are null
  1307.      * @since 3.10
  1308.      */
  1309.     public static <T> T[] addFirst(final T[] array, final T element) {
  1310.         return array == null ? add(array, element) : insert(0, array, element);
  1311.     }

  1312.     /**
  1313.      * A fluent version of {@link System#arraycopy(Object, int, Object, int, int)} that returns the destination array.
  1314.      *
  1315.      * @param <T>       the type.
  1316.      * @param source    the source array.
  1317.      * @param sourcePos starting position in the source array.
  1318.      * @param destPos   starting position in the destination data.
  1319.      * @param length    the number of array elements to be copied.
  1320.      * @param allocator allocates the array to populate and return.
  1321.      * @return dest
  1322.      * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds.
  1323.      * @throws ArrayStoreException       if an element in the {@code src} array could not be stored into the {@code dest} array because of a type
  1324.      *                                   mismatch.
  1325.      * @throws NullPointerException      if either {@code src} or {@code dest} is {@code null}.
  1326.      * @since 3.15.0
  1327.      */
  1328.     public static <T> T arraycopy(final T source, final int sourcePos, final int destPos, final int length, final Function<Integer, T> allocator) {
  1329.         return arraycopy(source, sourcePos, allocator.apply(length), destPos, length);
  1330.     }

  1331.     /**
  1332.      * A fluent version of {@link System#arraycopy(Object, int, Object, int, int)} that returns the destination array.
  1333.      *
  1334.      * @param <T>       the type.
  1335.      * @param source    the source array.
  1336.      * @param sourcePos starting position in the source array.
  1337.      * @param destPos   starting position in the destination data.
  1338.      * @param length    the number of array elements to be copied.
  1339.      * @param allocator allocates the array to populate and return.
  1340.      * @return dest
  1341.      * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds.
  1342.      * @throws ArrayStoreException       if an element in the {@code src} array could not be stored into the {@code dest} array because of a type
  1343.      *                                   mismatch.
  1344.      * @throws NullPointerException      if either {@code src} or {@code dest} is {@code null}.
  1345.      * @since 3.15.0
  1346.      */
  1347.     public static <T> T arraycopy(final T source, final int sourcePos, final int destPos, final int length, final Supplier<T> allocator) {
  1348.         return arraycopy(source, sourcePos, allocator.get(), destPos, length);
  1349.     }

  1350.     /**
  1351.      * A fluent version of {@link System#arraycopy(Object, int, Object, int, int)} that returns the destination array.
  1352.      *
  1353.      * @param <T>       the type
  1354.      * @param source    the source array.
  1355.      * @param sourcePos starting position in the source array.
  1356.      * @param dest      the destination array.
  1357.      * @param destPos   starting position in the destination data.
  1358.      * @param length    the number of array elements to be copied.
  1359.      * @return dest
  1360.      * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds.
  1361.      * @throws ArrayStoreException       if an element in the {@code src} array could not be stored into the {@code dest} array because of a type
  1362.      *                                   mismatch.
  1363.      * @throws NullPointerException      if either {@code src} or {@code dest} is {@code null}.
  1364.      * @since 3.15.0
  1365.      */
  1366.     public static <T> T arraycopy(final T source, final int sourcePos, final T dest, final int destPos, final int length) {
  1367.         System.arraycopy(source, sourcePos, dest, destPos, length);
  1368.         return dest;
  1369.     }

  1370.     /**
  1371.      * Clones an array or returns {@code null}.
  1372.      * <p>
  1373.      * This method returns {@code null} for a {@code null} input array.
  1374.      * </p>
  1375.      *
  1376.      * @param array the array to clone, may be {@code null}
  1377.      * @return the cloned array, {@code null} if {@code null} input
  1378.      */
  1379.     public static boolean[] clone(final boolean[] array) {
  1380.         return array != null ? array.clone() : null;
  1381.     }

  1382.     /**
  1383.      * Clones an array or returns {@code null}.
  1384.      * <p>
  1385.      * This method returns {@code null} for a {@code null} input array.
  1386.      * </p>
  1387.      *
  1388.      * @param array the array to clone, may be {@code null}
  1389.      * @return the cloned array, {@code null} if {@code null} input
  1390.      */
  1391.     public static byte[] clone(final byte[] array) {
  1392.         return array != null ? array.clone() : null;
  1393.     }

  1394.     /**
  1395.      * Clones an array or returns {@code null}.
  1396.      * <p>
  1397.      * This method returns {@code null} for a {@code null} input array.
  1398.      * </p>
  1399.      *
  1400.      * @param array the array to clone, may be {@code null}
  1401.      * @return the cloned array, {@code null} if {@code null} input
  1402.      */
  1403.     public static char[] clone(final char[] array) {
  1404.         return array != null ? array.clone() : null;
  1405.     }

  1406.     /**
  1407.      * Clones an array or returns {@code null}.
  1408.      * <p>
  1409.      * This method returns {@code null} for a {@code null} input array.
  1410.      * </p>
  1411.      *
  1412.      * @param array the array to clone, may be {@code null}
  1413.      * @return the cloned array, {@code null} if {@code null} input
  1414.      */
  1415.     public static double[] clone(final double[] array) {
  1416.         return array != null ? array.clone() : null;
  1417.     }

  1418.     /**
  1419.      * Clones an array or returns {@code null}.
  1420.      * <p>
  1421.      * This method returns {@code null} for a {@code null} input array.
  1422.      * </p>
  1423.      *
  1424.      * @param array the array to clone, may be {@code null}
  1425.      * @return the cloned array, {@code null} if {@code null} input
  1426.      */
  1427.     public static float[] clone(final float[] array) {
  1428.         return array != null ? array.clone() : null;
  1429.     }

  1430.     /**
  1431.      * Clones an array or returns {@code null}.
  1432.      * <p>
  1433.      * This method returns {@code null} for a {@code null} input array.
  1434.      * </p>
  1435.      *
  1436.      * @param array the array to clone, may be {@code null}
  1437.      * @return the cloned array, {@code null} if {@code null} input
  1438.      */
  1439.     public static int[] clone(final int[] array) {
  1440.         return array != null ? array.clone() : null;
  1441.     }

  1442.     /**
  1443.      * Clones an array or returns {@code null}.
  1444.      * <p>
  1445.      * This method returns {@code null} for a {@code null} input array.
  1446.      * </p>
  1447.      *
  1448.      * @param array the array to clone, may be {@code null}
  1449.      * @return the cloned array, {@code null} if {@code null} input
  1450.      */
  1451.     public static long[] clone(final long[] array) {
  1452.         return array != null ? array.clone() : null;
  1453.     }

  1454.     /**
  1455.      * Clones an array or returns {@code null}.
  1456.      * <p>
  1457.      * This method returns {@code null} for a {@code null} input array.
  1458.      * </p>
  1459.      *
  1460.      * @param array the array to clone, may be {@code null}
  1461.      * @return the cloned array, {@code null} if {@code null} input
  1462.      */
  1463.     public static short[] clone(final short[] array) {
  1464.         return array != null ? array.clone() : null;
  1465.     }

  1466.     /**
  1467.      * Shallow clones an array or returns {@code null}.
  1468.      * <p>
  1469.      * The objects in the array are not cloned, thus there is no special handling for multi-dimensional arrays.
  1470.      * </p>
  1471.      * <p>
  1472.      * This method returns {@code null} for a {@code null} input array.
  1473.      * </p>
  1474.      *
  1475.      * @param <T>   the component type of the array
  1476.      * @param array the array to shallow clone, may be {@code null}
  1477.      * @return the cloned array, {@code null} if {@code null} input
  1478.      */
  1479.     public static <T> T[] clone(final T[] array) {
  1480.         return array != null ? array.clone() : null;
  1481.     }

  1482.     /**
  1483.      * Checks if the value is in the given array.
  1484.      * <p>
  1485.      * The method returns {@code false} if a {@code null} array is passed in.
  1486.      * </p>
  1487.      *
  1488.      * @param array  the array to search
  1489.      * @param valueToFind  the value to find
  1490.      * @return {@code true} if the array contains the object
  1491.      */
  1492.     public static boolean contains(final boolean[] array, final boolean valueToFind) {
  1493.         return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
  1494.     }

  1495.     /**
  1496.      * Checks if the value is in the given array.
  1497.      * <p>
  1498.      * The method returns {@code false} if a {@code null} array is passed in.
  1499.      * </p>
  1500.      * <p>
  1501.      * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
  1502.      * {@link Arrays#sort(byte[])} and {@link Arrays#binarySearch(byte[], byte)}.
  1503.      * </p>
  1504.      *
  1505.      * @param array  the array to search
  1506.      * @param valueToFind  the value to find
  1507.      * @return {@code true} if the array contains the object
  1508.      */
  1509.     public static boolean contains(final byte[] array, final byte valueToFind) {
  1510.         return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
  1511.     }

  1512.     /**
  1513.      * Checks if the value is in the given array.
  1514.      * <p>
  1515.      * The method returns {@code false} if a {@code null} array is passed in.
  1516.      * </p>
  1517.      * <p>
  1518.      * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
  1519.      * {@link Arrays#sort(char[])} and {@link Arrays#binarySearch(char[], char)}.
  1520.      * </p>
  1521.      *
  1522.      * @param array  the array to search
  1523.      * @param valueToFind  the value to find
  1524.      * @return {@code true} if the array contains the object
  1525.      * @since 2.1
  1526.      */
  1527.     public static boolean contains(final char[] array, final char valueToFind) {
  1528.         return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
  1529.     }

  1530.     /**
  1531.      * Checks if the value is in the given array.
  1532.      * <p>
  1533.      * The method returns {@code false} if a {@code null} array is passed in.
  1534.      * </p>
  1535.      * <p>
  1536.      * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
  1537.      * {@link Arrays#sort(double[])} and {@link Arrays#binarySearch(double[], double)}.
  1538.      * </p>
  1539.      *
  1540.      * @param array  the array to search
  1541.      * @param valueToFind  the value to find
  1542.      * @return {@code true} if the array contains the object
  1543.      */
  1544.     public static boolean contains(final double[] array, final double valueToFind) {
  1545.         return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
  1546.     }

  1547.     /**
  1548.      * Checks if a value falling within the given tolerance is in the
  1549.      * given array.  If the array contains a value within the inclusive range
  1550.      * defined by (value - tolerance) to (value + tolerance).
  1551.      * <p>
  1552.      * The method returns {@code false} if a {@code null} array
  1553.      * is passed in.
  1554.      * </p>
  1555.      * <p>
  1556.      * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
  1557.      * {@link Arrays#sort(double[])} and {@link Arrays#binarySearch(double[], double)}.
  1558.      * </p>
  1559.      *
  1560.      * @param array  the array to search
  1561.      * @param valueToFind  the value to find
  1562.      * @param tolerance  the array contains the tolerance of the search
  1563.      * @return true if value falling within tolerance is in array
  1564.      */
  1565.     public static boolean contains(final double[] array, final double valueToFind, final double tolerance) {
  1566.         return indexOf(array, valueToFind, 0, tolerance) != INDEX_NOT_FOUND;
  1567.     }

  1568.     /**
  1569.      * Checks if the value is in the given array.
  1570.      * <p>
  1571.      * The method returns {@code false} if a {@code null} array is passed in.
  1572.      * </p>
  1573.      * <p>
  1574.      * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
  1575.      * {@link Arrays#sort(float[])} and {@link Arrays#binarySearch(float[], float)}.
  1576.      * </p>
  1577.      *
  1578.      * @param array  the array to search
  1579.      * @param valueToFind  the value to find
  1580.      * @return {@code true} if the array contains the object
  1581.      */
  1582.     public static boolean contains(final float[] array, final float valueToFind) {
  1583.         return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
  1584.     }

  1585.     /**
  1586.      * Checks if the value is in the given array.
  1587.      * <p>
  1588.      * The method returns {@code false} if a {@code null} array is passed in.
  1589.      * </p>
  1590.      * <p>
  1591.      * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
  1592.      * {@link Arrays#sort(int[])} and {@link Arrays#binarySearch(int[], int)}.
  1593.      * </p>
  1594.      *
  1595.      * @param array  the array to search
  1596.      * @param valueToFind  the value to find
  1597.      * @return {@code true} if the array contains the object
  1598.      */
  1599.     public static boolean contains(final int[] array, final int valueToFind) {
  1600.         return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
  1601.     }

  1602.     /**
  1603.      * Checks if the value is in the given array.
  1604.      * <p>
  1605.      * The method returns {@code false} if a {@code null} array is passed in.
  1606.      * </p>
  1607.      * <p>
  1608.      * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
  1609.      * {@link Arrays#sort(long[])} and {@link Arrays#binarySearch(long[], long)}.
  1610.      * </p>
  1611.      *
  1612.      * @param array  the array to search
  1613.      * @param valueToFind  the value to find
  1614.      * @return {@code true} if the array contains the object
  1615.      */
  1616.     public static boolean contains(final long[] array, final long valueToFind) {
  1617.         return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
  1618.     }

  1619.     /**
  1620.      * Checks if the object is in the given array.
  1621.      * <p>
  1622.      * The method returns {@code false} if a {@code null} array is passed in.
  1623.      * </p>
  1624.      * <p>
  1625.      * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
  1626.      * {@link Arrays#sort(Object[], Comparator)} and {@link Arrays#binarySearch(Object[], Object)}.
  1627.      * </p>
  1628.      *
  1629.      * @param array  the array to search, may be {@code null}.
  1630.      * @param objectToFind  the object to find, may be {@code null}.
  1631.      * @return {@code true} if the array contains the object
  1632.      */
  1633.     public static boolean contains(final Object[] array, final Object objectToFind) {
  1634.         return indexOf(array, objectToFind) != INDEX_NOT_FOUND;
  1635.     }

  1636.     /**
  1637.      * Checks if the value is in the given array.
  1638.      * <p>
  1639.      * The method returns {@code false} if a {@code null} array is passed in.
  1640.      * </p>
  1641.      * <p>
  1642.      * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
  1643.      * {@link Arrays#sort(short[])} and {@link Arrays#binarySearch(short[], short)}.
  1644.      * </p>
  1645.      *
  1646.      * @param array  the array to search
  1647.      * @param valueToFind  the value to find
  1648.      * @return {@code true} if the array contains the object
  1649.      */
  1650.     public static boolean contains(final short[] array, final short valueToFind) {
  1651.         return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
  1652.     }

  1653.     /**
  1654.      * Checks if any of the ints are in the given array.
  1655.      * <p>
  1656.      * The method returns {@code false} if a {@code null} array is passed in.
  1657.      * </p>
  1658.      * <p>
  1659.      * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
  1660.      * {@link Arrays#sort(int[])} and {@link Arrays#binarySearch(int[], int)}.
  1661.      * </p>
  1662.      *
  1663.      * @param array         the array to search
  1664.      * @param objectsToFind any of the ints to find
  1665.      * @return {@code true} if the array contains any of the ints
  1666.      * @since 3.18.0
  1667.      */
  1668.     public static boolean containsAny(final int[] array, final int... objectsToFind) {
  1669.         return IntStreams.of(objectsToFind).anyMatch(e -> contains(array, e));
  1670.     }

  1671.     /**
  1672.      * Checks if any of the objects are in the given array.
  1673.      * <p>
  1674.      * The method returns {@code false} if a {@code null} array is passed in.
  1675.      * </p>
  1676.      * <p>
  1677.      * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
  1678.      * {@link Arrays#sort(Object[], Comparator)} and {@link Arrays#binarySearch(Object[], Object)}.
  1679.      * </p>
  1680.      *
  1681.      * @param array         the array to search, may be {@code null}.
  1682.      * @param objectsToFind any of the objects to find, may be {@code null}.
  1683.      * @return {@code true} if the array contains any of the objects
  1684.      * @since 3.13.0
  1685.      */
  1686.     public static boolean containsAny(final Object[] array, final Object... objectsToFind) {
  1687.         return Streams.of(objectsToFind).anyMatch(e -> contains(array, e));
  1688.     }

  1689.     /**
  1690.      * Returns a copy of the given array of size 1 greater than the argument.
  1691.      * The last value of the array is left to the default value.
  1692.      *
  1693.      * @param array The array to copy, must not be {@code null}.
  1694.      * @param newArrayComponentType If {@code array} is {@code null}, create a
  1695.      * size 1 array of this type.
  1696.      * @return A new copy of the array of size 1 greater than the input.
  1697.      */
  1698.     private static Object copyArrayGrow1(final Object array, final Class<?> newArrayComponentType) {
  1699.         if (array != null) {
  1700.             final int arrayLength = Array.getLength(array);
  1701.             final Object newArray = Array.newInstance(array.getClass().getComponentType(), arrayLength + 1);
  1702.             System.arraycopy(array, 0, newArray, 0, arrayLength);
  1703.             return newArray;
  1704.         }
  1705.         return Array.newInstance(newArrayComponentType, 1);
  1706.     }

  1707.     /**
  1708.      * Gets the nTh element of an array or null if the index is out of bounds or the array is null.
  1709.      *
  1710.      * @param <T> The type of array elements.
  1711.      * @param array The array to index.
  1712.      * @param index The index
  1713.      * @return the nTh element of an array or null if the index is out of bounds or the array is null.
  1714.      * @since 3.11
  1715.      */
  1716.     public static <T> T get(final T[] array, final int index) {
  1717.         return get(array, index, null);
  1718.     }

  1719.     /**
  1720.      * Gets the nTh element of an array or a default value if the index is out of bounds.
  1721.      *
  1722.      * @param <T> The type of array elements.
  1723.      * @param array The array to index.
  1724.      * @param index The index
  1725.      * @param defaultValue The return value of the given index is out of bounds.
  1726.      * @return the nTh element of an array or a default value if the index is out of bounds.
  1727.      * @since 3.11
  1728.      */
  1729.     public static <T> T get(final T[] array, final int index, final T defaultValue) {
  1730.         return isArrayIndexValid(array, index) ? array[index] : defaultValue;
  1731.     }

  1732.     /**
  1733.      * Gets an array's component type.
  1734.      *
  1735.      * @param <T> The array type.
  1736.      * @param array The array.
  1737.      * @return The component type.
  1738.      * @since 3.13.0
  1739.      */
  1740.     public static <T> Class<T> getComponentType(final T[] array) {
  1741.         return ClassUtils.getComponentType(ObjectUtils.getClass(array));
  1742.     }

  1743.     /**
  1744.      * Gets the length of the specified array.
  1745.      * This method can deal with {@link Object} arrays and with primitive arrays.
  1746.      * <p>
  1747.      * If the input array is {@code null}, {@code 0} is returned.
  1748.      * </p>
  1749.      * <pre>
  1750.      * ArrayUtils.getLength(null)            = 0
  1751.      * ArrayUtils.getLength([])              = 0
  1752.      * ArrayUtils.getLength([null])          = 1
  1753.      * ArrayUtils.getLength([true, false])   = 2
  1754.      * ArrayUtils.getLength([1, 2, 3])       = 3
  1755.      * ArrayUtils.getLength(["a", "b", "c"]) = 3
  1756.      * </pre>
  1757.      *
  1758.      * @param array  the array to retrieve the length from, may be {@code null}.
  1759.      * @return The length of the array, or {@code 0} if the array is {@code null}
  1760.      * @throws IllegalArgumentException if the object argument is not an array.
  1761.      * @since 2.1
  1762.      */
  1763.     public static int getLength(final Object array) {
  1764.         return array != null ? Array.getLength(array) : 0;
  1765.     }

  1766.     /**
  1767.      * Gets a hash code for an array handling multidimensional arrays correctly.
  1768.      * <p>
  1769.      * Multi-dimensional primitive arrays are also handled correctly by this method.
  1770.      * </p>
  1771.      *
  1772.      * @param array  the array to get a hash code for, {@code null} returns zero
  1773.      * @return a hash code for the array
  1774.      */
  1775.     public static int hashCode(final Object array) {
  1776.         return new HashCodeBuilder().append(array).toHashCode();
  1777.     }

  1778.     static <K> void increment(final Map<K, MutableInt> occurrences, final K boxed) {
  1779.         occurrences.computeIfAbsent(boxed, k -> new MutableInt()).increment();
  1780.     }

  1781.     /**
  1782.      * Finds the indices of the given value in the array.
  1783.      * <p>
  1784.      * This method returns an empty BitSet for a {@code null} input array.
  1785.      * </p>
  1786.      *
  1787.      * @param array  the array to search for the object, may be {@code null}
  1788.      * @param valueToFind  the value to find
  1789.      * @return a BitSet of all the indices of the value within the array,
  1790.      *  an empty BitSet if not found or {@code null} array input
  1791.      * @since 3.10
  1792.      */
  1793.     public static BitSet indexesOf(final boolean[] array, final boolean valueToFind) {
  1794.         return indexesOf(array, valueToFind, 0);
  1795.     }

  1796.     /**
  1797.      * Finds the indices of the given value in the array starting at the given index.
  1798.      * <p>
  1799.      * This method returns an empty BitSet for a {@code null} input array.
  1800.      * </p>
  1801.      * <p>
  1802.      * A negative startIndex is treated as zero. A startIndex larger than the array
  1803.      * length will return an empty BitSet ({@code -1}).
  1804.      * </p>
  1805.      *
  1806.      * @param array  the array to search for the object, may be {@code null}
  1807.      * @param valueToFind  the value to find
  1808.      * @param startIndex  the index to start searching at
  1809.      * @return a BitSet of all the indices of the value within the array,
  1810.      *  an empty BitSet if not found or {@code null}
  1811.      *  array input
  1812.      * @since 3.10
  1813.      */
  1814.     public static BitSet indexesOf(final boolean[] array, final boolean valueToFind, int startIndex) {
  1815.         final BitSet bitSet = new BitSet();
  1816.         if (array == null) {
  1817.             return bitSet;
  1818.         }
  1819.         while (startIndex < array.length) {
  1820.             startIndex = indexOf(array, valueToFind, startIndex);
  1821.             if (startIndex == INDEX_NOT_FOUND) {
  1822.                 break;
  1823.             }
  1824.             bitSet.set(startIndex);
  1825.             ++startIndex;
  1826.         }
  1827.         return bitSet;
  1828.     }

  1829.     /**
  1830.      * Finds the indices of the given value in the array.
  1831.      *
  1832.      * <p>This method returns an empty BitSet for a {@code null} input array.</p>
  1833.      *
  1834.      * @param array  the array to search for the object, may be {@code null}
  1835.      * @param valueToFind  the value to find
  1836.      * @return a BitSet of all the indices of the value within the array,
  1837.      *  an empty BitSet if not found or {@code null} array input
  1838.      * @since 3.10
  1839.      */
  1840.     public static BitSet indexesOf(final byte[] array, final byte valueToFind) {
  1841.         return indexesOf(array, valueToFind, 0);
  1842.     }

  1843.     /**
  1844.      * Finds the indices of the given value in the array starting at the given index.
  1845.      *
  1846.      * <p>This method returns an empty BitSet 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 an empty BitSet.</p>
  1850.      *
  1851.      * @param array  the array to search 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 a BitSet of all the indices of the value within the array,
  1855.      *  an empty BitSet if not found or {@code null} array input
  1856.      * @since 3.10
  1857.      */
  1858.     public static BitSet indexesOf(final byte[] array, final byte valueToFind, int startIndex) {
  1859.         final BitSet bitSet = new BitSet();
  1860.         if (array == null) {
  1861.             return bitSet;
  1862.         }
  1863.         while (startIndex < array.length) {
  1864.             startIndex = indexOf(array, valueToFind, startIndex);
  1865.             if (startIndex == INDEX_NOT_FOUND) {
  1866.                 break;
  1867.             }
  1868.             bitSet.set(startIndex);
  1869.             ++startIndex;
  1870.         }

  1871.         return bitSet;
  1872.     }

  1873.     /**
  1874.      * Finds the indices of the given value in the array.
  1875.      *
  1876.      * <p>This method returns an empty BitSet for a {@code null} input array.</p>
  1877.      *
  1878.      * @param array  the array to search for the object, may be {@code null}
  1879.      * @param valueToFind  the value to find
  1880.      * @return a BitSet of all the indices of the value within the array,
  1881.      *  an empty BitSet if not found or {@code null} array input
  1882.      * @since 3.10
  1883.      */
  1884.     public static BitSet indexesOf(final char[] array, final char valueToFind) {
  1885.         return indexesOf(array, valueToFind, 0);
  1886.     }

  1887.     /**
  1888.      * Finds the indices of the given value in the array starting at the given index.
  1889.      *
  1890.      * <p>This method returns an empty BitSet for a {@code null} input array.</p>
  1891.      *
  1892.      * <p>A negative startIndex is treated as zero. A startIndex larger than the array
  1893.      * length will return an empty BitSet.</p>
  1894.      *
  1895.      * @param array  the array to search for the object, may be {@code null}
  1896.      * @param valueToFind  the value to find
  1897.      * @param startIndex  the index to start searching at
  1898.      * @return a BitSet of all the indices of the value within the array,
  1899.      *  an empty BitSet if not found or {@code null} array input
  1900.      * @since 3.10
  1901.      */
  1902.     public static BitSet indexesOf(final char[] array, final char valueToFind, int startIndex) {
  1903.         final BitSet bitSet = new BitSet();
  1904.         if (array == null) {
  1905.             return bitSet;
  1906.         }
  1907.         while (startIndex < array.length) {
  1908.             startIndex = indexOf(array, valueToFind, startIndex);
  1909.             if (startIndex == INDEX_NOT_FOUND) {
  1910.                 break;
  1911.             }
  1912.             bitSet.set(startIndex);
  1913.             ++startIndex;
  1914.         }
  1915.         return bitSet;
  1916.     }

  1917.     /**
  1918.      * Finds the indices of the given value in the array.
  1919.      *
  1920.      * <p>This method returns empty BitSet for a {@code null} input array.</p>
  1921.      *
  1922.      * @param array  the array to search for the object, may be {@code null}
  1923.      * @param valueToFind  the value to find
  1924.      * @return a BitSet of all the indices of the value within the array,
  1925.      *  an empty BitSet if not found or {@code null} array input
  1926.      * @since 3.10
  1927.      */
  1928.     public static BitSet indexesOf(final double[] array, final double valueToFind) {
  1929.         return indexesOf(array, valueToFind, 0);
  1930.     }

  1931.     /**
  1932.      * Finds the indices of the given value within a given tolerance in the array.
  1933.      *
  1934.      * <p>
  1935.      * This method will return all the indices of the value which fall between the region
  1936.      * defined by valueToFind - tolerance and valueToFind + tolerance, each time between the nearest integers.
  1937.      * </p>
  1938.      *
  1939.      * <p>This method returns an empty BitSet for a {@code null} input array.</p>
  1940.      *
  1941.      * @param array  the array to search for the object, may be {@code null}
  1942.      * @param valueToFind  the value to find
  1943.      * @param tolerance tolerance of the search
  1944.      * @return a BitSet of all the indices of the value within the array,
  1945.      *  an empty BitSet if not found or {@code null} array input
  1946.      * @since 3.10
  1947.      */
  1948.     public static BitSet indexesOf(final double[] array, final double valueToFind, final double tolerance) {
  1949.         return indexesOf(array, valueToFind, 0, tolerance);
  1950.     }

  1951.     /**
  1952.      * Finds the indices of the given value in the array starting at the given index.
  1953.      *
  1954.      * <p>This method returns an empty BitSet for a {@code null} input array.</p>
  1955.      *
  1956.      * <p>A negative startIndex is treated as zero. A startIndex larger than the array
  1957.      * length will return an empty BitSet.</p>
  1958.      *
  1959.      * @param array  the array to search for the object, may be {@code null}
  1960.      * @param valueToFind  the value to find
  1961.      * @param startIndex  the index to start searching at
  1962.      * @return a BitSet of the indices of the value within the array,
  1963.      *  an empty BitSet if not found or {@code null} array input
  1964.      * @since 3.10
  1965.      */
  1966.     public static BitSet indexesOf(final double[] array, final double valueToFind, int startIndex) {
  1967.         final BitSet bitSet = new BitSet();
  1968.         if (array == null) {
  1969.             return bitSet;
  1970.         }
  1971.         while (startIndex < array.length) {
  1972.             startIndex = indexOf(array, valueToFind, startIndex);
  1973.             if (startIndex == INDEX_NOT_FOUND) {
  1974.                 break;
  1975.             }
  1976.             bitSet.set(startIndex);
  1977.             ++startIndex;
  1978.         }
  1979.         return bitSet;
  1980.     }

  1981.     /**
  1982.      * Finds the indices of the given value in the array starting at the given index.
  1983.      *
  1984.      * <p>
  1985.      * This method will return the indices of the values which fall between the region
  1986.      * defined by valueToFind - tolerance and valueToFind + tolerance, between the nearest integers.
  1987.      * </p>
  1988.      *
  1989.      * <p>This method returns an empty BitSet for a {@code null} input array.</p>
  1990.      *
  1991.      * <p>A negative startIndex is treated as zero. A startIndex larger than the array
  1992.      * length will return an empty BitSet.</p>
  1993.      *
  1994.      * @param array  the array to search for the object, may be {@code null}
  1995.      * @param valueToFind  the value to find
  1996.      * @param startIndex  the index to start searching at
  1997.      * @param tolerance tolerance of the search
  1998.      * @return a BitSet of the indices of the value within the array,
  1999.      *  an empty BitSet if not found or {@code null} array input
  2000.      * @since 3.10
  2001.      */
  2002.     public static BitSet indexesOf(final double[] array, final double valueToFind, int startIndex, final double tolerance) {
  2003.         final BitSet bitSet = new BitSet();
  2004.         if (array == null) {
  2005.             return bitSet;
  2006.         }
  2007.         while (startIndex < array.length) {
  2008.             startIndex = indexOf(array, valueToFind, startIndex, tolerance);
  2009.             if (startIndex == INDEX_NOT_FOUND) {
  2010.                 break;
  2011.             }
  2012.             bitSet.set(startIndex);
  2013.             ++startIndex;
  2014.         }
  2015.         return bitSet;
  2016.     }

  2017.     /**
  2018.      * Finds the indices of the given value in the array.
  2019.      *
  2020.      * <p>This method returns an empty BitSet for a {@code null} input array.</p>
  2021.      *
  2022.      * @param array  the array to search for the object, may be {@code null}
  2023.      * @param valueToFind  the value to find
  2024.      * @return a BitSet of all the indices of the value within the array,
  2025.      *  an empty BitSet if not found or {@code null} array input
  2026.      * @since 3.10
  2027.      */
  2028.     public static BitSet indexesOf(final float[] array, final float valueToFind) {
  2029.         return indexesOf(array, valueToFind, 0);
  2030.     }

  2031.     /**
  2032.      * Finds the indices of the given value in the array starting at the given index.
  2033.      *
  2034.      * <p>This method returns an empty BitSet for a {@code null} input array.</p>
  2035.      *
  2036.      * <p>A negative startIndex is treated as zero. A startIndex larger than the array
  2037.      * length will return empty BitSet.</p>
  2038.      *
  2039.      * @param array  the array to search for the object, may be {@code null}
  2040.      * @param valueToFind  the value to find
  2041.      * @param startIndex  the index to start searching at
  2042.      * @return a BitSet of all the indices of the value within the array,
  2043.      *  an empty BitSet if not found or {@code null} array input
  2044.      * @since 3.10
  2045.      */
  2046.     public static BitSet indexesOf(final float[] array, final float valueToFind, int startIndex) {
  2047.         final BitSet bitSet = new BitSet();
  2048.         if (array == null) {
  2049.             return bitSet;
  2050.         }
  2051.         while (startIndex < array.length) {
  2052.             startIndex = indexOf(array, valueToFind, startIndex);
  2053.             if (startIndex == INDEX_NOT_FOUND) {
  2054.                 break;
  2055.             }
  2056.             bitSet.set(startIndex);
  2057.             ++startIndex;
  2058.         }
  2059.         return bitSet;
  2060.     }

  2061.     /**
  2062.      * Finds the indices of the given value in the array.
  2063.      *
  2064.      * <p>This method returns an empty BitSet for a {@code null} input array.</p>
  2065.      *
  2066.      * @param array  the array to search for the object, may be {@code null}
  2067.      * @param valueToFind  the value to find
  2068.      * @return a BitSet of all the indices of the value within the array,
  2069.      *  an empty BitSet if not found or {@code null} array input
  2070.      * @since 3.10
  2071.      */
  2072.     public static BitSet indexesOf(final int[] array, final int valueToFind) {
  2073.         return indexesOf(array, valueToFind, 0);
  2074.     }

  2075.     /**
  2076.      * Finds the indices of the given value in the array starting at the given index.
  2077.      *
  2078.      * <p>This method returns an empty BitSet for a {@code null} input array.</p>
  2079.      *
  2080.      * <p>A negative startIndex is treated as zero. A startIndex larger than the array
  2081.      * length will return an empty BitSet.</p>
  2082.      *
  2083.      * @param array  the array to search for the object, may be {@code null}
  2084.      * @param valueToFind  the value to find
  2085.      * @param startIndex  the index to start searching at
  2086.      * @return a BitSet of all the indices of the value within the array,
  2087.      *  an empty BitSet if not found or {@code null} array input
  2088.      * @since 3.10
  2089.      */
  2090.     public static BitSet indexesOf(final int[] array, final int valueToFind, int startIndex) {
  2091.         final BitSet bitSet = new BitSet();
  2092.         if (array == null) {
  2093.             return bitSet;
  2094.         }
  2095.         while (startIndex < array.length) {
  2096.             startIndex = indexOf(array, valueToFind, startIndex);

  2097.             if (startIndex == INDEX_NOT_FOUND) {
  2098.                 break;
  2099.             }
  2100.             bitSet.set(startIndex);
  2101.             ++startIndex;
  2102.         }
  2103.         return bitSet;
  2104.     }

  2105.     /**
  2106.      * Finds the indices of the given value in the array.
  2107.      *
  2108.      * <p>This method returns an empty BitSet for a {@code null} input array.</p>
  2109.      *
  2110.      * @param array  the array to search for the object, may be {@code null}
  2111.      * @param valueToFind  the value to find
  2112.      * @return a BitSet of all the indices of the value within the array,
  2113.      *  an empty BitSet if not found or {@code null} array input
  2114.      * @since 3.10
  2115.      */
  2116.     public static BitSet indexesOf(final long[] array, final long valueToFind) {
  2117.         return indexesOf(array, valueToFind, 0);
  2118.     }

  2119.     /**
  2120.      * Finds the indices of the given value in the array starting at the given index.
  2121.      *
  2122.      * <p>This method returns an empty BitSet for a {@code null} input array.</p>
  2123.      *
  2124.      * <p>A negative startIndex is treated as zero. A startIndex larger than the array
  2125.      * length will return an empty BitSet.</p>
  2126.      *
  2127.      * @param array  the array to search for the object, may be {@code null}
  2128.      * @param valueToFind  the value to find
  2129.      * @param startIndex  the index to start searching at
  2130.      * @return a BitSet of all the indices of the value within the array,
  2131.      *  an empty BitSet if not found or {@code null} array input
  2132.      * @since 3.10
  2133.      */
  2134.     public static BitSet indexesOf(final long[] array, final long valueToFind, int startIndex) {
  2135.         final BitSet bitSet = new BitSet();
  2136.         if (array == null) {
  2137.             return bitSet;
  2138.         }
  2139.         while (startIndex < array.length) {
  2140.             startIndex = indexOf(array, valueToFind, startIndex);
  2141.             if (startIndex == INDEX_NOT_FOUND) {
  2142.                 break;
  2143.             }
  2144.             bitSet.set(startIndex);
  2145.             ++startIndex;
  2146.         }
  2147.         return bitSet;
  2148.     }

  2149.     /**
  2150.      * Finds the indices of the given object in the array.
  2151.      *
  2152.      * <p>This method returns an empty BitSet for a {@code null} input array.</p>
  2153.      *
  2154.      * @param array  the array to search for the object, may be {@code null}.
  2155.      * @param objectToFind  the object to find, may be {@code null}.
  2156.      * @return a BitSet of all the indices of the object within the array,
  2157.      *  an empty BitSet if not found or {@code null} array input
  2158.      * @since 3.10
  2159.      */
  2160.     public static BitSet indexesOf(final Object[] array, final Object objectToFind) {
  2161.         return indexesOf(array, objectToFind, 0);
  2162.     }

  2163.     /**
  2164.      * Finds the indices of the given object in the array starting at the given index.
  2165.      *
  2166.      * <p>This method returns an empty BitSet for a {@code null} input array.</p>
  2167.      *
  2168.      * <p>A negative startIndex is treated as zero. A startIndex larger than the array
  2169.      * length will return an empty BitSet.</p>
  2170.      *
  2171.      * @param array  the array to search for the object, may be {@code null}.
  2172.      * @param objectToFind  the object to find, may be {@code null}.
  2173.      * @param startIndex  the index to start searching at
  2174.      * @return a BitSet of all the indices of the object within the array starting at the index,
  2175.      *  an empty BitSet if not found or {@code null} array input
  2176.      * @since 3.10
  2177.      */
  2178.     public static BitSet indexesOf(final Object[] array, final Object objectToFind, int startIndex) {
  2179.         final BitSet bitSet = new BitSet();
  2180.         if (array == null) {
  2181.             return bitSet;
  2182.         }
  2183.         while (startIndex < array.length) {
  2184.             startIndex = indexOf(array, objectToFind, startIndex);
  2185.             if (startIndex == INDEX_NOT_FOUND) {
  2186.                 break;
  2187.             }
  2188.             bitSet.set(startIndex);
  2189.             ++startIndex;
  2190.         }
  2191.         return bitSet;
  2192.     }

  2193.     /**
  2194.      * Finds the indices of the given value in the array.
  2195.      *
  2196.      * <p>This method returns an empty BitSet for a {@code null} input array.</p>
  2197.      *
  2198.      * @param array  the array to search for the object, may be {@code null}
  2199.      * @param valueToFind  the value to find
  2200.      * @return a BitSet of all the indices of the value within the array,
  2201.      *  an empty BitSet if not found or {@code null} array input
  2202.      * @since 3.10
  2203.      */
  2204.     public static BitSet indexesOf(final short[] array, final short valueToFind) {
  2205.         return indexesOf(array, valueToFind, 0);
  2206.     }

  2207.     /**
  2208.      * Finds the indices of the given value in the array starting at the given index.
  2209.      *
  2210.      * <p>This method returns an empty BitSet for a {@code null} input array.</p>
  2211.      *
  2212.      * <p>A negative startIndex is treated as zero. A startIndex larger than the array
  2213.      * length will return an empty BitSet.</p>
  2214.      *
  2215.      * @param array  the array to search for the object, may be {@code null}
  2216.      * @param valueToFind  the value to find
  2217.      * @param startIndex  the index to start searching at
  2218.      * @return a BitSet of all the indices of the value within the array,
  2219.      *  an empty BitSet if not found or {@code null} array input
  2220.      * @since 3.10
  2221.      */
  2222.     public static BitSet indexesOf(final short[] array, final short valueToFind, int startIndex) {
  2223.         final BitSet bitSet = new BitSet();
  2224.         if (array == null) {
  2225.             return bitSet;
  2226.         }
  2227.         while (startIndex < array.length) {
  2228.             startIndex = indexOf(array, valueToFind, startIndex);
  2229.             if (startIndex == INDEX_NOT_FOUND) {
  2230.                 break;
  2231.             }
  2232.             bitSet.set(startIndex);
  2233.             ++startIndex;
  2234.         }
  2235.         return bitSet;
  2236.     }

  2237.     /**
  2238.      * Finds the index of the given value in the array.
  2239.      * <p>
  2240.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  2241.      * </p>
  2242.      *
  2243.      * @param array  the array to search for the object, may be {@code null}
  2244.      * @param valueToFind  the value to find
  2245.      * @return the index of the value within the array,
  2246.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  2247.      */
  2248.     public static int indexOf(final boolean[] array, final boolean valueToFind) {
  2249.         return indexOf(array, valueToFind, 0);
  2250.     }

  2251.     /**
  2252.      * Finds the index of the given value in the array starting at the given index.
  2253.      * <p>
  2254.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  2255.      * </p>
  2256.      * <p>
  2257.      * A negative startIndex is treated as zero. A startIndex larger than the array
  2258.      * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
  2259.      * </p>
  2260.      *
  2261.      * @param array  the array to search for the object, may be {@code null}
  2262.      * @param valueToFind  the value to find
  2263.      * @param startIndex  the index to start searching at
  2264.      * @return the index of the value within the array,
  2265.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null}
  2266.      *  array input
  2267.      */
  2268.     public static int indexOf(final boolean[] array, final boolean valueToFind, final int startIndex) {
  2269.         if (isEmpty(array)) {
  2270.             return INDEX_NOT_FOUND;
  2271.         }
  2272.         for (int i = max0(startIndex); i < array.length; i++) {
  2273.             if (valueToFind == array[i]) {
  2274.                 return i;
  2275.             }
  2276.         }
  2277.         return INDEX_NOT_FOUND;
  2278.     }

  2279.     /**
  2280.      * Finds the index of the given value in the array.
  2281.      * <p>
  2282.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  2283.      * </p>
  2284.      *
  2285.      * @param array  the array to search for the object, may be {@code null}
  2286.      * @param valueToFind  the value to find
  2287.      * @return the index of the value within the array,
  2288.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  2289.      */
  2290.     public static int indexOf(final byte[] array, final byte valueToFind) {
  2291.         return indexOf(array, valueToFind, 0);
  2292.     }

  2293.     /**
  2294.      * Finds the index of the given value in the array starting at the given index.
  2295.      * <p>
  2296.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  2297.      * </p>
  2298.      * <p>
  2299.      * A negative startIndex is treated as zero. A startIndex larger than the array
  2300.      * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
  2301.      * </p>
  2302.      *
  2303.      * @param array  the array to search for the object, may be {@code null}
  2304.      * @param valueToFind  the value to find
  2305.      * @param startIndex  the index to start searching at
  2306.      * @return the index of the value within the array,
  2307.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  2308.      */
  2309.     public static int indexOf(final byte[] array, final byte valueToFind, final int startIndex) {
  2310.         if (array == null) {
  2311.             return INDEX_NOT_FOUND;
  2312.         }
  2313.         for (int i = max0(startIndex); i < array.length; i++) {
  2314.             if (valueToFind == array[i]) {
  2315.                 return i;
  2316.             }
  2317.         }
  2318.         return INDEX_NOT_FOUND;
  2319.     }

  2320.     /**
  2321.      * Finds the index of the given value in the array.
  2322.      * <p>
  2323.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  2324.      * </p>
  2325.      *
  2326.      * @param array  the array to search for the object, may be {@code null}
  2327.      * @param valueToFind  the value to find
  2328.      * @return the index of the value within the array,
  2329.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  2330.      * @since 2.1
  2331.      */
  2332.     public static int indexOf(final char[] array, final char valueToFind) {
  2333.         return indexOf(array, valueToFind, 0);
  2334.     }

  2335.     /**
  2336.      * Finds the index of the given value in the array starting at the given index.
  2337.      * <p>
  2338.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  2339.      * </p>
  2340.      * <p>
  2341.      * A negative startIndex is treated as zero. A startIndex larger than the array
  2342.      * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
  2343.      * </p>
  2344.      *
  2345.      * @param array  the array to search for the object, may be {@code null}
  2346.      * @param valueToFind  the value to find
  2347.      * @param startIndex  the index to start searching at
  2348.      * @return the index of the value within the array,
  2349.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  2350.      * @since 2.1
  2351.      */
  2352.     public static int indexOf(final char[] array, final char valueToFind, final int startIndex) {
  2353.         if (array == null) {
  2354.             return INDEX_NOT_FOUND;
  2355.         }
  2356.         for (int i = max0(startIndex); i < array.length; i++) {
  2357.             if (valueToFind == array[i]) {
  2358.                 return i;
  2359.             }
  2360.         }
  2361.         return INDEX_NOT_FOUND;
  2362.     }

  2363.     /**
  2364.      * Finds the index of the given value in the array.
  2365.      * <p>
  2366.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  2367.      * </p>
  2368.      *
  2369.      * @param array  the array to search for the object, may be {@code null}
  2370.      * @param valueToFind  the value to find
  2371.      * @return the index of the value within the array,
  2372.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  2373.      */
  2374.     public static int indexOf(final double[] array, final double valueToFind) {
  2375.         return indexOf(array, valueToFind, 0);
  2376.     }

  2377.     /**
  2378.      * Finds the index of the given value within a given tolerance in the array.
  2379.      * This method will return the index of the first value which falls between the region
  2380.      * defined by valueToFind - tolerance and valueToFind + tolerance.
  2381.      * <p>
  2382.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  2383.      * </p>
  2384.      *
  2385.      * @param array  the array to search for the object, may be {@code null}
  2386.      * @param valueToFind  the value to find
  2387.      * @param tolerance tolerance of the search
  2388.      * @return the index of the value within the array,
  2389.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  2390.      */
  2391.     public static int indexOf(final double[] array, final double valueToFind, final double tolerance) {
  2392.         return indexOf(array, valueToFind, 0, tolerance);
  2393.     }

  2394.     /**
  2395.      * Finds the index of the given value in the array starting at the given index.
  2396.      * <p>
  2397.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  2398.      * </p>
  2399.      * <p>
  2400.      * A negative startIndex is treated as zero. A startIndex larger than the array
  2401.      * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
  2402.      * </p>
  2403.      *
  2404.      * @param array  the array to search for the object, may be {@code null}
  2405.      * @param valueToFind  the value to find
  2406.      * @param startIndex  the index to start searching at
  2407.      * @return the index of the value within the array,
  2408.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  2409.      */
  2410.     public static int indexOf(final double[] array, final double valueToFind, final int startIndex) {
  2411.         if (isEmpty(array)) {
  2412.             return INDEX_NOT_FOUND;
  2413.         }
  2414.         final boolean searchNaN = Double.isNaN(valueToFind);
  2415.         for (int i = max0(startIndex); i < array.length; i++) {
  2416.             final double element = array[i];
  2417.             if (valueToFind == element || searchNaN && Double.isNaN(element)) {
  2418.                 return i;
  2419.             }
  2420.         }
  2421.         return INDEX_NOT_FOUND;
  2422.     }

  2423.     /**
  2424.      * Finds the index of the given value in the array starting at the given index.
  2425.      * This method will return the index of the first value which falls between the region
  2426.      * defined by valueToFind - tolerance and valueToFind + tolerance.
  2427.      * <p>
  2428.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  2429.      * </p>
  2430.      * <p>
  2431.      * A negative startIndex is treated as zero. A startIndex larger than the array
  2432.      * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
  2433.      * </p>
  2434.      *
  2435.      * @param array  the array to search for the object, may be {@code null}
  2436.      * @param valueToFind  the value to find
  2437.      * @param startIndex  the index to start searching at
  2438.      * @param tolerance tolerance of the search
  2439.      * @return the index of the value within the array,
  2440.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  2441.      */
  2442.     public static int indexOf(final double[] array, final double valueToFind, final int startIndex, final double tolerance) {
  2443.         if (isEmpty(array)) {
  2444.             return INDEX_NOT_FOUND;
  2445.         }
  2446.         final double min = valueToFind - tolerance;
  2447.         final double max = valueToFind + tolerance;
  2448.         for (int i = max0(startIndex); i < array.length; i++) {
  2449.             if (array[i] >= min && array[i] <= max) {
  2450.                 return i;
  2451.             }
  2452.         }
  2453.         return INDEX_NOT_FOUND;
  2454.     }

  2455.     /**
  2456.      * Finds the index of the given value in the array.
  2457.      * <p>
  2458.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  2459.      * </p>
  2460.      *
  2461.      * @param array  the array to search for the object, may be {@code null}
  2462.      * @param valueToFind  the value to find
  2463.      * @return the index of the value within the array,
  2464.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  2465.      */
  2466.     public static int indexOf(final float[] array, final float valueToFind) {
  2467.         return indexOf(array, valueToFind, 0);
  2468.     }

  2469.     /**
  2470.      * Finds the index of the given value in the array starting at the given index.
  2471.      * <p>
  2472.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  2473.      * </p>
  2474.      * <p>
  2475.      * A negative startIndex is treated as zero. A startIndex larger than the array
  2476.      * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
  2477.      * </p>
  2478.      *
  2479.      * @param array  the array to search for the object, may be {@code null}
  2480.      * @param valueToFind  the value to find
  2481.      * @param startIndex  the index to start searching at
  2482.      * @return the index of the value within the array,
  2483.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  2484.      */
  2485.     public static int indexOf(final float[] array, final float valueToFind, final int startIndex) {
  2486.         if (isEmpty(array)) {
  2487.             return INDEX_NOT_FOUND;
  2488.         }
  2489.         final boolean searchNaN = Float.isNaN(valueToFind);
  2490.         for (int i = max0(startIndex); i < array.length; i++) {
  2491.             final float element = array[i];
  2492.             if (valueToFind == element || searchNaN && Float.isNaN(element)) {
  2493.                 return i;
  2494.             }
  2495.         }
  2496.         return INDEX_NOT_FOUND;
  2497.     }

  2498.     /**
  2499.      * Finds the index of the given value in the array.
  2500.      * <p>
  2501.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  2502.      * </p>
  2503.      *
  2504.      * @param array  the array to search for the object, may be {@code null}
  2505.      * @param valueToFind  the value to find
  2506.      * @return the index of the value within the array,
  2507.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  2508.      */
  2509.     public static int indexOf(final int[] array, final int valueToFind) {
  2510.         return indexOf(array, valueToFind, 0);
  2511.     }

  2512.     /**
  2513.      * Finds the index of the given value in the array starting at the given index.
  2514.      * <p>
  2515.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  2516.      * </p>
  2517.      * <p>
  2518.      * A negative startIndex is treated as zero. A startIndex larger than the array
  2519.      * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
  2520.      * </p>
  2521.      *
  2522.      * @param array  the array to search for the object, may be {@code null}
  2523.      * @param valueToFind  the value to find
  2524.      * @param startIndex  the index to start searching at
  2525.      * @return the index of the value within the array,
  2526.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  2527.      */
  2528.     public static int indexOf(final int[] array, final int valueToFind, final int startIndex) {
  2529.         if (array == null) {
  2530.             return INDEX_NOT_FOUND;
  2531.         }
  2532.         for (int i = max0(startIndex); i < array.length; i++) {
  2533.             if (valueToFind == array[i]) {
  2534.                 return i;
  2535.             }
  2536.         }
  2537.         return INDEX_NOT_FOUND;
  2538.     }

  2539.     /**
  2540.      * Finds the index of the given value in the array.
  2541.      * <p>
  2542.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  2543.      * </p>
  2544.      *
  2545.      * @param array the array to search for the object, may be {@code null}
  2546.      * @param valueToFind the value to find
  2547.      * @return the index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null}
  2548.      *         array input
  2549.      */
  2550.     public static int indexOf(final long[] array, final long valueToFind) {
  2551.         return indexOf(array, valueToFind, 0);
  2552.     }

  2553.     /**
  2554.      * Finds the index of the given value in the array starting at the given index.
  2555.      * <p>
  2556.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  2557.      * </p>
  2558.      * <p>
  2559.      * A negative startIndex is treated as zero. A startIndex larger than the array
  2560.      * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
  2561.      * </p>
  2562.      *
  2563.      * @param array  the array to search for the object, may be {@code null}
  2564.      * @param valueToFind  the value to find
  2565.      * @param startIndex  the index to start searching at
  2566.      * @return the index of the value within the array,
  2567.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  2568.      */
  2569.     public static int indexOf(final long[] array, final long valueToFind, final int startIndex) {
  2570.         if (array == null) {
  2571.             return INDEX_NOT_FOUND;
  2572.         }
  2573.         for (int i = max0(startIndex); i < array.length; i++) {
  2574.             if (valueToFind == array[i]) {
  2575.                 return i;
  2576.             }
  2577.         }
  2578.         return INDEX_NOT_FOUND;
  2579.     }

  2580.     /**
  2581.      * Finds the index of the given object in the array.
  2582.      * <p>
  2583.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  2584.      * </p>
  2585.      *
  2586.      * @param array  the array to search for the object, may be {@code null}.
  2587.      * @param objectToFind  the object to find, may be {@code null}.
  2588.      * @return the index of the object within the array,
  2589.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  2590.      */
  2591.     public static int indexOf(final Object[] array, final Object objectToFind) {
  2592.         return indexOf(array, objectToFind, 0);
  2593.     }

  2594.     /**
  2595.      * Finds the index of the given object in the array starting at the given index.
  2596.      * <p>
  2597.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  2598.      * </p>
  2599.      * <p>
  2600.      * A negative startIndex is treated as zero. A startIndex larger than the array
  2601.      * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
  2602.      * </p>
  2603.      *
  2604.      * @param array  the array to search for the object, may be {@code null}.
  2605.      * @param objectToFind  the object to find, may be {@code null}.
  2606.      * @param startIndex  the index to start searching at
  2607.      * @return the index of the object within the array starting at the index,
  2608.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  2609.      */
  2610.     public static int indexOf(final Object[] array, final Object objectToFind, int startIndex) {
  2611.         if (array == null) {
  2612.             return INDEX_NOT_FOUND;
  2613.         }
  2614.         startIndex = max0(startIndex);
  2615.         if (objectToFind == null) {
  2616.             for (int i = startIndex; i < array.length; i++) {
  2617.                 if (array[i] == null) {
  2618.                     return i;
  2619.                 }
  2620.             }
  2621.         } else {
  2622.             for (int i = startIndex; i < array.length; i++) {
  2623.                 if (objectToFind.equals(array[i])) {
  2624.                     return i;
  2625.                 }
  2626.             }
  2627.         }
  2628.         return INDEX_NOT_FOUND;
  2629.     }

  2630.     /**
  2631.      * Finds the index of the given value in the array.
  2632.      * <p>
  2633.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  2634.      * </p>
  2635.      *
  2636.      * @param array  the array to search for the object, may be {@code null}
  2637.      * @param valueToFind  the value to find
  2638.      * @return the index of the value within the array,
  2639.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  2640.      */
  2641.     public static int indexOf(final short[] array, final short valueToFind) {
  2642.         return indexOf(array, valueToFind, 0);
  2643.     }

  2644.     /**
  2645.      * Finds the index of the given value in the array starting at the given index.
  2646.      * <p>
  2647.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  2648.      * </p>
  2649.      * <p>
  2650.      * A negative startIndex is treated as zero. A startIndex larger than the array
  2651.      * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
  2652.      * </p>
  2653.      *
  2654.      * @param array  the array to search for the object, may be {@code null}
  2655.      * @param valueToFind  the value to find
  2656.      * @param startIndex  the index to start searching at
  2657.      * @return the index of the value within the array,
  2658.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  2659.      */
  2660.     public static int indexOf(final short[] array, final short valueToFind, final int startIndex) {
  2661.         if (array == null) {
  2662.             return INDEX_NOT_FOUND;
  2663.         }
  2664.         for (int i = max0(startIndex); i < array.length; i++) {
  2665.             if (valueToFind == array[i]) {
  2666.                 return i;
  2667.             }
  2668.         }
  2669.         return INDEX_NOT_FOUND;
  2670.     }

  2671.     /**
  2672.      * Inserts elements into an array at the given index (starting from zero).
  2673.      *
  2674.      * <p>When an array is returned, it is always a new array.</p>
  2675.      *
  2676.      * <pre>
  2677.      * ArrayUtils.insert(index, null, null)      = null
  2678.      * ArrayUtils.insert(index, array, null)     = cloned copy of 'array'
  2679.      * ArrayUtils.insert(index, null, values)    = null
  2680.      * </pre>
  2681.      *
  2682.      * @param index the position within {@code array} to insert the new values
  2683.      * @param array the array to insert the values into, may be {@code null}
  2684.      * @param values the new values to insert, may be {@code null}
  2685.      * @return The new array or {@code null} if the given array is {@code null}.
  2686.      * @throws IndexOutOfBoundsException if {@code array} is provided
  2687.      * and either {@code index < 0} or {@code index > array.length}
  2688.      * @since 3.6
  2689.      */
  2690.     public static boolean[] insert(final int index, final boolean[] array, final boolean... values) {
  2691.         if (array == null) {
  2692.             return null;
  2693.         }
  2694.         if (isEmpty(values)) {
  2695.             return clone(array);
  2696.         }
  2697.         if (index < 0 || index > array.length) {
  2698.             throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
  2699.         }
  2700.         final boolean[] result = new boolean[array.length + values.length];
  2701.         System.arraycopy(values, 0, result, index, values.length);
  2702.         if (index > 0) {
  2703.             System.arraycopy(array, 0, result, 0, index);
  2704.         }
  2705.         if (index < array.length) {
  2706.             System.arraycopy(array, index, result, index + values.length, array.length - index);
  2707.         }
  2708.         return result;
  2709.     }

  2710.     /**
  2711.      * Inserts elements into an array at the given index (starting from zero).
  2712.      *
  2713.      * <p>When an array is returned, it is always a new array.</p>
  2714.      *
  2715.      * <pre>
  2716.      * ArrayUtils.insert(index, null, null)      = null
  2717.      * ArrayUtils.insert(index, array, null)     = cloned copy of 'array'
  2718.      * ArrayUtils.insert(index, null, values)    = null
  2719.      * </pre>
  2720.      *
  2721.      * @param index the position within {@code array} to insert the new values
  2722.      * @param array the array to insert the values into, may be {@code null}
  2723.      * @param values the new values to insert, may be {@code null}
  2724.      * @return The new array or {@code null} if the given array is {@code null}.
  2725.      * @throws IndexOutOfBoundsException if {@code array} is provided
  2726.      * and either {@code index < 0} or {@code index > array.length}
  2727.      * @since 3.6
  2728.      */
  2729.     public static byte[] insert(final int index, final byte[] array, final byte... values) {
  2730.         if (array == null) {
  2731.             return null;
  2732.         }
  2733.         if (isEmpty(values)) {
  2734.             return clone(array);
  2735.         }
  2736.         if (index < 0 || index > array.length) {
  2737.             throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
  2738.         }
  2739.         final byte[] result = new byte[array.length + values.length];
  2740.         System.arraycopy(values, 0, result, index, values.length);
  2741.         if (index > 0) {
  2742.             System.arraycopy(array, 0, result, 0, index);
  2743.         }
  2744.         if (index < array.length) {
  2745.             System.arraycopy(array, index, result, index + values.length, array.length - index);
  2746.         }
  2747.         return result;
  2748.     }

  2749.     /**
  2750.      * Inserts elements into an array at the given index (starting from zero).
  2751.      *
  2752.      * <p>When an array is returned, it is always a new array.</p>
  2753.      *
  2754.      * <pre>
  2755.      * ArrayUtils.insert(index, null, null)      = null
  2756.      * ArrayUtils.insert(index, array, null)     = cloned copy of 'array'
  2757.      * ArrayUtils.insert(index, null, values)    = null
  2758.      * </pre>
  2759.      *
  2760.      * @param index the position within {@code array} to insert the new values
  2761.      * @param array the array to insert the values into, may be {@code null}
  2762.      * @param values the new values to insert, may be {@code null}
  2763.      * @return The new array or {@code null} if the given array is {@code null}.
  2764.      * @throws IndexOutOfBoundsException if {@code array} is provided
  2765.      * and either {@code index < 0} or {@code index > array.length}
  2766.      * @since 3.6
  2767.      */
  2768.     public static char[] insert(final int index, final char[] array, final char... values) {
  2769.         if (array == null) {
  2770.             return null;
  2771.         }
  2772.         if (isEmpty(values)) {
  2773.             return clone(array);
  2774.         }
  2775.         if (index < 0 || index > array.length) {
  2776.             throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
  2777.         }
  2778.         final char[] result = new char[array.length + values.length];
  2779.         System.arraycopy(values, 0, result, index, values.length);
  2780.         if (index > 0) {
  2781.             System.arraycopy(array, 0, result, 0, index);
  2782.         }
  2783.         if (index < array.length) {
  2784.             System.arraycopy(array, index, result, index + values.length, array.length - index);
  2785.         }
  2786.         return result;
  2787.     }

  2788.     /**
  2789.      * Inserts elements into an array at the given index (starting from zero).
  2790.      *
  2791.      * <p>When an array is returned, it is always a new array.</p>
  2792.      *
  2793.      * <pre>
  2794.      * ArrayUtils.insert(index, null, null)      = null
  2795.      * ArrayUtils.insert(index, array, null)     = cloned copy of 'array'
  2796.      * ArrayUtils.insert(index, null, values)    = null
  2797.      * </pre>
  2798.      *
  2799.      * @param index the position within {@code array} to insert the new values
  2800.      * @param array the array to insert the values into, may be {@code null}
  2801.      * @param values the new values to insert, may be {@code null}
  2802.      * @return The new array or {@code null} if the given array is {@code null}.
  2803.      * @throws IndexOutOfBoundsException if {@code array} is provided
  2804.      * and either {@code index < 0} or {@code index > array.length}
  2805.      * @since 3.6
  2806.      */
  2807.     public static double[] insert(final int index, final double[] array, final double... values) {
  2808.         if (array == null) {
  2809.             return null;
  2810.         }
  2811.         if (isEmpty(values)) {
  2812.             return clone(array);
  2813.         }
  2814.         if (index < 0 || index > array.length) {
  2815.             throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
  2816.         }
  2817.         final double[] result = new double[array.length + values.length];
  2818.         System.arraycopy(values, 0, result, index, values.length);
  2819.         if (index > 0) {
  2820.             System.arraycopy(array, 0, result, 0, index);
  2821.         }
  2822.         if (index < array.length) {
  2823.             System.arraycopy(array, index, result, index + values.length, array.length - index);
  2824.         }
  2825.         return result;
  2826.     }

  2827.     /**
  2828.      * Inserts elements into an array at the given index (starting from zero).
  2829.      *
  2830.      * <p>When an array is returned, it is always a new array.</p>
  2831.      *
  2832.      * <pre>
  2833.      * ArrayUtils.insert(index, null, null)      = null
  2834.      * ArrayUtils.insert(index, array, null)     = cloned copy of 'array'
  2835.      * ArrayUtils.insert(index, null, values)    = null
  2836.      * </pre>
  2837.      *
  2838.      * @param index the position within {@code array} to insert the new values
  2839.      * @param array the array to insert the values into, may be {@code null}
  2840.      * @param values the new values to insert, may be {@code null}
  2841.      * @return The new array or {@code null} if the given array is {@code null}.
  2842.      * @throws IndexOutOfBoundsException if {@code array} is provided
  2843.      * and either {@code index < 0} or {@code index > array.length}
  2844.      * @since 3.6
  2845.      */
  2846.     public static float[] insert(final int index, final float[] array, final float... values) {
  2847.         if (array == null) {
  2848.             return null;
  2849.         }
  2850.         if (isEmpty(values)) {
  2851.             return clone(array);
  2852.         }
  2853.         if (index < 0 || index > array.length) {
  2854.             throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
  2855.         }
  2856.         final float[] result = new float[array.length + values.length];
  2857.         System.arraycopy(values, 0, result, index, values.length);
  2858.         if (index > 0) {
  2859.             System.arraycopy(array, 0, result, 0, index);
  2860.         }
  2861.         if (index < array.length) {
  2862.             System.arraycopy(array, index, result, index + values.length, array.length - index);
  2863.         }
  2864.         return result;
  2865.     }

  2866.     /**
  2867.      * Inserts elements into an array at the given index (starting from zero).
  2868.      *
  2869.      * <p>When an array is returned, it is always a new array.</p>
  2870.      *
  2871.      * <pre>
  2872.      * ArrayUtils.insert(index, null, null)      = null
  2873.      * ArrayUtils.insert(index, array, null)     = cloned copy of 'array'
  2874.      * ArrayUtils.insert(index, null, values)    = null
  2875.      * </pre>
  2876.      *
  2877.      * @param index the position within {@code array} to insert the new values
  2878.      * @param array the array to insert the values into, may be {@code null}
  2879.      * @param values the new values to insert, may be {@code null}
  2880.      * @return The new array or {@code null} if the given array is {@code null}.
  2881.      * @throws IndexOutOfBoundsException if {@code array} is provided
  2882.      * and either {@code index < 0} or {@code index > array.length}
  2883.      * @since 3.6
  2884.      */
  2885.     public static int[] insert(final int index, final int[] array, final int... values) {
  2886.         if (array == null) {
  2887.             return null;
  2888.         }
  2889.         if (isEmpty(values)) {
  2890.             return clone(array);
  2891.         }
  2892.         if (index < 0 || index > array.length) {
  2893.             throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
  2894.         }
  2895.         final int[] result = new int[array.length + values.length];
  2896.         System.arraycopy(values, 0, result, index, values.length);
  2897.         if (index > 0) {
  2898.             System.arraycopy(array, 0, result, 0, index);
  2899.         }
  2900.         if (index < array.length) {
  2901.             System.arraycopy(array, index, result, index + values.length, array.length - index);
  2902.         }
  2903.         return result;
  2904.     }

  2905.     /**
  2906.      * Inserts elements into an array at the given index (starting from zero).
  2907.      *
  2908.      * <p>When an array is returned, it is always a new array.</p>
  2909.      *
  2910.      * <pre>
  2911.      * ArrayUtils.insert(index, null, null)      = null
  2912.      * ArrayUtils.insert(index, array, null)     = cloned copy of 'array'
  2913.      * ArrayUtils.insert(index, null, values)    = null
  2914.      * </pre>
  2915.      *
  2916.      * @param index the position within {@code array} to insert the new values
  2917.      * @param array the array to insert the values into, may be {@code null}
  2918.      * @param values the new values to insert, may be {@code null}
  2919.      * @return The new array or {@code null} if the given array is {@code null}.
  2920.      * @throws IndexOutOfBoundsException if {@code array} is provided
  2921.      * and either {@code index < 0} or {@code index > array.length}
  2922.      * @since 3.6
  2923.      */
  2924.     public static long[] insert(final int index, final long[] array, final long... values) {
  2925.         if (array == null) {
  2926.             return null;
  2927.         }
  2928.         if (isEmpty(values)) {
  2929.             return clone(array);
  2930.         }
  2931.         if (index < 0 || index > array.length) {
  2932.             throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
  2933.         }
  2934.         final long[] result = new long[array.length + values.length];
  2935.         System.arraycopy(values, 0, result, index, values.length);
  2936.         if (index > 0) {
  2937.             System.arraycopy(array, 0, result, 0, index);
  2938.         }
  2939.         if (index < array.length) {
  2940.             System.arraycopy(array, index, result, index + values.length, array.length - index);
  2941.         }
  2942.         return result;
  2943.     }

  2944.     /**
  2945.      * Inserts elements into an array at the given index (starting from zero).
  2946.      *
  2947.      * <p>When an array is returned, it is always a new array.</p>
  2948.      *
  2949.      * <pre>
  2950.      * ArrayUtils.insert(index, null, null)      = null
  2951.      * ArrayUtils.insert(index, array, null)     = cloned copy of 'array'
  2952.      * ArrayUtils.insert(index, null, values)    = null
  2953.      * </pre>
  2954.      *
  2955.      * @param index the position within {@code array} to insert the new values
  2956.      * @param array the array to insert the values into, may be {@code null}
  2957.      * @param values the new values to insert, may be {@code null}
  2958.      * @return The new array or {@code null} if the given array is {@code null}.
  2959.      * @throws IndexOutOfBoundsException if {@code array} is provided
  2960.      * and either {@code index < 0} or {@code index > array.length}
  2961.      * @since 3.6
  2962.      */
  2963.     public static short[] insert(final int index, final short[] array, final short... values) {
  2964.         if (array == null) {
  2965.             return null;
  2966.         }
  2967.         if (isEmpty(values)) {
  2968.             return clone(array);
  2969.         }
  2970.         if (index < 0 || index > array.length) {
  2971.             throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
  2972.         }
  2973.         final short[] result = new short[array.length + values.length];
  2974.         System.arraycopy(values, 0, result, index, values.length);
  2975.         if (index > 0) {
  2976.             System.arraycopy(array, 0, result, 0, index);
  2977.         }
  2978.         if (index < array.length) {
  2979.             System.arraycopy(array, index, result, index + values.length, array.length - index);
  2980.         }
  2981.         return result;
  2982.     }

  2983.     /**
  2984.      * Inserts elements into an array at the given index (starting from zero).
  2985.      *
  2986.      * <p>When an array is returned, it is always a new array.</p>
  2987.      *
  2988.      * <pre>
  2989.      * ArrayUtils.insert(index, null, null)      = null
  2990.      * ArrayUtils.insert(index, array, null)     = cloned copy of 'array'
  2991.      * ArrayUtils.insert(index, null, values)    = null
  2992.      * </pre>
  2993.      *
  2994.      * @param <T> The type of elements in {@code array} and {@code values}
  2995.      * @param index the position within {@code array} to insert the new values
  2996.      * @param array the array to insert the values into, may be {@code null}
  2997.      * @param values the new values to insert, may be {@code null}
  2998.      * @return The new array or {@code null} if the given array is {@code null}.
  2999.      * @throws IndexOutOfBoundsException if {@code array} is provided
  3000.      * and either {@code index < 0} or {@code index > array.length}
  3001.      * @since 3.6
  3002.      */
  3003.     @SafeVarargs
  3004.     public static <T> T[] insert(final int index, final T[] array, final T... values) {
  3005.         /*
  3006.          * Note on use of @SafeVarargs:
  3007.          *
  3008.          * By returning null when 'array' is null, we avoid returning the vararg
  3009.          * array to the caller. We also avoid relying on the type of the vararg
  3010.          * array, by inspecting the component type of 'array'.
  3011.          */
  3012.         if (array == null) {
  3013.             return null;
  3014.         }
  3015.         if (isEmpty(values)) {
  3016.             return clone(array);
  3017.         }
  3018.         if (index < 0 || index > array.length) {
  3019.             throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
  3020.         }
  3021.         final Class<T> type = getComponentType(array);
  3022.         final int length = array.length + values.length;
  3023.         final T[] result = newInstance(type, length);
  3024.         System.arraycopy(values, 0, result, index, values.length);
  3025.         if (index > 0) {
  3026.             System.arraycopy(array, 0, result, 0, index);
  3027.         }
  3028.         if (index < array.length) {
  3029.             System.arraycopy(array, index, result, index + values.length, array.length - index);
  3030.         }
  3031.         return result;
  3032.     }

  3033.     /**
  3034.      * Checks if an array is empty or {@code null}.
  3035.      *
  3036.      * @param array the array to test
  3037.      * @return {@code true} if the array is empty or {@code null}
  3038.      */
  3039.     private static boolean isArrayEmpty(final Object array) {
  3040.         return getLength(array) == 0;
  3041.     }

  3042.     /**
  3043.      * Tests whether a given array can safely be accessed at the given index.
  3044.      *
  3045.      * <pre>
  3046.      * ArrayUtils.isArrayIndexValid(null, 0)       = false
  3047.      * ArrayUtils.isArrayIndexValid([], 0)         = false
  3048.      * ArrayUtils.isArrayIndexValid(["a"], 0)      = true
  3049.      * </pre>
  3050.      *
  3051.      * @param <T> the component type of the array
  3052.      * @param array the array to inspect, may be {@code null}.
  3053.      * @param index the index of the array to be inspected
  3054.      * @return Whether the given index is safely-accessible in the given array
  3055.      * @since 3.8
  3056.      */
  3057.     public static <T> boolean isArrayIndexValid(final T[] array, final int index) {
  3058.         return index >= 0 && getLength(array) > index;
  3059.     }

  3060.     /**
  3061.      * Tests whether an array of primitive booleans is empty or {@code null}.
  3062.      *
  3063.      * @param array  the array to test
  3064.      * @return {@code true} if the array is empty or {@code null}
  3065.      * @since 2.1
  3066.      */
  3067.     public static boolean isEmpty(final boolean[] array) {
  3068.         return isArrayEmpty(array);
  3069.     }

  3070.     /**
  3071.      * Tests whether an array of primitive bytes is empty or {@code null}.
  3072.      *
  3073.      * @param array  the array to test
  3074.      * @return {@code true} if the array is empty or {@code null}
  3075.      * @since 2.1
  3076.      */
  3077.     public static boolean isEmpty(final byte[] array) {
  3078.         return isArrayEmpty(array);
  3079.     }

  3080.     /**
  3081.      * Tests whether an array of primitive chars is empty or {@code null}.
  3082.      *
  3083.      * @param array  the array to test
  3084.      * @return {@code true} if the array is empty or {@code null}
  3085.      * @since 2.1
  3086.      */
  3087.     public static boolean isEmpty(final char[] array) {
  3088.         return isArrayEmpty(array);
  3089.     }

  3090.     /**
  3091.      * Tests whether an array of primitive doubles is empty or {@code null}.
  3092.      *
  3093.      * @param array  the array to test
  3094.      * @return {@code true} if the array is empty or {@code null}
  3095.      * @since 2.1
  3096.      */
  3097.     public static boolean isEmpty(final double[] array) {
  3098.         return isArrayEmpty(array);
  3099.     }

  3100.     /**
  3101.      * Tests whether an array of primitive floats is empty or {@code null}.
  3102.      *
  3103.      * @param array  the array to test
  3104.      * @return {@code true} if the array is empty or {@code null}
  3105.      * @since 2.1
  3106.      */
  3107.     public static boolean isEmpty(final float[] array) {
  3108.         return isArrayEmpty(array);
  3109.     }

  3110.     /**
  3111.      * Tests whether an array of primitive ints is empty or {@code null}.
  3112.      *
  3113.      * @param array  the array to test
  3114.      * @return {@code true} if the array is empty or {@code null}
  3115.      * @since 2.1
  3116.      */
  3117.     public static boolean isEmpty(final int[] array) {
  3118.         return isArrayEmpty(array);
  3119.     }

  3120.     /**
  3121.      * Tests whether an array of primitive longs is empty or {@code null}.
  3122.      *
  3123.      * @param array  the array to test
  3124.      * @return {@code true} if the array is empty or {@code null}
  3125.      * @since 2.1
  3126.      */
  3127.     public static boolean isEmpty(final long[] array) {
  3128.         return isArrayEmpty(array);
  3129.     }

  3130.     /**
  3131.      * Tests whether an array of Objects is empty or {@code null}.
  3132.      *
  3133.      * @param array  the array to test
  3134.      * @return {@code true} if the array is empty or {@code null}
  3135.      * @since 2.1
  3136.      */
  3137.     public static boolean isEmpty(final Object[] array) {
  3138.         return isArrayEmpty(array);
  3139.     }

  3140.     /**
  3141.      * Tests whether an array of primitive shorts is empty or {@code null}.
  3142.      *
  3143.      * @param array  the array to test
  3144.      * @return {@code true} if the array is empty or {@code null}
  3145.      * @since 2.1
  3146.      */
  3147.     public static boolean isEmpty(final short[] array) {
  3148.         return isArrayEmpty(array);
  3149.     }

  3150.     /**
  3151.      * Tests whether two arrays have equal content, using equals(), handling multidimensional arrays
  3152.      * correctly.
  3153.      * <p>
  3154.      * Multi-dimensional primitive arrays are also handled correctly by this method.
  3155.      * </p>
  3156.      *
  3157.      * @param array1  the left-hand side array to compare, may be {@code null}
  3158.      * @param array2  the right-hand side array to compare, may be {@code null}
  3159.      * @return {@code true} if the arrays are equal
  3160.      * @deprecated this method has been replaced by {@code java.util.Objects.deepEquals(Object, Object)} and will be
  3161.      * removed from future releases.
  3162.      */
  3163.     @Deprecated
  3164.     public static boolean isEquals(final Object array1, final Object array2) {
  3165.         return new EqualsBuilder().append(array1, array2).isEquals();
  3166.     }

  3167.     /**
  3168.      * Tests whether an array of primitive booleans is not empty and not {@code null}.
  3169.      *
  3170.      * @param array  the array to test
  3171.      * @return {@code true} if the array is not empty and not {@code null}
  3172.      * @since 2.5
  3173.      */
  3174.     public static boolean isNotEmpty(final boolean[] array) {
  3175.         return !isEmpty(array);
  3176.     }

  3177.     /**
  3178.      * Tests whether an array of primitive bytes is not empty and not {@code null}.
  3179.      *
  3180.      * @param array  the array to test
  3181.      * @return {@code true} if the array is not empty and not {@code null}
  3182.      * @since 2.5
  3183.      */
  3184.     public static boolean isNotEmpty(final byte[] array) {
  3185.         return !isEmpty(array);
  3186.     }

  3187.     /**
  3188.      * Tests whether an array of primitive chars is not empty and not {@code null}.
  3189.      *
  3190.      * @param array  the array to test
  3191.      * @return {@code true} if the array is not empty and not {@code null}
  3192.      * @since 2.5
  3193.      */
  3194.     public static boolean isNotEmpty(final char[] array) {
  3195.         return !isEmpty(array);
  3196.     }

  3197.     /**
  3198.      * Tests whether an array of primitive doubles is not empty and not {@code null}.
  3199.      *
  3200.      * @param array  the array to test
  3201.      * @return {@code true} if the array is not empty and not {@code null}
  3202.      * @since 2.5
  3203.      */
  3204.     public static boolean isNotEmpty(final double[] array) {
  3205.         return !isEmpty(array);
  3206.     }

  3207.     /**
  3208.      * Tests whether an array of primitive floats is not empty and not {@code null}.
  3209.      *
  3210.      * @param array  the array to test
  3211.      * @return {@code true} if the array is not empty and not {@code null}
  3212.      * @since 2.5
  3213.      */
  3214.     public static boolean isNotEmpty(final float[] array) {
  3215.         return !isEmpty(array);
  3216.     }

  3217.     /**
  3218.      * Tests whether an array of primitive ints is not empty and not {@code null}.
  3219.      *
  3220.      * @param array  the array to test
  3221.      * @return {@code true} if the array is not empty and not {@code null}
  3222.      * @since 2.5
  3223.      */
  3224.     public static boolean isNotEmpty(final int[] array) {
  3225.         return !isEmpty(array);
  3226.     }

  3227.     /**
  3228.      * Tests whether an array of primitive longs is not empty and not {@code null}.
  3229.      *
  3230.      * @param array  the array to test
  3231.      * @return {@code true} if the array is not empty and not {@code null}
  3232.      * @since 2.5
  3233.      */
  3234.     public static boolean isNotEmpty(final long[] array) {
  3235.         return !isEmpty(array);
  3236.     }

  3237.     /**
  3238.      * Tests whether an array of primitive shorts is not empty and not {@code null}.
  3239.      *
  3240.      * @param array  the array to test
  3241.      * @return {@code true} if the array is not empty and not {@code null}
  3242.      * @since 2.5
  3243.      */
  3244.     public static boolean isNotEmpty(final short[] array) {
  3245.         return !isEmpty(array);
  3246.     }

  3247.     /**
  3248.      * Tests whether an array of Objects is not empty and not {@code null}.
  3249.      *
  3250.      * @param <T> the component type of the array
  3251.      * @param array  the array to test
  3252.      * @return {@code true} if the array is not empty and not {@code null}
  3253.      * @since 2.5
  3254.      */
  3255.      public static <T> boolean isNotEmpty(final T[] array) {
  3256.          return !isEmpty(array);
  3257.      }

  3258.     /**
  3259.      * Tests whether two arrays are the same length, treating
  3260.      * {@code null} arrays as length {@code 0}.
  3261.      *
  3262.      * @param array1 the first array, may be {@code null}
  3263.      * @param array2 the second array, may be {@code null}
  3264.      * @return {@code true} if length of arrays matches, treating
  3265.      *  {@code null} as an empty array
  3266.      */
  3267.     public static boolean isSameLength(final boolean[] array1, final boolean[] array2) {
  3268.         return getLength(array1) == getLength(array2);
  3269.     }

  3270.     /**
  3271.      * Tests whether two arrays are the same length, treating
  3272.      * {@code null} arrays as length {@code 0}.
  3273.      *
  3274.      * @param array1 the first array, may be {@code null}
  3275.      * @param array2 the second array, may be {@code null}
  3276.      * @return {@code true} if length of arrays matches, treating
  3277.      *  {@code null} as an empty array
  3278.      */
  3279.     public static boolean isSameLength(final byte[] array1, final byte[] array2) {
  3280.         return getLength(array1) == getLength(array2);
  3281.     }

  3282.     /**
  3283.      * Tests whether two arrays are the same length, treating
  3284.      * {@code null} arrays as length {@code 0}.
  3285.      *
  3286.      * @param array1 the first array, may be {@code null}
  3287.      * @param array2 the second array, may be {@code null}
  3288.      * @return {@code true} if length of arrays matches, treating
  3289.      *  {@code null} as an empty array
  3290.      */
  3291.     public static boolean isSameLength(final char[] array1, final char[] array2) {
  3292.         return getLength(array1) == getLength(array2);
  3293.     }

  3294.     /**
  3295.      * Tests whether two arrays are the same length, treating
  3296.      * {@code null} arrays as length {@code 0}.
  3297.      *
  3298.      * @param array1 the first array, may be {@code null}
  3299.      * @param array2 the second array, may be {@code null}
  3300.      * @return {@code true} if length of arrays matches, treating
  3301.      *  {@code null} as an empty array
  3302.      */
  3303.     public static boolean isSameLength(final double[] array1, final double[] array2) {
  3304.         return getLength(array1) == getLength(array2);
  3305.     }

  3306.     /**
  3307.      * Tests whether two arrays are the same length, treating
  3308.      * {@code null} arrays as length {@code 0}.
  3309.      *
  3310.      * @param array1 the first array, may be {@code null}
  3311.      * @param array2 the second array, may be {@code null}
  3312.      * @return {@code true} if length of arrays matches, treating
  3313.      *  {@code null} as an empty array
  3314.      */
  3315.     public static boolean isSameLength(final float[] array1, final float[] array2) {
  3316.         return getLength(array1) == getLength(array2);
  3317.     }

  3318.     /**
  3319.      * Tests whether two arrays are the same length, treating
  3320.      * {@code null} arrays as length {@code 0}.
  3321.      *
  3322.      * @param array1 the first array, may be {@code null}
  3323.      * @param array2 the second array, may be {@code null}
  3324.      * @return {@code true} if length of arrays matches, treating
  3325.      *  {@code null} as an empty array
  3326.      */
  3327.     public static boolean isSameLength(final int[] array1, final int[] array2) {
  3328.         return getLength(array1) == getLength(array2);
  3329.     }

  3330.     /**
  3331.      * Tests whether two arrays are the same length, treating
  3332.      * {@code null} arrays as length {@code 0}.
  3333.      *
  3334.      * @param array1 the first array, may be {@code null}
  3335.      * @param array2 the second array, may be {@code null}
  3336.      * @return {@code true} if length of arrays matches, treating
  3337.      *  {@code null} as an empty array
  3338.      */
  3339.     public static boolean isSameLength(final long[] array1, final long[] array2) {
  3340.         return getLength(array1) == getLength(array2);
  3341.     }

  3342.     /**
  3343.      * Tests whether two arrays are the same length, treating
  3344.      * {@code null} arrays as length {@code 0}.
  3345.      * <p>
  3346.      * Any multi-dimensional aspects of the arrays are ignored.
  3347.      * </p>
  3348.      *
  3349.      * @param array1 the first array, may be {@code null}
  3350.      * @param array2 the second array, may be {@code null}
  3351.      * @return {@code true} if length of arrays matches, treating
  3352.      *  {@code null} as an empty array
  3353.      * @since 3.11
  3354.      */
  3355.     public static boolean isSameLength(final Object array1, final Object array2) {
  3356.         return getLength(array1) == getLength(array2);
  3357.     }

  3358.     /**
  3359.      * Tests whether two arrays are the same length, treating
  3360.      * {@code null} arrays as length {@code 0}.
  3361.      * <p>
  3362.      * Any multi-dimensional aspects of the arrays are ignored.
  3363.      * </p>
  3364.      *
  3365.      * @param array1 the first array, may be {@code null}
  3366.      * @param array2 the second array, may be {@code null}
  3367.      * @return {@code true} if length of arrays matches, treating
  3368.      *  {@code null} as an empty array
  3369.      */
  3370.     public static boolean isSameLength(final Object[] array1, final Object[] array2) {
  3371.         return getLength(array1) == getLength(array2);
  3372.     }

  3373.     /**
  3374.      * Tests whether two arrays are the same length, treating
  3375.      * {@code null} arrays as length {@code 0}.
  3376.      *
  3377.      * @param array1 the first array, may be {@code null}
  3378.      * @param array2 the second array, may be {@code null}
  3379.      * @return {@code true} if length of arrays matches, treating
  3380.      *  {@code null} as an empty array
  3381.      */
  3382.     public static boolean isSameLength(final short[] array1, final short[] array2) {
  3383.         return getLength(array1) == getLength(array2);
  3384.     }

  3385.     /**
  3386.      * Tests whether two arrays are the same type taking into account
  3387.      * multidimensional arrays.
  3388.      *
  3389.      * @param array1 the first array, must not be {@code null}
  3390.      * @param array2 the second array, must not be {@code null}
  3391.      * @return {@code true} if type of arrays matches
  3392.      * @throws IllegalArgumentException if either array is {@code null}
  3393.      */
  3394.     public static boolean isSameType(final Object array1, final Object array2) {
  3395.         if (array1 == null || array2 == null) {
  3396.             throw new IllegalArgumentException("The Array must not be null");
  3397.         }
  3398.         return array1.getClass().getName().equals(array2.getClass().getName());
  3399.     }

  3400.     /**
  3401.      * Tests whether whether the provided array is sorted according to natural ordering
  3402.      * ({@code false} before {@code true}).
  3403.      *
  3404.      * @param array the array to check
  3405.      * @return whether the array is sorted according to natural ordering
  3406.      * @since 3.4
  3407.      */
  3408.     public static boolean isSorted(final boolean[] array) {
  3409.         if (getLength(array) < 2) {
  3410.             return true;
  3411.         }
  3412.         boolean previous = array[0];
  3413.         final int n = array.length;
  3414.         for (int i = 1; i < n; i++) {
  3415.             final boolean current = array[i];
  3416.             if (BooleanUtils.compare(previous, current) > 0) {
  3417.                 return false;
  3418.             }
  3419.             previous = current;
  3420.         }
  3421.         return true;
  3422.     }

  3423.     /**
  3424.      * Tests whether the provided array is sorted according to natural ordering.
  3425.      *
  3426.      * @param array the array to check
  3427.      * @return whether the array is sorted according to natural ordering
  3428.      * @since 3.4
  3429.      */
  3430.     public static boolean isSorted(final byte[] array) {
  3431.         if (getLength(array) < 2) {
  3432.             return true;
  3433.         }
  3434.         byte previous = array[0];
  3435.         final int n = array.length;
  3436.         for (int i = 1; i < n; i++) {
  3437.             final byte current = array[i];
  3438.             if (NumberUtils.compare(previous, current) > 0) {
  3439.                 return false;
  3440.             }
  3441.             previous = current;
  3442.         }
  3443.         return true;
  3444.     }

  3445.     /**
  3446.      * Tests whether the provided array is sorted according to natural ordering.
  3447.      *
  3448.      * @param array the array to check
  3449.      * @return whether the array is sorted according to natural ordering
  3450.      * @since 3.4
  3451.      */
  3452.     public static boolean isSorted(final char[] array) {
  3453.         if (getLength(array) < 2) {
  3454.             return true;
  3455.         }
  3456.         char previous = array[0];
  3457.         final int n = array.length;
  3458.         for (int i = 1; i < n; i++) {
  3459.             final char current = array[i];
  3460.             if (CharUtils.compare(previous, current) > 0) {
  3461.                 return false;
  3462.             }
  3463.             previous = current;
  3464.         }
  3465.         return true;
  3466.     }

  3467.     /**
  3468.      * Tests whether the provided array is sorted according to natural ordering.
  3469.      *
  3470.      * @param array the array to check
  3471.      * @return whether the array is sorted according to natural ordering
  3472.      * @since 3.4
  3473.      */
  3474.     public static boolean isSorted(final double[] array) {
  3475.         if (getLength(array) < 2) {
  3476.             return true;
  3477.         }
  3478.         double previous = array[0];
  3479.         final int n = array.length;
  3480.         for (int i = 1; i < n; i++) {
  3481.             final double current = array[i];
  3482.             if (Double.compare(previous, current) > 0) {
  3483.                 return false;
  3484.             }
  3485.             previous = current;
  3486.         }
  3487.         return true;
  3488.     }

  3489.     /**
  3490.      * Tests whether the provided array is sorted according to natural ordering.
  3491.      *
  3492.      * @param array the array to check
  3493.      * @return whether the array is sorted according to natural ordering
  3494.      * @since 3.4
  3495.      */
  3496.     public static boolean isSorted(final float[] array) {
  3497.         if (getLength(array) < 2) {
  3498.             return true;
  3499.         }
  3500.         float previous = array[0];
  3501.         final int n = array.length;
  3502.         for (int i = 1; i < n; i++) {
  3503.             final float current = array[i];
  3504.             if (Float.compare(previous, current) > 0) {
  3505.                 return false;
  3506.             }
  3507.             previous = current;
  3508.         }
  3509.         return true;
  3510.     }

  3511.     /**
  3512.      * Tests whether the provided array is sorted according to natural ordering.
  3513.      *
  3514.      * @param array the array to check
  3515.      * @return whether the array is sorted according to natural ordering
  3516.      * @since 3.4
  3517.      */
  3518.     public static boolean isSorted(final int[] array) {
  3519.         if (getLength(array) < 2) {
  3520.             return true;
  3521.         }
  3522.         int previous = array[0];
  3523.         final int n = array.length;
  3524.         for (int i = 1; i < n; i++) {
  3525.             final int current = array[i];
  3526.             if (NumberUtils.compare(previous, current) > 0) {
  3527.                 return false;
  3528.             }
  3529.             previous = current;
  3530.         }
  3531.         return true;
  3532.     }

  3533.     /**
  3534.      * Tests whether the provided array is sorted according to natural ordering.
  3535.      *
  3536.      * @param array the array to check
  3537.      * @return whether the array is sorted according to natural ordering
  3538.      * @since 3.4
  3539.      */
  3540.     public static boolean isSorted(final long[] array) {
  3541.         if (getLength(array) < 2) {
  3542.             return true;
  3543.         }
  3544.         long previous = array[0];
  3545.         final int n = array.length;
  3546.         for (int i = 1; i < n; i++) {
  3547.             final long current = array[i];
  3548.             if (NumberUtils.compare(previous, current) > 0) {
  3549.                 return false;
  3550.             }
  3551.             previous = current;
  3552.         }
  3553.         return true;
  3554.     }

  3555.     /**
  3556.      * Tests whether the provided array is sorted according to natural ordering.
  3557.      *
  3558.      * @param array the array to check
  3559.      * @return whether the array is sorted according to natural ordering
  3560.      * @since 3.4
  3561.      */
  3562.     public static boolean isSorted(final short[] array) {
  3563.         if (getLength(array) < 2) {
  3564.             return true;
  3565.         }
  3566.         short previous = array[0];
  3567.         final int n = array.length;
  3568.         for (int i = 1; i < n; i++) {
  3569.             final short current = array[i];
  3570.             if (NumberUtils.compare(previous, current) > 0) {
  3571.                 return false;
  3572.             }
  3573.             previous = current;
  3574.         }
  3575.         return true;
  3576.     }

  3577.     /**
  3578.      * Tests whether the provided array is sorted according to the class's
  3579.      * {@code compareTo} method.
  3580.      *
  3581.      * @param array the array to check
  3582.      * @param <T> the datatype of the array to check, it must implement {@link Comparable}
  3583.      * @return whether the array is sorted
  3584.      * @since 3.4
  3585.      */
  3586.     public static <T extends Comparable<? super T>> boolean isSorted(final T[] array) {
  3587.         return isSorted(array, Comparable::compareTo);
  3588.     }

  3589.     /**
  3590.      * Tests whether the provided array is sorted according to the provided {@link Comparator}.
  3591.      *
  3592.      * @param array the array to check
  3593.      * @param comparator the {@link Comparator} to compare over
  3594.      * @param <T> the datatype of the array
  3595.      * @return whether the array is sorted
  3596.      * @throws NullPointerException if {@code comparator} is {@code null}
  3597.      * @since 3.4
  3598.      */
  3599.     public static <T> boolean isSorted(final T[] array, final Comparator<T> comparator) {
  3600.         Objects.requireNonNull(comparator, "comparator");
  3601.         if (getLength(array) < 2) {
  3602.             return true;
  3603.         }
  3604.         T previous = array[0];
  3605.         final int n = array.length;
  3606.         for (int i = 1; i < n; i++) {
  3607.             final T current = array[i];
  3608.             if (comparator.compare(previous, current) > 0) {
  3609.                 return false;
  3610.             }
  3611.             previous = current;
  3612.         }
  3613.         return true;
  3614.     }

  3615.     /**
  3616.      * Finds the last index of the given value within the array.
  3617.      * <p>
  3618.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) if
  3619.      * {@code null} array input.
  3620.      * </p>
  3621.      *
  3622.      * @param array  the array to traverse backwards looking for the object, may be {@code null}
  3623.      * @param valueToFind  the object to find
  3624.      * @return the last index of the value within the array,
  3625.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  3626.      */
  3627.     public static int lastIndexOf(final boolean[] array, final boolean valueToFind) {
  3628.         return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
  3629.     }

  3630.     /**
  3631.      * Finds the last index of the given value in the array starting at the given index.
  3632.      * <p>
  3633.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  3634.      * </p>
  3635.      * <p>
  3636.      * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than
  3637.      * the array length will search from the end of the array.
  3638.      * </p>
  3639.      *
  3640.      * @param array  the array to traverse for looking for the object, may be {@code null}
  3641.      * @param valueToFind  the value to find
  3642.      * @param startIndex  the start index to traverse backwards from
  3643.      * @return the last index of the value within the array,
  3644.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  3645.      */
  3646.     public static int lastIndexOf(final boolean[] array, final boolean valueToFind, int startIndex) {
  3647.         if (isEmpty(array) || startIndex < 0) {
  3648.             return INDEX_NOT_FOUND;
  3649.         }
  3650.         if (startIndex >= array.length) {
  3651.             startIndex = array.length - 1;
  3652.         }
  3653.         for (int i = startIndex; i >= 0; i--) {
  3654.             if (valueToFind == array[i]) {
  3655.                 return i;
  3656.             }
  3657.         }
  3658.         return INDEX_NOT_FOUND;
  3659.     }

  3660.     /**
  3661.      * Finds the last index of the given value within the array.
  3662.      * <p>
  3663.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  3664.      * </p>
  3665.      *
  3666.      * @param array  the array to traverse backwards looking for the object, may be {@code null}
  3667.      * @param valueToFind  the object to find
  3668.      * @return the last index of the value within the array,
  3669.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  3670.      */
  3671.     public static int lastIndexOf(final byte[] array, final byte valueToFind) {
  3672.         return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
  3673.     }

  3674.     /**
  3675.      * Finds the last index of the given value in the array starting at the given index.
  3676.      * <p>
  3677.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  3678.      * </p>
  3679.      * <p>
  3680.      * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
  3681.      * array length will search from the end of the array.
  3682.      * </p>
  3683.      *
  3684.      * @param array  the array to traverse for looking for the object, may be {@code null}
  3685.      * @param valueToFind  the value to find
  3686.      * @param startIndex  the start index to traverse backwards from
  3687.      * @return the last index of the value within the array,
  3688.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  3689.      */
  3690.     public static int lastIndexOf(final byte[] array, final byte valueToFind, int startIndex) {
  3691.         if (array == null || startIndex < 0) {
  3692.             return INDEX_NOT_FOUND;
  3693.         }
  3694.         if (startIndex >= array.length) {
  3695.             startIndex = array.length - 1;
  3696.         }
  3697.         for (int i = startIndex; i >= 0; i--) {
  3698.             if (valueToFind == array[i]) {
  3699.                 return i;
  3700.             }
  3701.         }
  3702.         return INDEX_NOT_FOUND;
  3703.     }

  3704.     /**
  3705.      * Finds the last index of the given value within the array.
  3706.      * <p>
  3707.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  3708.      * </p>
  3709.      *
  3710.      * @param array  the array to traverse backwards looking for the object, may be {@code null}
  3711.      * @param valueToFind  the object to find
  3712.      * @return the last index of the value within the array,
  3713.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  3714.      * @since 2.1
  3715.      */
  3716.     public static int lastIndexOf(final char[] array, final char valueToFind) {
  3717.         return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
  3718.     }

  3719.     /**
  3720.      * Finds the last index of the given value in the array starting at the given index.
  3721.      * <p>
  3722.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  3723.      * </p>
  3724.      * <p>
  3725.      * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
  3726.      * array length will search from the end of the array.
  3727.      * </p>
  3728.      *
  3729.      * @param array  the array to traverse for looking for the object, may be {@code null}
  3730.      * @param valueToFind  the value to find
  3731.      * @param startIndex  the start index to traverse backwards from
  3732.      * @return the last index of the value within the array,
  3733.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  3734.      * @since 2.1
  3735.      */
  3736.     public static int lastIndexOf(final char[] array, final char valueToFind, int startIndex) {
  3737.         if (array == null || startIndex < 0) {
  3738.             return INDEX_NOT_FOUND;
  3739.         }
  3740.         if (startIndex >= array.length) {
  3741.             startIndex = array.length - 1;
  3742.         }
  3743.         for (int i = startIndex; i >= 0; i--) {
  3744.             if (valueToFind == array[i]) {
  3745.                 return i;
  3746.             }
  3747.         }
  3748.         return INDEX_NOT_FOUND;
  3749.     }

  3750.     /**
  3751.      * Finds the last index of the given value within the array.
  3752.      * <p>
  3753.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  3754.      * </p>
  3755.      *
  3756.      * @param array  the array to traverse backwards looking for the object, may be {@code null}
  3757.      * @param valueToFind  the object to find
  3758.      * @return the last index of the value within the array,
  3759.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  3760.      */
  3761.     public static int lastIndexOf(final double[] array, final double valueToFind) {
  3762.         return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
  3763.     }

  3764.     /**
  3765.      * Finds the last index of the given value within a given tolerance in the array.
  3766.      * This method will return the index of the last value which falls between the region
  3767.      * defined by valueToFind - tolerance and valueToFind + tolerance.
  3768.      * <p>
  3769.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  3770.      * </p>
  3771.      *
  3772.      * @param array  the array to search for the object, may be {@code null}
  3773.      * @param valueToFind  the value to find
  3774.      * @param tolerance tolerance of the search
  3775.      * @return the index of the value within the array,
  3776.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  3777.      */
  3778.     public static int lastIndexOf(final double[] array, final double valueToFind, final double tolerance) {
  3779.         return lastIndexOf(array, valueToFind, Integer.MAX_VALUE, tolerance);
  3780.     }

  3781.     /**
  3782.      * Finds the last index of the given value in the array starting at the given index.
  3783.      * <p>
  3784.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  3785.      * </p>
  3786.      * <p>
  3787.      * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
  3788.      * array length will search from the end of the array.
  3789.      * </p>
  3790.      *
  3791.      * @param array  the array to traverse for looking for the object, may be {@code null}
  3792.      * @param valueToFind  the value to find
  3793.      * @param startIndex  the start index to traverse backwards from
  3794.      * @return the last index of the value within the array,
  3795.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  3796.      */
  3797.     public static int lastIndexOf(final double[] array, final double valueToFind, int startIndex) {
  3798.         if (isEmpty(array) || startIndex < 0) {
  3799.             return INDEX_NOT_FOUND;
  3800.         }
  3801.         if (startIndex >= array.length) {
  3802.             startIndex = array.length - 1;
  3803.         }
  3804.         for (int i = startIndex; i >= 0; i--) {
  3805.             if (valueToFind == array[i]) {
  3806.                 return i;
  3807.             }
  3808.         }
  3809.         return INDEX_NOT_FOUND;
  3810.     }

  3811.     /**
  3812.      * Finds the last index of the given value in the array starting at the given index.
  3813.      * This method will return the index of the last value which falls between the region
  3814.      * defined by valueToFind - tolerance and valueToFind + tolerance.
  3815.      * <p>
  3816.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  3817.      * </p>
  3818.      * <p>
  3819.      * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
  3820.      * array length will search from the end of the array.
  3821.      * </p>
  3822.      *
  3823.      * @param array  the array to traverse for looking for the object, may be {@code null}
  3824.      * @param valueToFind  the value to find
  3825.      * @param startIndex  the start index to traverse backwards from
  3826.      * @param tolerance  search for value within plus/minus this amount
  3827.      * @return the last index of the value within the array,
  3828.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  3829.      */
  3830.     public static int lastIndexOf(final double[] array, final double valueToFind, int startIndex, final double tolerance) {
  3831.         if (isEmpty(array) || startIndex < 0) {
  3832.             return INDEX_NOT_FOUND;
  3833.         }
  3834.         if (startIndex >= array.length) {
  3835.             startIndex = array.length - 1;
  3836.         }
  3837.         final double min = valueToFind - tolerance;
  3838.         final double max = valueToFind + tolerance;
  3839.         for (int i = startIndex; i >= 0; i--) {
  3840.             if (array[i] >= min && array[i] <= max) {
  3841.                 return i;
  3842.             }
  3843.         }
  3844.         return INDEX_NOT_FOUND;
  3845.     }

  3846.     /**
  3847.      * Finds the last index of the given value within the array.
  3848.      * <p>
  3849.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  3850.      * </p>
  3851.      *
  3852.      * @param array  the array to traverse backwards looking for the object, may be {@code null}
  3853.      * @param valueToFind  the object to find
  3854.      * @return the last index of the value within the array,
  3855.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  3856.      */
  3857.     public static int lastIndexOf(final float[] array, final float valueToFind) {
  3858.         return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
  3859.     }

  3860.     /**
  3861.      * Finds the last index of the given value in the array starting at the given index.
  3862.      * <p>
  3863.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  3864.      * </p>
  3865.      * <p>
  3866.      * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
  3867.      * array length will search from the end of the array.
  3868.      * </p>
  3869.      *
  3870.      * @param array  the array to traverse for looking for the object, may be {@code null}
  3871.      * @param valueToFind  the value to find
  3872.      * @param startIndex  the start index to traverse backwards from
  3873.      * @return the last index of the value within the array,
  3874.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  3875.      */
  3876.     public static int lastIndexOf(final float[] array, final float valueToFind, int startIndex) {
  3877.         if (isEmpty(array) || startIndex < 0) {
  3878.             return INDEX_NOT_FOUND;
  3879.         }
  3880.         if (startIndex >= array.length) {
  3881.             startIndex = array.length - 1;
  3882.         }
  3883.         for (int i = startIndex; i >= 0; i--) {
  3884.             if (valueToFind == array[i]) {
  3885.                 return i;
  3886.             }
  3887.         }
  3888.         return INDEX_NOT_FOUND;
  3889.     }

  3890.     /**
  3891.      * Finds the last index of the given value within the array.
  3892.      * <p>
  3893.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  3894.      * </p>
  3895.      *
  3896.      * @param array  the array to traverse backwards looking for the object, may be {@code null}
  3897.      * @param valueToFind  the object to find
  3898.      * @return the last index of the value within the array,
  3899.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  3900.      */
  3901.     public static int lastIndexOf(final int[] array, final int valueToFind) {
  3902.         return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
  3903.     }

  3904.     /**
  3905.      * Finds the last index of the given value in the array starting at the given index.
  3906.      * <p>
  3907.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  3908.      * </p>
  3909.      * <p>
  3910.      * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
  3911.      * array length will search from the end of the array.
  3912.      * </p>
  3913.      *
  3914.      * @param array  the array to traverse for looking for the object, may be {@code null}
  3915.      * @param valueToFind  the value to find
  3916.      * @param startIndex  the start index to traverse backwards from
  3917.      * @return the last index of the value within the array,
  3918.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  3919.      */
  3920.     public static int lastIndexOf(final int[] array, final int valueToFind, int startIndex) {
  3921.         if (array == null || startIndex < 0) {
  3922.             return INDEX_NOT_FOUND;
  3923.         }
  3924.         if (startIndex >= array.length) {
  3925.             startIndex = array.length - 1;
  3926.         }
  3927.         for (int i = startIndex; i >= 0; i--) {
  3928.             if (valueToFind == array[i]) {
  3929.                 return i;
  3930.             }
  3931.         }
  3932.         return INDEX_NOT_FOUND;
  3933.     }

  3934.     /**
  3935.      * Finds the last index of the given value within the array.
  3936.      * <p>
  3937.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  3938.      * </p>
  3939.      *
  3940.      * @param array  the array to traverse backwards looking for the object, may be {@code null}
  3941.      * @param valueToFind  the object to find
  3942.      * @return the last index of the value within the array,
  3943.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  3944.      */
  3945.     public static int lastIndexOf(final long[] array, final long valueToFind) {
  3946.         return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
  3947.     }

  3948.     /**
  3949.      * Finds the last index of the given value in the array starting at the given index.
  3950.      * <p>
  3951.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  3952.      * </p>
  3953.      * <p>
  3954.      * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
  3955.      * array length will search from the end of the array.
  3956.      * </p>
  3957.      *
  3958.      * @param array  the array to traverse for looking for the object, may be {@code null}
  3959.      * @param valueToFind  the value to find
  3960.      * @param startIndex  the start index to traverse backwards from
  3961.      * @return the last index of the value within the array,
  3962.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  3963.      */
  3964.     public static int lastIndexOf(final long[] array, final long valueToFind, int startIndex) {
  3965.         if (array == null || startIndex < 0) {
  3966.             return INDEX_NOT_FOUND;
  3967.         }
  3968.         if (startIndex >= array.length) {
  3969.             startIndex = array.length - 1;
  3970.         }
  3971.         for (int i = startIndex; i >= 0; i--) {
  3972.             if (valueToFind == array[i]) {
  3973.                 return i;
  3974.             }
  3975.         }
  3976.         return INDEX_NOT_FOUND;
  3977.     }

  3978.     /**
  3979.      * Finds the last index of the given object within the array.
  3980.      * <p>
  3981.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  3982.      * </p>
  3983.      *
  3984.      * @param array  the array to traverse backwards looking for the object, may be {@code null}
  3985.      * @param objectToFind  the object to find, may be {@code null}
  3986.      * @return the last index of the object within the array,
  3987.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  3988.      */
  3989.     public static int lastIndexOf(final Object[] array, final Object objectToFind) {
  3990.         return lastIndexOf(array, objectToFind, Integer.MAX_VALUE);
  3991.     }

  3992.     /**
  3993.      * Finds the last index of the given object in the array starting at the given index.
  3994.      * <p>
  3995.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  3996.      * </p>
  3997.      * <p>
  3998.      * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than
  3999.      * the array length will search from the end of the array.
  4000.      * </p>
  4001.      *
  4002.      * @param array  the array to traverse for looking for the object, may be {@code null}
  4003.      * @param objectToFind  the object to find, may be {@code null}
  4004.      * @param startIndex  the start index to traverse backwards from
  4005.      * @return the last index of the object within the array,
  4006.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  4007.      */
  4008.     public static int lastIndexOf(final Object[] array, final Object objectToFind, int startIndex) {
  4009.         if (array == null || startIndex < 0) {
  4010.             return INDEX_NOT_FOUND;
  4011.         }
  4012.         if (startIndex >= array.length) {
  4013.             startIndex = array.length - 1;
  4014.         }
  4015.         if (objectToFind == null) {
  4016.             for (int i = startIndex; i >= 0; i--) {
  4017.                 if (array[i] == null) {
  4018.                     return i;
  4019.                 }
  4020.             }
  4021.         } else if (array.getClass().getComponentType().isInstance(objectToFind)) {
  4022.             for (int i = startIndex; i >= 0; i--) {
  4023.                 if (objectToFind.equals(array[i])) {
  4024.                     return i;
  4025.                 }
  4026.             }
  4027.         }
  4028.         return INDEX_NOT_FOUND;
  4029.     }

  4030.     /**
  4031.      * Finds the last index of the given value within the array.
  4032.      * <p>
  4033.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  4034.      * </p>
  4035.      *
  4036.      * @param array  the array to traverse backwards looking for the object, may be {@code null}
  4037.      * @param valueToFind  the object to find
  4038.      * @return the last index of the value within the array,
  4039.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  4040.      */
  4041.     public static int lastIndexOf(final short[] array, final short valueToFind) {
  4042.         return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
  4043.     }

  4044.     /**
  4045.      * Finds the last index of the given value in the array starting at the given index.
  4046.      * <p>
  4047.      * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
  4048.      * </p>
  4049.      * <p>
  4050.      * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
  4051.      * array length will search from the end of the array.
  4052.      * </p>
  4053.      *
  4054.      * @param array  the array to traverse for looking for the object, may be {@code null}
  4055.      * @param valueToFind  the value to find
  4056.      * @param startIndex  the start index to traverse backwards from
  4057.      * @return the last index of the value within the array,
  4058.      *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
  4059.      */
  4060.     public static int lastIndexOf(final short[] array, final short valueToFind, int startIndex) {
  4061.         if (array == null || startIndex < 0) {
  4062.             return INDEX_NOT_FOUND;
  4063.         }
  4064.         if (startIndex >= array.length) {
  4065.             startIndex = array.length - 1;
  4066.         }
  4067.         for (int i = startIndex; i >= 0; i--) {
  4068.             if (valueToFind == array[i]) {
  4069.                 return i;
  4070.             }
  4071.         }
  4072.         return INDEX_NOT_FOUND;
  4073.     }

  4074.     /**
  4075.      * Maps elements from an array into elements of a new array of a given type, while mapping old elements to new elements.
  4076.      *
  4077.      * @param <T>           The input array type.
  4078.      * @param <R>           The output array type.
  4079.      * @param <E>           The type of exceptions thrown when the mapper function fails.
  4080.      * @param array         The input array.
  4081.      * @param componentType the component type of the result array.
  4082.      * @param mapper        a non-interfering, stateless function to apply to each element
  4083.      * @return a new array
  4084.      * @throws E Thrown when the mapper function fails.
  4085.      */
  4086.     private static <T, R, E extends Throwable> R[] map(final T[] array, final Class<R> componentType, final FailableFunction<? super T, ? extends R, E> mapper)
  4087.             throws E {
  4088.         return ArrayFill.fill(newInstance(componentType, array.length), i -> mapper.apply(array[i]));
  4089.     }

  4090.     private static int max0(final int other) {
  4091.         return Math.max(0, other);
  4092.     }

  4093.     /**
  4094.      * Delegates to {@link Array#newInstance(Class,int)} using generics.
  4095.      *
  4096.      * @param <T> The array type.
  4097.      * @param componentType The array class.
  4098.      * @param length the array length
  4099.      * @return The new array.
  4100.      * @throws NullPointerException if the specified {@code componentType} parameter is null.
  4101.      * @since 3.13.0
  4102.      */
  4103.     @SuppressWarnings("unchecked") // OK, because array and values are of type T
  4104.     public static <T> T[] newInstance(final Class<T> componentType, final int length) {
  4105.         return (T[]) Array.newInstance(componentType, length);
  4106.     }

  4107.     /**
  4108.      * Defensive programming technique to change a {@code null}
  4109.      * reference to an empty one.
  4110.      * <p>
  4111.      * This method returns a default array for a {@code null} input array.
  4112.      * </p>
  4113.      * <p>
  4114.      * As a memory optimizing technique an empty array passed in will be overridden with
  4115.      * the empty {@code public static} references in this class.
  4116.      * </p>
  4117.      *
  4118.      * @param <T> The array type.
  4119.      * @param array  the array to check for {@code null} or empty
  4120.      * @param defaultArray A default array, usually empty.
  4121.      * @return the same array, or defaultArray if {@code null} or empty input.
  4122.      * @since 3.15.0
  4123.      */
  4124.     public static <T> T[] nullTo(final T[] array, final T[] defaultArray) {
  4125.         return isEmpty(array) ? defaultArray : array;
  4126.     }

  4127.     /**
  4128.      * Defensive programming technique to change a {@code null}
  4129.      * reference to an empty one.
  4130.      * <p>
  4131.      * This method returns an empty array for a {@code null} input array.
  4132.      * </p>
  4133.      * <p>
  4134.      * As a memory optimizing technique an empty array passed in will be overridden with
  4135.      * the empty {@code public static} references in this class.
  4136.      * </p>
  4137.      *
  4138.      * @param array  the array to check for {@code null} or empty
  4139.      * @return the same array, {@code public static} empty array if {@code null} or empty input
  4140.      * @since 2.5
  4141.      */
  4142.     public static boolean[] nullToEmpty(final boolean[] array) {
  4143.         return isEmpty(array) ? EMPTY_BOOLEAN_ARRAY : array;
  4144.     }

  4145.     /**
  4146.      * Defensive programming technique to change a {@code null}
  4147.      * reference to an empty one.
  4148.      * <p>
  4149.      * This method returns an empty array for a {@code null} input array.
  4150.      * </p>
  4151.      * <p>
  4152.      * As a memory optimizing technique an empty array passed in will be overridden with
  4153.      * the empty {@code public static} references in this class.
  4154.      * </p>
  4155.      *
  4156.      * @param array  the array to check for {@code null} or empty
  4157.      * @return the same array, {@code public static} empty array if {@code null} or empty input
  4158.      * @since 2.5
  4159.      */
  4160.     public static Boolean[] nullToEmpty(final Boolean[] array) {
  4161.         return nullTo(array, EMPTY_BOOLEAN_OBJECT_ARRAY);
  4162.     }

  4163.     /**
  4164.      * Defensive programming technique to change a {@code null}
  4165.      * reference to an empty one.
  4166.      * <p>
  4167.      * This method returns an empty array for a {@code null} input array.
  4168.      * </p>
  4169.      * <p>
  4170.      * As a memory optimizing technique an empty array passed in will be overridden with
  4171.      * the empty {@code public static} references in this class.
  4172.      * </p>
  4173.      *
  4174.      * @param array  the array to check for {@code null} or empty
  4175.      * @return the same array, {@code public static} empty array if {@code null} or empty input
  4176.      * @since 2.5
  4177.      */
  4178.     public static byte[] nullToEmpty(final byte[] array) {
  4179.         return isEmpty(array) ? EMPTY_BYTE_ARRAY : array;
  4180.     }

  4181.     /**
  4182.      * Defensive programming technique to change a {@code null}
  4183.      * reference to an empty one.
  4184.      * <p>
  4185.      * This method returns an empty array for a {@code null} input array.
  4186.      * </p>
  4187.      * <p>
  4188.      * As a memory optimizing technique an empty array passed in will be overridden with
  4189.      * the empty {@code public static} references in this class.
  4190.      * </p>
  4191.      *
  4192.      * @param array  the array to check for {@code null} or empty
  4193.      * @return the same array, {@code public static} empty array if {@code null} or empty input
  4194.      * @since 2.5
  4195.      */
  4196.     public static Byte[] nullToEmpty(final Byte[] array) {
  4197.         return nullTo(array, EMPTY_BYTE_OBJECT_ARRAY);
  4198.     }

  4199.     /**
  4200.      * Defensive programming technique to change a {@code null}
  4201.      * reference to an empty one.
  4202.      * <p>
  4203.      * This method returns an empty array for a {@code null} input array.
  4204.      * </p>
  4205.      * <p>
  4206.      * As a memory optimizing technique an empty array passed in will be overridden with
  4207.      * the empty {@code public static} references in this class.
  4208.      * </p>
  4209.      *
  4210.      * @param array  the array to check for {@code null} or empty
  4211.      * @return the same array, {@code public static} empty array if {@code null} or empty input
  4212.      * @since 2.5
  4213.      */
  4214.     public static char[] nullToEmpty(final char[] array) {
  4215.         return isEmpty(array) ? EMPTY_CHAR_ARRAY : array;
  4216.     }

  4217.     /**
  4218.      * Defensive programming technique to change a {@code null}
  4219.      * reference to an empty one.
  4220.      * <p>
  4221.      * This method returns an empty array for a {@code null} input array.
  4222.      * </p>
  4223.      * <p>
  4224.      * As a memory optimizing technique an empty array passed in will be overridden with
  4225.      * the empty {@code public static} references in this class.
  4226.      * </p>
  4227.      *
  4228.      * @param array  the array to check for {@code null} or empty
  4229.      * @return the same array, {@code public static} empty array if {@code null} or empty input
  4230.      * @since 2.5
  4231.      */
  4232.     public static Character[] nullToEmpty(final Character[] array) {
  4233.         return nullTo(array, EMPTY_CHARACTER_OBJECT_ARRAY);
  4234.     }

  4235.     /**
  4236.      * Defensive programming technique to change a {@code null}
  4237.      * reference to an empty one.
  4238.      * <p>
  4239.      * This method returns an empty array for a {@code null} input array.
  4240.      * </p>
  4241.      * <p>
  4242.      * As a memory optimizing technique an empty array passed in will be overridden with
  4243.      * the empty {@code public static} references in this class.
  4244.      * </p>
  4245.      *
  4246.      * @param array  the array to check for {@code null} or empty
  4247.      * @return the same array, {@code public static} empty array if {@code null} or empty input
  4248.      * @since 3.2
  4249.      */
  4250.     public static Class<?>[] nullToEmpty(final Class<?>[] array) {
  4251.         return nullTo(array, EMPTY_CLASS_ARRAY);
  4252.     }

  4253.     /**
  4254.      * Defensive programming technique to change a {@code null}
  4255.      * reference to an empty one.
  4256.      * <p>
  4257.      * This method returns an empty array for a {@code null} input array.
  4258.      * </p>
  4259.      * <p>
  4260.      * As a memory optimizing technique an empty array passed in will be overridden with
  4261.      * the empty {@code public static} references in this class.
  4262.      * </p>
  4263.      *
  4264.      * @param array  the array to check for {@code null} or empty
  4265.      * @return the same array, {@code public static} empty array if {@code null} or empty input
  4266.      * @since 2.5
  4267.      */
  4268.     public static double[] nullToEmpty(final double[] array) {
  4269.         return isEmpty(array) ? EMPTY_DOUBLE_ARRAY : array;
  4270.     }

  4271.     /**
  4272.      * Defensive programming technique to change a {@code null}
  4273.      * reference to an empty one.
  4274.      * <p>
  4275.      * This method returns an empty array for a {@code null} input array.
  4276.      * </p>
  4277.      * <p>
  4278.      * As a memory optimizing technique an empty array passed in will be overridden with
  4279.      * the empty {@code public static} references in this class.
  4280.      * </p>
  4281.      *
  4282.      * @param array  the array to check for {@code null} or empty
  4283.      * @return the same array, {@code public static} empty array if {@code null} or empty input
  4284.      * @since 2.5
  4285.      */
  4286.     public static Double[] nullToEmpty(final Double[] array) {
  4287.         return nullTo(array, EMPTY_DOUBLE_OBJECT_ARRAY);
  4288.     }

  4289.     /**
  4290.      * Defensive programming technique to change a {@code null}
  4291.      * reference to an empty one.
  4292.      * <p>
  4293.      * This method returns an empty array for a {@code null} input array.
  4294.      * </p>
  4295.      * <p>
  4296.      * As a memory optimizing technique an empty array passed in will be overridden with
  4297.      * the empty {@code public static} references in this class.
  4298.      * </p>
  4299.      *
  4300.      * @param array  the array to check for {@code null} or empty
  4301.      * @return the same array, {@code public static} empty array if {@code null} or empty input
  4302.      * @since 2.5
  4303.      */
  4304.     public static float[] nullToEmpty(final float[] array) {
  4305.         return isEmpty(array) ? EMPTY_FLOAT_ARRAY : array;
  4306.     }

  4307.     /**
  4308.      * Defensive programming technique to change a {@code null}
  4309.      * reference to an empty one.
  4310.      * <p>
  4311.      * This method returns an empty array for a {@code null} input array.
  4312.      * </p>
  4313.      * <p>
  4314.      * As a memory optimizing technique an empty array passed in will be overridden with
  4315.      * the empty {@code public static} references in this class.
  4316.      * </p>
  4317.      *
  4318.      * @param array  the array to check for {@code null} or empty
  4319.      * @return the same array, {@code public static} empty array if {@code null} or empty input
  4320.      * @since 2.5
  4321.      */
  4322.     public static Float[] nullToEmpty(final Float[] array) {
  4323.         return nullTo(array, EMPTY_FLOAT_OBJECT_ARRAY);
  4324.     }

  4325.     /**
  4326.      * Defensive programming technique to change a {@code null}
  4327.      * reference to an empty one.
  4328.      * <p>
  4329.      * This method returns an empty array for a {@code null} input array.
  4330.      * </p>
  4331.      * <p>
  4332.      * As a memory optimizing technique an empty array passed in will be overridden with
  4333.      * the empty {@code public static} references in this class.
  4334.      * </p>
  4335.      *
  4336.      * @param array  the array to check for {@code null} or empty
  4337.      * @return the same array, {@code public static} empty array if {@code null} or empty input
  4338.      * @since 2.5
  4339.      */
  4340.     public static int[] nullToEmpty(final int[] array) {
  4341.         return isEmpty(array) ? EMPTY_INT_ARRAY : array;
  4342.     }

  4343.     /**
  4344.      * Defensive programming technique to change a {@code null}
  4345.      * reference to an empty one.
  4346.      * <p>
  4347.      * This method returns an empty array for a {@code null} input array.
  4348.      * </p>
  4349.      * <p>
  4350.      * As a memory optimizing technique an empty array passed in will be overridden with
  4351.      * the empty {@code public static} references in this class.
  4352.      * </p>
  4353.      *
  4354.      * @param array  the array to check for {@code null} or empty
  4355.      * @return the same array, {@code public static} empty array if {@code null} or empty input
  4356.      * @since 2.5
  4357.      */
  4358.     public static Integer[] nullToEmpty(final Integer[] array) {
  4359.         return nullTo(array, EMPTY_INTEGER_OBJECT_ARRAY);
  4360.     }

  4361.     /**
  4362.      * Defensive programming technique to change a {@code null}
  4363.      * reference to an empty one.
  4364.      * <p>
  4365.      * This method returns an empty array for a {@code null} input array.
  4366.      * </p>
  4367.      * <p>
  4368.      * As a memory optimizing technique an empty array passed in will be overridden with
  4369.      * the empty {@code public static} references in this class.
  4370.      * </p>
  4371.      *
  4372.      * @param array  the array to check for {@code null} or empty
  4373.      * @return the same array, {@code public static} empty array if {@code null} or empty input
  4374.      * @since 2.5
  4375.      */
  4376.     public static long[] nullToEmpty(final long[] array) {
  4377.         return isEmpty(array) ? EMPTY_LONG_ARRAY : array;
  4378.     }

  4379.     /**
  4380.      * Defensive programming technique to change a {@code null}
  4381.      * reference to an empty one.
  4382.      * <p>
  4383.      * This method returns an empty array for a {@code null} input array.
  4384.      * </p>
  4385.      * <p>
  4386.      * As a memory optimizing technique an empty array passed in will be overridden with
  4387.      * the empty {@code public static} references in this class.
  4388.      * </p>
  4389.      *
  4390.      * @param array  the array to check for {@code null} or empty
  4391.      * @return the same array, {@code public static} empty array if {@code null} or empty input
  4392.      * @since 2.5
  4393.      */
  4394.     public static Long[] nullToEmpty(final Long[] array) {
  4395.         return nullTo(array, EMPTY_LONG_OBJECT_ARRAY);
  4396.     }

  4397.     /**
  4398.      * Defensive programming technique to change a {@code null}
  4399.      * reference to an empty one.
  4400.      * <p>
  4401.      * This method returns an empty array for a {@code null} input array.
  4402.      * </p>
  4403.      * <p>
  4404.      * As a memory optimizing technique an empty array passed in will be overridden with
  4405.      * the empty {@code public static} references in this class.
  4406.      * </p>
  4407.      *
  4408.      * @param array  the array to check for {@code null} or empty
  4409.      * @return the same array, {@code public static} empty array if {@code null} or empty input
  4410.      * @since 2.5
  4411.      */
  4412.     public static Object[] nullToEmpty(final Object[] array) {
  4413.         return nullTo(array, EMPTY_OBJECT_ARRAY);
  4414.     }

  4415.     /**
  4416.      * Defensive programming technique to change a {@code null}
  4417.      * reference to an empty one.
  4418.      * <p>
  4419.      * This method returns an empty array for a {@code null} input array.
  4420.      * </p>
  4421.      * <p>
  4422.      * As a memory optimizing technique an empty array passed in will be overridden with
  4423.      * the empty {@code public static} references in this class.
  4424.      * </p>
  4425.      *
  4426.      * @param array  the array to check for {@code null} or empty
  4427.      * @return the same array, {@code public static} empty array if {@code null} or empty input
  4428.      * @since 2.5
  4429.      */
  4430.     public static short[] nullToEmpty(final short[] array) {
  4431.         return isEmpty(array) ? EMPTY_SHORT_ARRAY : array;
  4432.     }

  4433.     /**
  4434.      * Defensive programming technique to change a {@code null}
  4435.      * reference to an empty one.
  4436.      * <p>
  4437.      * This method returns an empty array for a {@code null} input array.
  4438.      * </p>
  4439.      * <p>
  4440.      * As a memory optimizing technique an empty array passed in will be overridden with
  4441.      * the empty {@code public static} references in this class.
  4442.      * </p>
  4443.      *
  4444.      * @param array  the array to check for {@code null} or empty
  4445.      * @return the same array, {@code public static} empty array if {@code null} or empty input
  4446.      * @since 2.5
  4447.      */
  4448.     public static Short[] nullToEmpty(final Short[] array) {
  4449.         return nullTo(array, EMPTY_SHORT_OBJECT_ARRAY);
  4450.     }

  4451.     /**
  4452.      * Defensive programming technique to change a {@code null}
  4453.      * reference to an empty one.
  4454.      * <p>
  4455.      * This method returns an empty array for a {@code null} input array.
  4456.      * </p>
  4457.      * <p>
  4458.      * As a memory optimizing technique an empty array passed in will be overridden with
  4459.      * the empty {@code public static} references in this class.
  4460.      * </p>
  4461.      *
  4462.      * @param array  the array to check for {@code null} or empty
  4463.      * @return the same array, {@code public static} empty array if {@code null} or empty input
  4464.      * @since 2.5
  4465.      */
  4466.     public static String[] nullToEmpty(final String[] array) {
  4467.         return nullTo(array, EMPTY_STRING_ARRAY);
  4468.     }

  4469.     /**
  4470.      * Defensive programming technique to change a {@code null}
  4471.      * reference to an empty one.
  4472.      * <p>
  4473.      * This method returns an empty array for a {@code null} input array.
  4474.      * </p>
  4475.      *
  4476.      * @param array  the array to check for {@code null} or empty
  4477.      * @param type   the class representation of the desired array
  4478.      * @param <T>  the class type
  4479.      * @return the same array, {@code public static} empty array if {@code null}
  4480.      * @throws IllegalArgumentException if the type argument is null
  4481.      * @since 3.5
  4482.      */
  4483.     public static <T> T[] nullToEmpty(final T[] array, final Class<T[]> type) {
  4484.         if (type == null) {
  4485.             throw new IllegalArgumentException("The type must not be null");
  4486.         }
  4487.         if (array == null) {
  4488.             return type.cast(Array.newInstance(type.getComponentType(), 0));
  4489.         }
  4490.         return array;
  4491.     }

  4492.     /**
  4493.      * Gets the {@link ThreadLocalRandom} for {@code shuffle} methods that don't take a {@link Random} argument.
  4494.      *
  4495.      * @return the current ThreadLocalRandom.
  4496.      */
  4497.     private static ThreadLocalRandom random() {
  4498.         return ThreadLocalRandom.current();
  4499.     }

  4500.     /**
  4501.      * Removes the element at the specified position from the specified array.
  4502.      * All subsequent elements are shifted to the left (subtracts one from
  4503.      * their indices).
  4504.      * <p>
  4505.      * This method returns a new array with the same elements of the input
  4506.      * array except the element on the specified position. The component
  4507.      * type of the returned array is always the same as that of the input
  4508.      * array.
  4509.      * </p>
  4510.      * <p>
  4511.      * If the input array is {@code null}, an IndexOutOfBoundsException
  4512.      * will be thrown, because in that case no valid index can be specified.
  4513.      * </p>
  4514.      * <pre>
  4515.      * ArrayUtils.remove([true], 0)              = []
  4516.      * ArrayUtils.remove([true, false], 0)       = [false]
  4517.      * ArrayUtils.remove([true, false], 1)       = [true]
  4518.      * ArrayUtils.remove([true, true, false], 1) = [true, false]
  4519.      * </pre>
  4520.      *
  4521.      * @param array  the array to remove the element from, may not be {@code null}
  4522.      * @param index  the position of the element to be removed
  4523.      * @return A new array containing the existing elements except the element
  4524.      *         at the specified position.
  4525.      * @throws IndexOutOfBoundsException if the index is out of range
  4526.      * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
  4527.      * @since 2.1
  4528.      */
  4529.     public static boolean[] remove(final boolean[] array, final int index) {
  4530.         return (boolean[]) remove((Object) array, index);
  4531.     }

  4532.     /**
  4533.      * Removes the element at the specified position from the specified array.
  4534.      * All subsequent elements are shifted to the left (subtracts one from
  4535.      * their indices).
  4536.      * <p>
  4537.      * This method returns a new array with the same elements of the input
  4538.      * array except the element on the specified position. The component
  4539.      * type of the returned array is always the same as that of the input
  4540.      * array.
  4541.      * </p>
  4542.      * <p>
  4543.      * If the input array is {@code null}, an IndexOutOfBoundsException
  4544.      * will be thrown, because in that case no valid index can be specified.
  4545.      * </p>
  4546.      * <pre>
  4547.      * ArrayUtils.remove([1], 0)          = []
  4548.      * ArrayUtils.remove([1, 0], 0)       = [0]
  4549.      * ArrayUtils.remove([1, 0], 1)       = [1]
  4550.      * ArrayUtils.remove([1, 0, 1], 1)    = [1, 1]
  4551.      * </pre>
  4552.      *
  4553.      * @param array  the array to remove the element from, may not be {@code null}
  4554.      * @param index  the position of the element to be removed
  4555.      * @return A new array containing the existing elements except the element
  4556.      *         at the specified position.
  4557.      * @throws IndexOutOfBoundsException if the index is out of range
  4558.      * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
  4559.      * @since 2.1
  4560.      */
  4561.     public static byte[] remove(final byte[] array, final int index) {
  4562.         return (byte[]) remove((Object) array, index);
  4563.     }

  4564.     /**
  4565.      * Removes the element at the specified position from the specified array.
  4566.      * All subsequent elements are shifted to the left (subtracts one from
  4567.      * their indices).
  4568.      * <p>
  4569.      * This method returns a new array with the same elements of the input
  4570.      * array except the element on the specified position. The component
  4571.      * type of the returned array is always the same as that of the input
  4572.      * array.
  4573.      * </p>
  4574.      * <p>
  4575.      * If the input array is {@code null}, an IndexOutOfBoundsException
  4576.      * will be thrown, because in that case no valid index can be specified.
  4577.      * </p>
  4578.      * <pre>
  4579.      * ArrayUtils.remove(['a'], 0)           = []
  4580.      * ArrayUtils.remove(['a', 'b'], 0)      = ['b']
  4581.      * ArrayUtils.remove(['a', 'b'], 1)      = ['a']
  4582.      * ArrayUtils.remove(['a', 'b', 'c'], 1) = ['a', 'c']
  4583.      * </pre>
  4584.      *
  4585.      * @param array  the array to remove the element from, may not be {@code null}
  4586.      * @param index  the position of the element to be removed
  4587.      * @return A new array containing the existing elements except the element
  4588.      *         at the specified position.
  4589.      * @throws IndexOutOfBoundsException if the index is out of range
  4590.      * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
  4591.      * @since 2.1
  4592.      */
  4593.     public static char[] remove(final char[] array, final int index) {
  4594.         return (char[]) remove((Object) array, index);
  4595.     }

  4596.     /**
  4597.      * Removes the element at the specified position from the specified array.
  4598.      * All subsequent elements are shifted to the left (subtracts one from
  4599.      * their indices).
  4600.      * <p>
  4601.      * This method returns a new array with the same elements of the input
  4602.      * array except the element on the specified position. The component
  4603.      * type of the returned array is always the same as that of the input
  4604.      * array.
  4605.      * </p>
  4606.      * <p>
  4607.      * If the input array is {@code null}, an IndexOutOfBoundsException
  4608.      * will be thrown, because in that case no valid index can be specified.
  4609.      * </p>
  4610.      * <pre>
  4611.      * ArrayUtils.remove([1.1], 0)           = []
  4612.      * ArrayUtils.remove([2.5, 6.0], 0)      = [6.0]
  4613.      * ArrayUtils.remove([2.5, 6.0], 1)      = [2.5]
  4614.      * ArrayUtils.remove([2.5, 6.0, 3.8], 1) = [2.5, 3.8]
  4615.      * </pre>
  4616.      *
  4617.      * @param array  the array to remove the element from, may not be {@code null}
  4618.      * @param index  the position of the element to be removed
  4619.      * @return A new array containing the existing elements except the element
  4620.      *         at the specified position.
  4621.      * @throws IndexOutOfBoundsException if the index is out of range
  4622.      * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
  4623.      * @since 2.1
  4624.      */
  4625.     public static double[] remove(final double[] array, final int index) {
  4626.         return (double[]) remove((Object) array, index);
  4627.     }

  4628.     /**
  4629.      * Removes the element at the specified position from the specified array.
  4630.      * All subsequent elements are shifted to the left (subtracts one from
  4631.      * their indices).
  4632.      * <p>
  4633.      * This method returns a new array with the same elements of the input
  4634.      * array except the element on the specified position. The component
  4635.      * type of the returned array is always the same as that of the input
  4636.      * array.
  4637.      * </p>
  4638.      * <p>
  4639.      * If the input array is {@code null}, an IndexOutOfBoundsException
  4640.      * will be thrown, because in that case no valid index can be specified.
  4641.      * </p>
  4642.      * <pre>
  4643.      * ArrayUtils.remove([1.1], 0)           = []
  4644.      * ArrayUtils.remove([2.5, 6.0], 0)      = [6.0]
  4645.      * ArrayUtils.remove([2.5, 6.0], 1)      = [2.5]
  4646.      * ArrayUtils.remove([2.5, 6.0, 3.8], 1) = [2.5, 3.8]
  4647.      * </pre>
  4648.      *
  4649.      * @param array  the array to remove the element from, may not be {@code null}
  4650.      * @param index  the position of the element to be removed
  4651.      * @return A new array containing the existing elements except the element
  4652.      *         at the specified position.
  4653.      * @throws IndexOutOfBoundsException if the index is out of range
  4654.      * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
  4655.      * @since 2.1
  4656.      */
  4657.     public static float[] remove(final float[] array, final int index) {
  4658.         return (float[]) remove((Object) array, index);
  4659.     }

  4660.     /**
  4661.      * Removes the element at the specified position from the specified array.
  4662.      * All subsequent elements are shifted to the left (subtracts one from
  4663.      * their indices).
  4664.      * <p>
  4665.      * This method returns a new array with the same elements of the input
  4666.      * array except the element on the specified position. The component
  4667.      * type of the returned array is always the same as that of the input
  4668.      * array.
  4669.      * </p>
  4670.      * <p>
  4671.      * If the input array is {@code null}, an IndexOutOfBoundsException
  4672.      * will be thrown, because in that case no valid index can be specified.
  4673.      * </p>
  4674.      * <pre>
  4675.      * ArrayUtils.remove([1], 0)         = []
  4676.      * ArrayUtils.remove([2, 6], 0)      = [6]
  4677.      * ArrayUtils.remove([2, 6], 1)      = [2]
  4678.      * ArrayUtils.remove([2, 6, 3], 1)   = [2, 3]
  4679.      * </pre>
  4680.      *
  4681.      * @param array  the array to remove the element from, may not be {@code null}
  4682.      * @param index  the position of the element to be removed
  4683.      * @return A new array containing the existing elements except the element
  4684.      *         at the specified position.
  4685.      * @throws IndexOutOfBoundsException if the index is out of range
  4686.      * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
  4687.      * @since 2.1
  4688.      */
  4689.     public static int[] remove(final int[] array, final int index) {
  4690.         return (int[]) remove((Object) array, index);
  4691.     }

  4692.     /**
  4693.      * Removes the element at the specified position from the specified array.
  4694.      * All subsequent elements are shifted to the left (subtracts one from
  4695.      * their indices).
  4696.      * <p>
  4697.      * This method returns a new array with the same elements of the input
  4698.      * array except the element on the specified position. The component
  4699.      * type of the returned array is always the same as that of the input
  4700.      * array.
  4701.      * </p>
  4702.      * <p>
  4703.      * If the input array is {@code null}, an IndexOutOfBoundsException
  4704.      * will be thrown, because in that case no valid index can be specified.
  4705.      * </p>
  4706.      * <pre>
  4707.      * ArrayUtils.remove([1], 0)         = []
  4708.      * ArrayUtils.remove([2, 6], 0)      = [6]
  4709.      * ArrayUtils.remove([2, 6], 1)      = [2]
  4710.      * ArrayUtils.remove([2, 6, 3], 1)   = [2, 3]
  4711.      * </pre>
  4712.      *
  4713.      * @param array  the array to remove the element from, may not be {@code null}
  4714.      * @param index  the position of the element to be removed
  4715.      * @return A new array containing the existing elements except the element
  4716.      *         at the specified position.
  4717.      * @throws IndexOutOfBoundsException if the index is out of range
  4718.      * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
  4719.      * @since 2.1
  4720.      */
  4721.     public static long[] remove(final long[] array, final int index) {
  4722.         return (long[]) remove((Object) array, index);
  4723.     }

  4724.     /**
  4725.      * Removes the element at the specified position from the specified array.
  4726.      * All subsequent elements are shifted to the left (subtracts one from
  4727.      * their indices).
  4728.      * <p>
  4729.      * This method returns a new array with the same elements of the input
  4730.      * array except the element on the specified position. The component
  4731.      * type of the returned array is always the same as that of the input
  4732.      * array.
  4733.      * </p>
  4734.      * <p>
  4735.      * If the input array is {@code null}, an IndexOutOfBoundsException
  4736.      * will be thrown, because in that case no valid index can be specified.
  4737.      * </p>
  4738.      *
  4739.      * @param array  the array to remove the element from, may not be {@code null}
  4740.      * @param index  the position of the element to be removed
  4741.      * @return A new array containing the existing elements except the element
  4742.      *         at the specified position.
  4743.      * @throws IndexOutOfBoundsException if the index is out of range
  4744.      * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
  4745.      * @since 2.1
  4746.      */
  4747.     private static Object remove(final Object array, final int index) {
  4748.         final int length = getLength(array);
  4749.         if (index < 0 || index >= length) {
  4750.             throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
  4751.         }
  4752.         final Object result = Array.newInstance(array.getClass().getComponentType(), length - 1);
  4753.         System.arraycopy(array, 0, result, 0, index);
  4754.         if (index < length - 1) {
  4755.             System.arraycopy(array, index + 1, result, index, length - index - 1);
  4756.         }
  4757.         return result;
  4758.     }

  4759.     /**
  4760.      * Removes the element at the specified position from the specified array.
  4761.      * All subsequent elements are shifted to the left (subtracts one from
  4762.      * their indices).
  4763.      * <p>
  4764.      * This method returns a new array with the same elements of the input
  4765.      * array except the element on the specified position. The component
  4766.      * type of the returned array is always the same as that of the input
  4767.      * array.
  4768.      * </p>
  4769.      * <p>
  4770.      * If the input array is {@code null}, an IndexOutOfBoundsException
  4771.      * will be thrown, because in that case no valid index can be specified.
  4772.      * </p>
  4773.      * <pre>
  4774.      * ArrayUtils.remove([1], 0)         = []
  4775.      * ArrayUtils.remove([2, 6], 0)      = [6]
  4776.      * ArrayUtils.remove([2, 6], 1)      = [2]
  4777.      * ArrayUtils.remove([2, 6, 3], 1)   = [2, 3]
  4778.      * </pre>
  4779.      *
  4780.      * @param array  the array to remove the element from, may not be {@code null}
  4781.      * @param index  the position of the element to be removed
  4782.      * @return A new array containing the existing elements except the element
  4783.      *         at the specified position.
  4784.      * @throws IndexOutOfBoundsException if the index is out of range
  4785.      * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
  4786.      * @since 2.1
  4787.      */
  4788.     public static short[] remove(final short[] array, final int index) {
  4789.         return (short[]) remove((Object) array, index);
  4790.     }

  4791.     /**
  4792.      * Removes the element at the specified position from the specified array.
  4793.      * All subsequent elements are shifted to the left (subtracts one from
  4794.      * their indices).
  4795.      * <p>
  4796.      * This method returns a new array with the same elements of the input
  4797.      * array except the element on the specified position. The component
  4798.      * type of the returned array is always the same as that of the input
  4799.      * array.
  4800.      * </p>
  4801.      * <p>
  4802.      * If the input array is {@code null}, an IndexOutOfBoundsException
  4803.      * will be thrown, because in that case no valid index can be specified.
  4804.      * </p>
  4805.      * <pre>
  4806.      * ArrayUtils.remove(["a"], 0)           = []
  4807.      * ArrayUtils.remove(["a", "b"], 0)      = ["b"]
  4808.      * ArrayUtils.remove(["a", "b"], 1)      = ["a"]
  4809.      * ArrayUtils.remove(["a", "b", "c"], 1) = ["a", "c"]
  4810.      * </pre>
  4811.      *
  4812.      * @param <T> the component type of the array
  4813.      * @param array  the array to remove the element from, may not be {@code null}
  4814.      * @param index  the position of the element to be removed
  4815.      * @return A new array containing the existing elements except the element
  4816.      *         at the specified position.
  4817.      * @throws IndexOutOfBoundsException if the index is out of range
  4818.      * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
  4819.      * @since 2.1
  4820.      */
  4821.     @SuppressWarnings("unchecked") // remove() always creates an array of the same type as its input
  4822.     public static <T> T[] remove(final T[] array, final int index) {
  4823.         return (T[]) remove((Object) array, index);
  4824.     }

  4825.     /**
  4826.      * Removes the elements at the specified positions from the specified array.
  4827.      * All remaining elements are shifted to the left.
  4828.      * <p>
  4829.      * This method returns a new array with the same elements of the input
  4830.      * array except those at the specified positions. The component
  4831.      * type of the returned array is always the same as that of the input
  4832.      * array.
  4833.      * </p>
  4834.      * <p>
  4835.      * If the input array is {@code null}, an IndexOutOfBoundsException
  4836.      * will be thrown, because in that case no valid index can be specified.
  4837.      * </p>
  4838.      * <pre>
  4839.      * ArrayUtils.removeAll([true, false, true], 0, 2) = [false]
  4840.      * ArrayUtils.removeAll([true, false, true], 1, 2) = [true]
  4841.      * </pre>
  4842.      *
  4843.      * @param array   the array to remove the element from, may not be {@code null}
  4844.      * @param indices the positions of the elements to be removed
  4845.      * @return A new array containing the existing elements except those
  4846.      *         at the specified positions.
  4847.      * @throws IndexOutOfBoundsException if any index is out of range
  4848.      * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
  4849.      * @since 3.0.1
  4850.      */
  4851.     public static boolean[] removeAll(final boolean[] array, final int... indices) {
  4852.         return (boolean[]) removeAll((Object) array, indices);
  4853.     }

  4854.     /**
  4855.      * Removes the elements at the specified positions from the specified array.
  4856.      * All remaining elements are shifted to the left.
  4857.      * <p>
  4858.      * This method returns a new array with the same elements of the input
  4859.      * array except those at the specified positions. The component
  4860.      * type of the returned array is always the same as that of the input
  4861.      * array.
  4862.      * </p>
  4863.      * <p>
  4864.      * If the input array is {@code null}, an IndexOutOfBoundsException
  4865.      * will be thrown, because in that case no valid index can be specified.
  4866.      * </p>
  4867.      * <pre>
  4868.      * ArrayUtils.removeAll([1], 0)             = []
  4869.      * ArrayUtils.removeAll([2, 6], 0)          = [6]
  4870.      * ArrayUtils.removeAll([2, 6], 0, 1)       = []
  4871.      * ArrayUtils.removeAll([2, 6, 3], 1, 2)    = [2]
  4872.      * ArrayUtils.removeAll([2, 6, 3], 0, 2)    = [6]
  4873.      * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
  4874.      * </pre>
  4875.      *
  4876.      * @param array   the array to remove the element from, may not be {@code null}
  4877.      * @param indices the positions of the elements to be removed
  4878.      * @return A new array containing the existing elements except those
  4879.      *         at the specified positions.
  4880.      * @throws IndexOutOfBoundsException if any index is out of range
  4881.      * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
  4882.      * @since 3.0.1
  4883.      */
  4884.     public static byte[] removeAll(final byte[] array, final int... indices) {
  4885.         return (byte[]) removeAll((Object) array, indices);
  4886.     }

  4887.     /**
  4888.      * Removes the elements at the specified positions from the specified array.
  4889.      * All remaining elements are shifted to the left.
  4890.      * <p>
  4891.      * This method returns a new array with the same elements of the input
  4892.      * array except those at the specified positions. The component
  4893.      * type of the returned array is always the same as that of the input
  4894.      * array.
  4895.      * </p>
  4896.      * <p>
  4897.      * If the input array is {@code null}, an IndexOutOfBoundsException
  4898.      * will be thrown, because in that case no valid index can be specified.
  4899.      * </p>
  4900.      * <pre>
  4901.      * ArrayUtils.removeAll([1], 0)             = []
  4902.      * ArrayUtils.removeAll([2, 6], 0)          = [6]
  4903.      * ArrayUtils.removeAll([2, 6], 0, 1)       = []
  4904.      * ArrayUtils.removeAll([2, 6, 3], 1, 2)    = [2]
  4905.      * ArrayUtils.removeAll([2, 6, 3], 0, 2)    = [6]
  4906.      * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
  4907.      * </pre>
  4908.      *
  4909.      * @param array   the array to remove the element from, may not be {@code null}
  4910.      * @param indices the positions of the elements to be removed
  4911.      * @return A new array containing the existing elements except those
  4912.      *         at the specified positions.
  4913.      * @throws IndexOutOfBoundsException if any index is out of range
  4914.      * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
  4915.      * @since 3.0.1
  4916.      */
  4917.     public static char[] removeAll(final char[] array, final int... indices) {
  4918.         return (char[]) removeAll((Object) array, indices);
  4919.     }

  4920.     /**
  4921.      * Removes the elements at the specified positions from the specified array.
  4922.      * All remaining elements are shifted to the left.
  4923.      * <p>
  4924.      * This method returns a new array with the same elements of the input
  4925.      * array except those at the specified positions. The component
  4926.      * type of the returned array is always the same as that of the input
  4927.      * array.
  4928.      * </p>
  4929.      * <p>
  4930.      * If the input array is {@code null}, an IndexOutOfBoundsException
  4931.      * will be thrown, because in that case no valid index can be specified.
  4932.      * </p>
  4933.      * <pre>
  4934.      * ArrayUtils.removeAll([1], 0)             = []
  4935.      * ArrayUtils.removeAll([2, 6], 0)          = [6]
  4936.      * ArrayUtils.removeAll([2, 6], 0, 1)       = []
  4937.      * ArrayUtils.removeAll([2, 6, 3], 1, 2)    = [2]
  4938.      * ArrayUtils.removeAll([2, 6, 3], 0, 2)    = [6]
  4939.      * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
  4940.      * </pre>
  4941.      *
  4942.      * @param array   the array to remove the element from, may not be {@code null}
  4943.      * @param indices the positions of the elements to be removed
  4944.      * @return A new array containing the existing elements except those
  4945.      *         at the specified positions.
  4946.      * @throws IndexOutOfBoundsException if any index is out of range
  4947.      * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
  4948.      * @since 3.0.1
  4949.      */
  4950.     public static double[] removeAll(final double[] array, final int... indices) {
  4951.         return (double[]) removeAll((Object) array, indices);
  4952.     }

  4953.     /**
  4954.      * Removes the elements at the specified positions from the specified array.
  4955.      * All remaining elements are shifted to the left.
  4956.      * <p>
  4957.      * This method returns a new array with the same elements of the input
  4958.      * array except those at the specified positions. The component
  4959.      * type of the returned array is always the same as that of the input
  4960.      * array.
  4961.      * </p>
  4962.      * <p>
  4963.      * If the input array is {@code null}, an IndexOutOfBoundsException
  4964.      * will be thrown, because in that case no valid index can be specified.
  4965.      * </p>
  4966.      * <pre>
  4967.      * ArrayUtils.removeAll([1], 0)             = []
  4968.      * ArrayUtils.removeAll([2, 6], 0)          = [6]
  4969.      * ArrayUtils.removeAll([2, 6], 0, 1)       = []
  4970.      * ArrayUtils.removeAll([2, 6, 3], 1, 2)    = [2]
  4971.      * ArrayUtils.removeAll([2, 6, 3], 0, 2)    = [6]
  4972.      * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
  4973.      * </pre>
  4974.      *
  4975.      * @param array   the array to remove the element from, may not be {@code null}
  4976.      * @param indices the positions of the elements to be removed
  4977.      * @return A new array containing the existing elements except those
  4978.      *         at the specified positions.
  4979.      * @throws IndexOutOfBoundsException if any index is out of range
  4980.      * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
  4981.      * @since 3.0.1
  4982.      */
  4983.     public static float[] removeAll(final float[] array, final int... indices) {
  4984.         return (float[]) removeAll((Object) array, indices);
  4985.     }

  4986.     /**
  4987.      * Removes the elements at the specified positions from the specified array.
  4988.      * All remaining elements are shifted to the left.
  4989.      * <p>
  4990.      * This method returns a new array with the same elements of the input
  4991.      * array except those at the specified positions. The component
  4992.      * type of the returned array is always the same as that of the input
  4993.      * array.
  4994.      * </p>
  4995.      * <p>
  4996.      * If the input array is {@code null}, an IndexOutOfBoundsException
  4997.      * will be thrown, because in that case no valid index can be specified.
  4998.      * </p>
  4999.      * <pre>
  5000.      * ArrayUtils.removeAll([1], 0)             = []
  5001.      * ArrayUtils.removeAll([2, 6], 0)          = [6]
  5002.      * ArrayUtils.removeAll([2, 6], 0, 1)       = []
  5003.      * ArrayUtils.removeAll([2, 6, 3], 1, 2)    = [2]
  5004.      * ArrayUtils.removeAll([2, 6, 3], 0, 2)    = [6]
  5005.      * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
  5006.      * </pre>
  5007.      *
  5008.      * @param array   the array to remove the element from, may not be {@code null}
  5009.      * @param indices the positions of the elements to be removed
  5010.      * @return A new array containing the existing elements except those
  5011.      *         at the specified positions.
  5012.      * @throws IndexOutOfBoundsException if any index is out of range
  5013.      * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
  5014.      * @since 3.0.1
  5015.      */
  5016.     public static int[] removeAll(final int[] array, final int... indices) {
  5017.         return (int[]) removeAll((Object) array, indices);
  5018.     }

  5019.     /**
  5020.      * Removes the elements at the specified positions from the specified array.
  5021.      * All remaining elements are shifted to the left.
  5022.      * <p>
  5023.      * This method returns a new array with the same elements of the input
  5024.      * array except those at the specified positions. The component
  5025.      * type of the returned array is always the same as that of the input
  5026.      * array.
  5027.      * </p>
  5028.      * <p>
  5029.      * If the input array is {@code null}, an IndexOutOfBoundsException
  5030.      * will be thrown, because in that case no valid index can be specified.
  5031.      * </p>
  5032.      * <pre>
  5033.      * ArrayUtils.removeAll([1], 0)             = []
  5034.      * ArrayUtils.removeAll([2, 6], 0)          = [6]
  5035.      * ArrayUtils.removeAll([2, 6], 0, 1)       = []
  5036.      * ArrayUtils.removeAll([2, 6, 3], 1, 2)    = [2]
  5037.      * ArrayUtils.removeAll([2, 6, 3], 0, 2)    = [6]
  5038.      * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
  5039.      * </pre>
  5040.      *
  5041.      * @param array   the array to remove the element from, may not be {@code null}
  5042.      * @param indices the positions of the elements to be removed
  5043.      * @return A new array containing the existing elements except those
  5044.      *         at the specified positions.
  5045.      * @throws IndexOutOfBoundsException if any index is out of range
  5046.      * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
  5047.      * @since 3.0.1
  5048.      */
  5049.     public static long[] removeAll(final long[] array, final int... indices) {
  5050.         return (long[]) removeAll((Object) array, indices);
  5051.     }

  5052.     /**
  5053.      * Removes multiple array elements specified by index.
  5054.      *
  5055.      * @param array source
  5056.      * @param indices to remove
  5057.      * @return new array of same type minus elements specified by unique values of {@code indices}
  5058.      */
  5059.     // package protected for access by unit tests
  5060.     static Object removeAll(final Object array, final int... indices) {
  5061.         if (array == null) {
  5062.             return null;
  5063.         }
  5064.         final int length = getLength(array);
  5065.         int diff = 0; // number of distinct indexes, i.e. number of entries that will be removed
  5066.         final int[] clonedIndices = ArraySorter.sort(clone(indices));
  5067.         // identify length of result array
  5068.         if (isNotEmpty(clonedIndices)) {
  5069.             int i = clonedIndices.length;
  5070.             int prevIndex = length;
  5071.             while (--i >= 0) {
  5072.                 final int index = clonedIndices[i];
  5073.                 if (index < 0 || index >= length) {
  5074.                     throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
  5075.                 }
  5076.                 if (index >= prevIndex) {
  5077.                     continue;
  5078.                 }
  5079.                 diff++;
  5080.                 prevIndex = index;
  5081.             }
  5082.         }
  5083.         // create result array
  5084.         final Object result = Array.newInstance(array.getClass().getComponentType(), length - diff);
  5085.         if (diff < length && clonedIndices != null) {
  5086.             int end = length; // index just after last copy
  5087.             int dest = length - diff; // number of entries so far not copied
  5088.             for (int i = clonedIndices.length - 1; i >= 0; i--) {
  5089.                 final int index = clonedIndices[i];
  5090.                 if (end - index > 1) { // same as (cp > 0)
  5091.                     final int cp = end - index - 1;
  5092.                     dest -= cp;
  5093.                     System.arraycopy(array, index + 1, result, dest, cp);
  5094.                     // After this copy, we still have room for dest items.
  5095.                 }
  5096.                 end = index;
  5097.             }
  5098.             if (end > 0) {
  5099.                 System.arraycopy(array, 0, result, 0, end);
  5100.             }
  5101.         }
  5102.         return result;
  5103.     }

  5104.     /**
  5105.      * Removes the elements at the specified positions from the specified array.
  5106.      * All remaining elements are shifted to the left.
  5107.      * <p>
  5108.      * This method returns a new array with the same elements of the input
  5109.      * array except those at the specified positions. The component
  5110.      * type of the returned array is always the same as that of the input
  5111.      * array.
  5112.      * </p>
  5113.      * <p>
  5114.      * If the input array is {@code null}, an IndexOutOfBoundsException
  5115.      * will be thrown, because in that case no valid index can be specified.
  5116.      * </p>
  5117.      * <pre>
  5118.      * ArrayUtils.removeAll([1], 0)             = []
  5119.      * ArrayUtils.removeAll([2, 6], 0)          = [6]
  5120.      * ArrayUtils.removeAll([2, 6], 0, 1)       = []
  5121.      * ArrayUtils.removeAll([2, 6, 3], 1, 2)    = [2]
  5122.      * ArrayUtils.removeAll([2, 6, 3], 0, 2)    = [6]
  5123.      * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
  5124.      * </pre>
  5125.      *
  5126.      * @param array   the array to remove the element from, may not be {@code null}
  5127.      * @param indices the positions of the elements to be removed
  5128.      * @return A new array containing the existing elements except those
  5129.      *         at the specified positions.
  5130.      * @throws IndexOutOfBoundsException if any index is out of range
  5131.      * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
  5132.      * @since 3.0.1
  5133.      */
  5134.     public static short[] removeAll(final short[] array, final int... indices) {
  5135.         return (short[]) removeAll((Object) array, indices);
  5136.     }

  5137.     /**
  5138.      * Removes the elements at the specified positions from the specified array.
  5139.      * All remaining elements are shifted to the left.
  5140.      * <p>
  5141.      * This method returns a new array with the same elements of the input
  5142.      * array except those at the specified positions. The component
  5143.      * type of the returned array is always the same as that of the input
  5144.      * array.
  5145.      * </p>
  5146.      * <p>
  5147.      * If the input array is {@code null}, an IndexOutOfBoundsException
  5148.      * will be thrown, because in that case no valid index can be specified.
  5149.      * </p>
  5150.      * <pre>
  5151.      * ArrayUtils.removeAll(["a", "b", "c"], 0, 2) = ["b"]
  5152.      * ArrayUtils.removeAll(["a", "b", "c"], 1, 2) = ["a"]
  5153.      * </pre>
  5154.      *
  5155.      * @param <T> the component type of the array
  5156.      * @param array   the array to remove the element from, may not be {@code null}
  5157.      * @param indices the positions of the elements to be removed
  5158.      * @return A new array containing the existing elements except those
  5159.      *         at the specified positions.
  5160.      * @throws IndexOutOfBoundsException if any index is out of range
  5161.      * (index &lt; 0 || index &gt;= array.length), or if the array is {@code null}.
  5162.      * @since 3.0.1
  5163.      */
  5164.     @SuppressWarnings("unchecked") // removeAll() always creates an array of the same type as its input
  5165.     public static <T> T[] removeAll(final T[] array, final int... indices) {
  5166.         return (T[]) removeAll((Object) array, indices);
  5167.     }

  5168.     /**
  5169.      * Removes the occurrences of the specified element from the specified boolean array.
  5170.      * <p>
  5171.      * All subsequent elements are shifted to the left (subtracts one from their indices).
  5172.      * If the array doesn't contain such an element, no elements are removed from the array.
  5173.      * {@code null} will be returned if the input array is {@code null}.
  5174.      * </p>
  5175.      *
  5176.      * @param array the input array, will not be modified, and may be {@code null}.
  5177.      * @param element the element to remove.
  5178.      * @return A new array containing the existing elements except the occurrences of the specified element.
  5179.      * @since 3.5
  5180.      * @deprecated Use {@link #removeAllOccurrences(boolean[], boolean)}
  5181.      */
  5182.     @Deprecated
  5183.     public static boolean[] removeAllOccurences(final boolean[] array, final boolean element) {
  5184.         return (boolean[]) removeAt(array, indexesOf(array, element));
  5185.     }

  5186.     /**
  5187.      * Removes the occurrences of the specified element from the specified byte array.
  5188.      * <p>
  5189.      * All subsequent elements are shifted to the left (subtracts one from their indices).
  5190.      * If the array doesn't contain such an element, no elements are removed from the array.
  5191.      * {@code null} will be returned if the input array is {@code null}.
  5192.      * </p>
  5193.      *
  5194.      * @param array the input array, will not be modified, and may be {@code null}.
  5195.      * @param element the element to remove.
  5196.      * @return A new array containing the existing elements except the occurrences of the specified element.
  5197.      * @since 3.5
  5198.      * @deprecated Use {@link #removeAllOccurrences(byte[], byte)}
  5199.      */
  5200.     @Deprecated
  5201.     public static byte[] removeAllOccurences(final byte[] array, final byte element) {
  5202.         return (byte[]) removeAt(array, indexesOf(array, element));
  5203.     }

  5204.     /**
  5205.      * Removes the occurrences of the specified element from the specified char array.
  5206.      * <p>
  5207.      * All subsequent elements are shifted to the left (subtracts one from their indices).
  5208.      * If the array doesn't contain such an element, no elements are removed from the array.
  5209.      * {@code null} will be returned if the input array is {@code null}.
  5210.      * </p>
  5211.      *
  5212.      * @param array the input array, will not be modified, and may be {@code null}.
  5213.      * @param element the element to remove.
  5214.      * @return A new array containing the existing elements except the occurrences of the specified element.
  5215.      * @since 3.5
  5216.      * @deprecated Use {@link #removeAllOccurrences(char[], char)}
  5217.      */
  5218.     @Deprecated
  5219.     public static char[] removeAllOccurences(final char[] array, final char element) {
  5220.         return (char[]) removeAt(array, indexesOf(array, element));
  5221.     }

  5222.     /**
  5223.      * Removes the occurrences of the specified element from the specified double array.
  5224.      * <p>
  5225.      * All subsequent elements are shifted to the left (subtracts one from their indices).
  5226.      * If the array doesn't contain such an element, no elements are removed from the array.
  5227.      * {@code null} will be returned if the input array is {@code null}.
  5228.      * </p>
  5229.      *
  5230.      * @param array the input array, will not be modified, and may be {@code null}.
  5231.      * @param element the element to remove.
  5232.      * @return A new array containing the existing elements except the occurrences of the specified element.
  5233.      * @since 3.5
  5234.      * @deprecated Use {@link #removeAllOccurrences(double[], double)}
  5235.      */
  5236.     @Deprecated
  5237.     public static double[] removeAllOccurences(final double[] array, final double element) {
  5238.         return (double[]) removeAt(array, indexesOf(array, element));
  5239.     }

  5240.     /**
  5241.      * Removes the occurrences of the specified element from the specified float array.
  5242.      * <p>
  5243.      * All subsequent elements are shifted to the left (subtracts one from their indices).
  5244.      * If the array doesn't contain such an element, no elements are removed from the array.
  5245.      * {@code null} will be returned if the input array is {@code null}.
  5246.      * </p>
  5247.      *
  5248.      * @param array the input array, will not be modified, and may be {@code null}.
  5249.      * @param element the element to remove.
  5250.      * @return A new array containing the existing elements except the occurrences of the specified element.
  5251.      * @since 3.5
  5252.      * @deprecated Use {@link #removeAllOccurrences(float[], float)}
  5253.      */
  5254.     @Deprecated
  5255.     public static float[] removeAllOccurences(final float[] array, final float element) {
  5256.         return (float[]) removeAt(array, indexesOf(array, element));
  5257.     }

  5258.     /**
  5259.      * Removes the occurrences of the specified element from the specified int array.
  5260.      * <p>
  5261.      * All subsequent elements are shifted to the left (subtracts one from their indices).
  5262.      * If the array doesn't contain such an element, no elements are removed from the array.
  5263.      * {@code null} will be returned if the input array is {@code null}.
  5264.      * </p>
  5265.      *
  5266.      * @param array the input array, will not be modified, and may be {@code null}.
  5267.      * @param element the element to remove.
  5268.      * @return A new array containing the existing elements except the occurrences of the specified element.
  5269.      * @since 3.5
  5270.      * @deprecated Use {@link #removeAllOccurrences(int[], int)}
  5271.      */
  5272.     @Deprecated
  5273.     public static int[] removeAllOccurences(final int[] array, final int element) {
  5274.         return (int[]) removeAt(array, indexesOf(array, element));
  5275.     }

  5276.     /**
  5277.      * Removes the occurrences of the specified element from the specified long array.
  5278.      * <p>
  5279.      * All subsequent elements are shifted to the left (subtracts one from their indices).
  5280.      * If the array doesn't contain such an element, no elements are removed from the array.
  5281.      * {@code null} will be returned if the input array is {@code null}.
  5282.      * </p>
  5283.      *
  5284.      * @param array the input array, will not be modified, and may be {@code null}.
  5285.      * @param element the element to remove.
  5286.      * @return A new array containing the existing elements except the occurrences of the specified element.
  5287.      * @since 3.5
  5288.      * @deprecated Use {@link #removeAllOccurrences(long[], long)}
  5289.      */
  5290.     @Deprecated
  5291.     public static long[] removeAllOccurences(final long[] array, final long element) {
  5292.         return (long[]) removeAt(array, indexesOf(array, element));
  5293.     }

  5294.     /**
  5295.      * Removes the occurrences of the specified element from the specified short array.
  5296.      * <p>
  5297.      * All subsequent elements are shifted to the left (subtracts one from their indices).
  5298.      * If the array doesn't contain such an element, no elements are removed from the array.
  5299.      * {@code null} will be returned if the input array is {@code null}.
  5300.      * </p>
  5301.      *
  5302.      * @param array the input array, will not be modified, and may be {@code null}.
  5303.      * @param element the element to remove.
  5304.      * @return A new array containing the existing elements except the occurrences of the specified element.
  5305.      * @since 3.5
  5306.      * @deprecated Use {@link #removeAllOccurrences(short[], short)}
  5307.      */
  5308.     @Deprecated
  5309.     public static short[] removeAllOccurences(final short[] array, final short element) {
  5310.         return (short[]) removeAt(array, indexesOf(array, element));
  5311.     }

  5312.     /**
  5313.      * Removes the occurrences of the specified element from the specified array.
  5314.      * <p>
  5315.      * All subsequent elements are shifted to the left (subtracts one from their indices).
  5316.      * If the array doesn't contain such an element, no elements are removed from the array.
  5317.      * {@code null} will be returned if the input array is {@code null}.
  5318.      * </p>
  5319.      *
  5320.      * @param <T> the type of object in the array, may be {@code null}.
  5321.      * @param array the input array, will not be modified, and may be {@code null}.
  5322.      * @param element the element to remove, may be {@code null}.
  5323.      * @return A new array containing the existing elements except the occurrences of the specified element.
  5324.      * @since 3.5
  5325.      * @deprecated Use {@link #removeAllOccurrences(Object[], Object)}
  5326.      */
  5327.     @Deprecated
  5328.     public static <T> T[] removeAllOccurences(final T[] array, final T element) {
  5329.         return (T[]) removeAt(array, indexesOf(array, element));
  5330.     }

  5331.     /**
  5332.      * Removes the occurrences of the specified element from the specified boolean array.
  5333.      * <p>
  5334.      * All subsequent elements are shifted to the left (subtracts one from their indices).
  5335.      * If the array doesn't contain such an element, no elements are removed from the array.
  5336.      * {@code null} will be returned if the input array is {@code null}.
  5337.      * </p>
  5338.      *
  5339.      * @param array the input array, will not be modified, and may be {@code null}.
  5340.      * @param element the element to remove.
  5341.      * @return A new array containing the existing elements except the occurrences of the specified element.
  5342.      * @since 3.10
  5343.      */
  5344.     public static boolean[] removeAllOccurrences(final boolean[] array, final boolean element) {
  5345.         return (boolean[]) removeAt(array, indexesOf(array, element));
  5346.     }

  5347.     /**
  5348.      * Removes the occurrences of the specified element from the specified byte array.
  5349.      * <p>
  5350.      * All subsequent elements are shifted to the left (subtracts one from their indices).
  5351.      * If the array doesn't contain such an element, no elements are removed from the array.
  5352.      * {@code null} will be returned if the input array is {@code null}.
  5353.      * </p>
  5354.      *
  5355.      * @param array the input array, will not be modified, and may be {@code null}.
  5356.      * @param element the element to remove.
  5357.      * @return A new array containing the existing elements except the occurrences of the specified element.
  5358.      * @since 3.10
  5359.      */
  5360.     public static byte[] removeAllOccurrences(final byte[] array, final byte element) {
  5361.         return (byte[]) removeAt(array, indexesOf(array, element));
  5362.     }

  5363.     /**
  5364.      * Removes the occurrences of the specified element from the specified char array.
  5365.      * <p>
  5366.      * All subsequent elements are shifted to the left (subtracts one from their indices).
  5367.      * If the array doesn't contain such an element, no elements are removed from the array.
  5368.      * {@code null} will be returned if the input array is {@code null}.
  5369.      * </p>
  5370.      *
  5371.      * @param array the input array, will not be modified, and may be {@code null}.
  5372.      * @param element the element to remove.
  5373.      * @return A new array containing the existing elements except the occurrences of the specified element.
  5374.      * @since 3.10
  5375.      */
  5376.     public static char[] removeAllOccurrences(final char[] array, final char element) {
  5377.         return (char[]) removeAt(array, indexesOf(array, element));
  5378.     }

  5379.     /**
  5380.      * Removes the occurrences of the specified element from the specified double array.
  5381.      * <p>
  5382.      * All subsequent elements are shifted to the left (subtracts one from their indices).
  5383.      * If the array doesn't contain such an element, no elements are removed from the array.
  5384.      * {@code null} will be returned if the input array is {@code null}.
  5385.      * </p>
  5386.      *
  5387.      * @param array the input array, will not be modified, and may be {@code null}.
  5388.      * @param element the element to remove.
  5389.      * @return A new array containing the existing elements except the occurrences of the specified element.
  5390.      * @since 3.10
  5391.      */
  5392.     public static double[] removeAllOccurrences(final double[] array, final double element) {
  5393.         return (double[]) removeAt(array, indexesOf(array, element));
  5394.     }

  5395.     /**
  5396.      * Removes the occurrences of the specified element from the specified float array.
  5397.      * <p>
  5398.      * All subsequent elements are shifted to the left (subtracts one from their indices).
  5399.      * If the array doesn't contain such an element, no elements are removed from the array.
  5400.      * {@code null} will be returned if the input array is {@code null}.
  5401.      * </p>
  5402.      *
  5403.      * @param array the input array, will not be modified, and may be {@code null}.
  5404.      * @param element the element to remove.
  5405.      * @return A new array containing the existing elements except the occurrences of the specified element.
  5406.      * @since 3.10
  5407.      */
  5408.     public static float[] removeAllOccurrences(final float[] array, final float element) {
  5409.         return (float[]) removeAt(array, indexesOf(array, element));
  5410.     }

  5411.     /**
  5412.      * Removes the occurrences of the specified element from the specified int array.
  5413.      * <p>
  5414.      * All subsequent elements are shifted to the left (subtracts one from their indices).
  5415.      * If the array doesn't contain such an element, no elements are removed from the array.
  5416.      * {@code null} will be returned if the input array is {@code null}.
  5417.      * </p>
  5418.      *
  5419.      * @param array the input array, will not be modified, and may be {@code null}.
  5420.      * @param element the element to remove.
  5421.      * @return A new array containing the existing elements except the occurrences of the specified element.
  5422.      * @since 3.10
  5423.      */
  5424.     public static int[] removeAllOccurrences(final int[] array, final int element) {
  5425.         return (int[]) removeAt(array, indexesOf(array, element));
  5426.     }

  5427.     /**
  5428.      * Removes the occurrences of the specified element from the specified long array.
  5429.      * <p>
  5430.      * All subsequent elements are shifted to the left (subtracts one from their indices).
  5431.      * If the array doesn't contain such an element, no elements are removed from the array.
  5432.      * {@code null} will be returned if the input array is {@code null}.
  5433.      * </p>
  5434.      *
  5435.      * @param array the input array, will not be modified, and may be {@code null}.
  5436.      * @param element the element to remove.
  5437.      * @return A new array containing the existing elements except the occurrences of the specified element.
  5438.      * @since 3.10
  5439.      */
  5440.     public static long[] removeAllOccurrences(final long[] array, final long element) {
  5441.         return (long[]) removeAt(array, indexesOf(array, element));
  5442.     }

  5443.     /**
  5444.      * Removes the occurrences of the specified element from the specified short array.
  5445.      * <p>
  5446.      * All subsequent elements are shifted to the left (subtracts one from their indices).
  5447.      * If the array doesn't contain such an element, no elements are removed from the array.
  5448.      * {@code null} will be returned if the input array is {@code null}.
  5449.      * </p>
  5450.      *
  5451.      * @param array the input array, will not be modified, and may be {@code null}.
  5452.      * @param element the element to remove.
  5453.      * @return A new array containing the existing elements except the occurrences of the specified element.
  5454.      * @since 3.10
  5455.      */
  5456.     public static short[] removeAllOccurrences(final short[] array, final short element) {
  5457.         return (short[]) removeAt(array, indexesOf(array, element));
  5458.     }

  5459.     /**
  5460.      * Removes the occurrences of the specified element from the specified array.
  5461.      * <p>
  5462.      * All subsequent elements are shifted to the left (subtracts one from their indices).
  5463.      * If the array doesn't contain such an element, no elements are removed from the array.
  5464.      * {@code null} will be returned if the input array is {@code null}.
  5465.      * </p>
  5466.      *
  5467.      * @param <T> the type of object in the array, may be {@code null}.
  5468.      * @param array the input array, will not be modified, and may be {@code null}.
  5469.      * @param element the element to remove, may be {@code null}.
  5470.      * @return A new array containing the existing elements except the occurrences of the specified element.
  5471.      * @since 3.10
  5472.      */
  5473.     public static <T> T[] removeAllOccurrences(final T[] array, final T element) {
  5474.         return (T[]) removeAt(array, indexesOf(array, element));
  5475.     }

  5476.     /**
  5477.      * Removes multiple array elements specified by indices.
  5478.      *
  5479.      * @param array the input array, will not be modified, and may be {@code null}.
  5480.      * @param indices to remove.
  5481.      * @return new array of same type minus elements specified by the set bits in {@code indices}.
  5482.      */
  5483.     // package protected for access by unit tests
  5484.     static Object removeAt(final Object array, final BitSet indices) {
  5485.         if (array == null) {
  5486.             return null;
  5487.         }
  5488.         final int srcLength = getLength(array);
  5489.         // No need to check maxIndex here, because method only currently called from removeElements()
  5490.         // which guarantee to generate only valid bit entries.
  5491. //        final int maxIndex = indices.length();
  5492. //        if (maxIndex > srcLength) {
  5493. //            throw new IndexOutOfBoundsException("Index: " + (maxIndex-1) + ", Length: " + srcLength);
  5494. //        }
  5495.         final int removals = indices.cardinality(); // true bits are items to remove
  5496.         final Object result = Array.newInstance(array.getClass().getComponentType(), srcLength - removals);
  5497.         int srcIndex = 0;
  5498.         int destIndex = 0;
  5499.         int count;
  5500.         int set;
  5501.         while ((set = indices.nextSetBit(srcIndex)) != -1) {
  5502.             count = set - srcIndex;
  5503.             if (count > 0) {
  5504.                 System.arraycopy(array, srcIndex, result, destIndex, count);
  5505.                 destIndex += count;
  5506.             }
  5507.             srcIndex = indices.nextClearBit(set);
  5508.         }
  5509.         count = srcLength - srcIndex;
  5510.         if (count > 0) {
  5511.             System.arraycopy(array, srcIndex, result, destIndex, count);
  5512.         }
  5513.         return result;
  5514.     }

  5515.     /**
  5516.      * Removes the first occurrence of the specified element from the
  5517.      * specified array. All subsequent elements are shifted to the left
  5518.      * (subtracts one from their indices). If the array doesn't contain
  5519.      * such an element, no elements are removed from the array.
  5520.      * <p>
  5521.      * This method returns a new array with the same elements of the input
  5522.      * array except the first occurrence of the specified element. The component
  5523.      * type of the returned array is always the same as that of the input
  5524.      * array.
  5525.      * </p>
  5526.      * <pre>
  5527.      * ArrayUtils.removeElement(null, true)                = null
  5528.      * ArrayUtils.removeElement([], true)                  = []
  5529.      * ArrayUtils.removeElement([true], false)             = [true]
  5530.      * ArrayUtils.removeElement([true, false], false)      = [true]
  5531.      * ArrayUtils.removeElement([true, false, true], true) = [false, true]
  5532.      * </pre>
  5533.      *
  5534.      * @param array the input array, may be {@code null}.
  5535.      * @param element  the element to be removed.
  5536.      * @return A new array containing the existing elements except the first
  5537.      *         occurrence of the specified element.
  5538.      * @since 2.1
  5539.      */
  5540.     public static boolean[] removeElement(final boolean[] array, final boolean element) {
  5541.         final int index = indexOf(array, element);
  5542.         return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
  5543.     }

  5544.     /**
  5545.      * Removes the first occurrence of the specified element from the
  5546.      * specified array. All subsequent elements are shifted to the left
  5547.      * (subtracts one from their indices). If the array doesn't contain
  5548.      * such an element, no elements are removed from the array.
  5549.      * <p>
  5550.      * This method returns a new array with the same elements of the input
  5551.      * array except the first occurrence of the specified element. The component
  5552.      * type of the returned array is always the same as that of the input
  5553.      * array.
  5554.      * </p>
  5555.      * <pre>
  5556.      * ArrayUtils.removeElement(null, 1)        = null
  5557.      * ArrayUtils.removeElement([], 1)          = []
  5558.      * ArrayUtils.removeElement([1], 0)         = [1]
  5559.      * ArrayUtils.removeElement([1, 0], 0)      = [1]
  5560.      * ArrayUtils.removeElement([1, 0, 1], 1)   = [0, 1]
  5561.      * </pre>
  5562.      *
  5563.      * @param array the input array, may be {@code null}.
  5564.      * @param element  the element to be removed.
  5565.      * @return A new array containing the existing elements except the first
  5566.      *         occurrence of the specified element.
  5567.      * @since 2.1
  5568.      */
  5569.     public static byte[] removeElement(final byte[] array, final byte element) {
  5570.         final int index = indexOf(array, element);
  5571.         return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
  5572.     }

  5573.     /**
  5574.      * Removes the first occurrence of the specified element from the
  5575.      * specified array. All subsequent elements are shifted to the left
  5576.      * (subtracts one from their indices). If the array doesn't contain
  5577.      * such an element, no elements are removed from the array.
  5578.      * <p>
  5579.      * This method returns a new array with the same elements of the input
  5580.      * array except the first occurrence of the specified element. The component
  5581.      * type of the returned array is always the same as that of the input
  5582.      * array.
  5583.      * </p>
  5584.      * <pre>
  5585.      * ArrayUtils.removeElement(null, 'a')            = null
  5586.      * ArrayUtils.removeElement([], 'a')              = []
  5587.      * ArrayUtils.removeElement(['a'], 'b')           = ['a']
  5588.      * ArrayUtils.removeElement(['a', 'b'], 'a')      = ['b']
  5589.      * ArrayUtils.removeElement(['a', 'b', 'a'], 'a') = ['b', 'a']
  5590.      * </pre>
  5591.      *
  5592.      * @param array the input array, may be {@code null}.
  5593.      * @param element  the element to be removed.
  5594.      * @return A new array containing the existing elements except the first
  5595.      *         occurrence of the specified element.
  5596.      * @since 2.1
  5597.      */
  5598.     public static char[] removeElement(final char[] array, final char element) {
  5599.         final int index = indexOf(array, element);
  5600.         return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
  5601.     }

  5602.     /**
  5603.      * Removes the first occurrence of the specified element from the
  5604.      * specified array. All subsequent elements are shifted to the left
  5605.      * (subtracts one from their indices). If the array doesn't contain
  5606.      * such an element, no elements are removed from the array.
  5607.      * <p>
  5608.      * This method returns a new array with the same elements of the input
  5609.      * array except the first occurrence of the specified element. The component
  5610.      * type of the returned array is always the same as that of the input
  5611.      * array.
  5612.      * </p>
  5613.      * <pre>
  5614.      * ArrayUtils.removeElement(null, 1.1)            = null
  5615.      * ArrayUtils.removeElement([], 1.1)              = []
  5616.      * ArrayUtils.removeElement([1.1], 1.2)           = [1.1]
  5617.      * ArrayUtils.removeElement([1.1, 2.3], 1.1)      = [2.3]
  5618.      * ArrayUtils.removeElement([1.1, 2.3, 1.1], 1.1) = [2.3, 1.1]
  5619.      * </pre>
  5620.      *
  5621.      * @param array the input array, may be {@code null}.
  5622.      * @param element  the element to be removed.
  5623.      * @return A new array containing the existing elements except the first
  5624.      *         occurrence of the specified element.
  5625.      * @since 2.1
  5626.      */
  5627.     public static double[] removeElement(final double[] array, final double element) {
  5628.         final int index = indexOf(array, element);
  5629.         return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
  5630.     }

  5631.     /**
  5632.      * Removes the first occurrence of the specified element from the
  5633.      * specified array. All subsequent elements are shifted to the left
  5634.      * (subtracts one from their indices). If the array doesn't contain
  5635.      * such an element, no elements are removed from the array.
  5636.      * <p>
  5637.      * This method returns a new array with the same elements of the input
  5638.      * array except the first occurrence of the specified element. The component
  5639.      * type of the returned array is always the same as that of the input
  5640.      * array.
  5641.      * </p>
  5642.      * <pre>
  5643.      * ArrayUtils.removeElement(null, 1.1)            = null
  5644.      * ArrayUtils.removeElement([], 1.1)              = []
  5645.      * ArrayUtils.removeElement([1.1], 1.2)           = [1.1]
  5646.      * ArrayUtils.removeElement([1.1, 2.3], 1.1)      = [2.3]
  5647.      * ArrayUtils.removeElement([1.1, 2.3, 1.1], 1.1) = [2.3, 1.1]
  5648.      * </pre>
  5649.      *
  5650.      * @param array the input array, may be {@code null}.
  5651.      * @param element  the element to be removed.
  5652.      * @return A new array containing the existing elements except the first
  5653.      *         occurrence of the specified element.
  5654.      * @since 2.1
  5655.      */
  5656.     public static float[] removeElement(final float[] array, final float element) {
  5657.         final int index = indexOf(array, element);
  5658.         return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
  5659.     }

  5660.     /**
  5661.      * Removes the first occurrence of the specified element from the
  5662.      * specified array. All subsequent elements are shifted to the left
  5663.      * (subtracts one from their indices). If the array doesn't contain
  5664.      * such an element, no elements are removed from the array.
  5665.      * <p>
  5666.      * This method returns a new array with the same elements of the input
  5667.      * array except the first occurrence of the specified element. The component
  5668.      * type of the returned array is always the same as that of the input
  5669.      * array.
  5670.      * </p>
  5671.      * <pre>
  5672.      * ArrayUtils.removeElement(null, 1)      = null
  5673.      * ArrayUtils.removeElement([], 1)        = []
  5674.      * ArrayUtils.removeElement([1], 2)       = [1]
  5675.      * ArrayUtils.removeElement([1, 3], 1)    = [3]
  5676.      * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
  5677.      * </pre>
  5678.      *
  5679.      * @param array the input array, may be {@code null}.
  5680.      * @param element  the element to be removed.
  5681.      * @return A new array containing the existing elements except the first
  5682.      *         occurrence of the specified element.
  5683.      * @since 2.1
  5684.      */
  5685.     public static int[] removeElement(final int[] array, final int element) {
  5686.         final int index = indexOf(array, element);
  5687.         return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
  5688.     }

  5689.     /**
  5690.      * Removes the first occurrence of the specified element from the
  5691.      * specified array. All subsequent elements are shifted to the left
  5692.      * (subtracts one from their indices). If the array doesn't contain
  5693.      * such an element, no elements are removed from the array.
  5694.      * <p>
  5695.      * This method returns a new array with the same elements of the input
  5696.      * array except the first occurrence of the specified element. The component
  5697.      * type of the returned array is always the same as that of the input
  5698.      * array.
  5699.      * </p>
  5700.      * <pre>
  5701.      * ArrayUtils.removeElement(null, 1)      = null
  5702.      * ArrayUtils.removeElement([], 1)        = []
  5703.      * ArrayUtils.removeElement([1], 2)       = [1]
  5704.      * ArrayUtils.removeElement([1, 3], 1)    = [3]
  5705.      * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
  5706.      * </pre>
  5707.      *
  5708.      * @param array the input array, may be {@code null}.
  5709.      * @param element  the element to be removed.
  5710.      * @return A new array containing the existing elements except the first
  5711.      *         occurrence of the specified element.
  5712.      * @since 2.1
  5713.      */
  5714.     public static long[] removeElement(final long[] array, final long element) {
  5715.         final int index = indexOf(array, element);
  5716.         return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
  5717.     }

  5718.     /**
  5719.      * Removes the first occurrence of the specified element from the
  5720.      * specified array. All subsequent elements are shifted to the left
  5721.      * (subtracts one from their indices). If the array doesn't contain
  5722.      * such an element, no elements are removed from the array.
  5723.      * <p>
  5724.      * This method returns a new array with the same elements of the input
  5725.      * array except the first occurrence of the specified element. The component
  5726.      * type of the returned array is always the same as that of the input
  5727.      * array.
  5728.      * </p>
  5729.      * <pre>
  5730.      * ArrayUtils.removeElement(null, 1)      = null
  5731.      * ArrayUtils.removeElement([], 1)        = []
  5732.      * ArrayUtils.removeElement([1], 2)       = [1]
  5733.      * ArrayUtils.removeElement([1, 3], 1)    = [3]
  5734.      * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
  5735.      * </pre>
  5736.      *
  5737.      * @param array the input array, may be {@code null}.
  5738.      * @param element  the element to be removed.
  5739.      * @return A new array containing the existing elements except the first
  5740.      *         occurrence of the specified element.
  5741.      * @since 2.1
  5742.      */
  5743.     public static short[] removeElement(final short[] array, final short element) {
  5744.         final int index = indexOf(array, element);
  5745.         return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
  5746.     }

  5747.     /**
  5748.      * Removes the first occurrence of the specified element from the
  5749.      * specified array. All subsequent elements are shifted to the left
  5750.      * (subtracts one from their indices). If the array doesn't contain
  5751.      * such an element, no elements are removed from the array.
  5752.      * <p>
  5753.      * This method returns a new array with the same elements of the input
  5754.      * array except the first occurrence of the specified element. The component
  5755.      * type of the returned array is always the same as that of the input
  5756.      * array.
  5757.      * </p>
  5758.      * <pre>
  5759.      * ArrayUtils.removeElement(null, "a")            = null
  5760.      * ArrayUtils.removeElement([], "a")              = []
  5761.      * ArrayUtils.removeElement(["a"], "b")           = ["a"]
  5762.      * ArrayUtils.removeElement(["a", "b"], "a")      = ["b"]
  5763.      * ArrayUtils.removeElement(["a", "b", "a"], "a") = ["b", "a"]
  5764.      * </pre>
  5765.      *
  5766.      * @param <T> the component type of the array
  5767.      * @param array the input array, may be {@code null}.
  5768.      * @param element  the element to be removed, may be {@code null}.
  5769.      * @return A new array containing the existing elements except the first
  5770.      *         occurrence of the specified element.
  5771.      * @since 2.1
  5772.      */
  5773.     public static <T> T[] removeElement(final T[] array, final Object element) {
  5774.         final int index = indexOf(array, element);
  5775.         return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
  5776.     }

  5777.     /**
  5778.      * Removes occurrences of specified elements, in specified quantities,
  5779.      * from the specified array. All subsequent elements are shifted left.
  5780.      * For any element-to-be-removed specified in greater quantities than
  5781.      * contained in the original array, no change occurs beyond the
  5782.      * removal of the existing matching items.
  5783.      * <p>
  5784.      * This method returns a new array with the same elements of the input
  5785.      * array except for the earliest-encountered occurrences of the specified
  5786.      * elements. The component type of the returned array is always the same
  5787.      * as that of the input array.
  5788.      * </p>
  5789.      * <pre>
  5790.      * ArrayUtils.removeElements(null, true, false)               = null
  5791.      * ArrayUtils.removeElements([], true, false)                 = []
  5792.      * ArrayUtils.removeElements([true], false, false)            = [true]
  5793.      * ArrayUtils.removeElements([true, false], true, true)       = [false]
  5794.      * ArrayUtils.removeElements([true, false, true], true)       = [false, true]
  5795.      * ArrayUtils.removeElements([true, false, true], true, true) = [false]
  5796.      * </pre>
  5797.      *
  5798.      * @param array the input array, will not be modified, and may be {@code null}.
  5799.      * @param values  the values to be removed.
  5800.      * @return A new array containing the existing elements except the
  5801.      *         earliest-encountered occurrences of the specified elements.
  5802.      * @since 3.0.1
  5803.      */
  5804.     public static boolean[] removeElements(final boolean[] array, final boolean... values) {
  5805.         if (isEmpty(array) || isEmpty(values)) {
  5806.             return clone(array);
  5807.         }
  5808.         final HashMap<Boolean, MutableInt> occurrences = new HashMap<>(2); // only two possible values here
  5809.         for (final boolean v : values) {
  5810.             increment(occurrences, Boolean.valueOf(v));
  5811.         }
  5812.         final BitSet toRemove = new BitSet();
  5813.         for (int i = 0; i < array.length; i++) {
  5814.             final boolean key = array[i];
  5815.             final MutableInt count = occurrences.get(key);
  5816.             if (count != null) {
  5817.                 if (count.decrementAndGet() == 0) {
  5818.                     occurrences.remove(key);
  5819.                 }
  5820.                 toRemove.set(i);
  5821.             }
  5822.         }
  5823.         return (boolean[]) removeAt(array, toRemove);
  5824.     }

  5825.     /**
  5826.      * Removes occurrences of specified elements, in specified quantities,
  5827.      * from the specified array. All subsequent elements are shifted left.
  5828.      * For any element-to-be-removed specified in greater quantities than
  5829.      * contained in the original array, no change occurs beyond the
  5830.      * removal of the existing matching items.
  5831.      * <p>
  5832.      * This method returns a new array with the same elements of the input
  5833.      * array except for the earliest-encountered occurrences of the specified
  5834.      * elements. The component type of the returned array is always the same
  5835.      * as that of the input array.
  5836.      * </p>
  5837.      * <pre>
  5838.      * ArrayUtils.removeElements(null, 1, 2)      = null
  5839.      * ArrayUtils.removeElements([], 1, 2)        = []
  5840.      * ArrayUtils.removeElements([1], 2, 3)       = [1]
  5841.      * ArrayUtils.removeElements([1, 3], 1, 2)    = [3]
  5842.      * ArrayUtils.removeElements([1, 3, 1], 1)    = [3, 1]
  5843.      * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
  5844.      * </pre>
  5845.      *
  5846.      * @param array the input array, will not be modified, and may be {@code null}.
  5847.      * @param values  the values to be removed.
  5848.      * @return A new array containing the existing elements except the
  5849.      *         earliest-encountered occurrences of the specified elements.
  5850.      * @since 3.0.1
  5851.      */
  5852.     public static byte[] removeElements(final byte[] array, final byte... values) {
  5853.         if (isEmpty(array) || isEmpty(values)) {
  5854.             return clone(array);
  5855.         }
  5856.         final HashMap<Byte, MutableInt> occurrences = new HashMap<>(values.length);
  5857.         for (final byte v : values) {
  5858.             increment(occurrences, Byte.valueOf(v));
  5859.         }
  5860.         final BitSet toRemove = new BitSet();
  5861.         for (int i = 0; i < array.length; i++) {
  5862.             final byte key = array[i];
  5863.             final MutableInt count = occurrences.get(key);
  5864.             if (count != null) {
  5865.                 if (count.decrementAndGet() == 0) {
  5866.                     occurrences.remove(key);
  5867.                 }
  5868.                 toRemove.set(i);
  5869.             }
  5870.         }
  5871.         return (byte[]) removeAt(array, toRemove);
  5872.     }

  5873.     /**
  5874.      * Removes occurrences of specified elements, in specified quantities,
  5875.      * from the specified array. All subsequent elements are shifted left.
  5876.      * For any element-to-be-removed specified in greater quantities than
  5877.      * contained in the original array, no change occurs beyond the
  5878.      * removal of the existing matching items.
  5879.      * <p>
  5880.      * This method returns a new array with the same elements of the input
  5881.      * array except for the earliest-encountered occurrences of the specified
  5882.      * elements. The component type of the returned array is always the same
  5883.      * as that of the input array.
  5884.      * </p>
  5885.      * <pre>
  5886.      * ArrayUtils.removeElements(null, 1, 2)      = null
  5887.      * ArrayUtils.removeElements([], 1, 2)        = []
  5888.      * ArrayUtils.removeElements([1], 2, 3)       = [1]
  5889.      * ArrayUtils.removeElements([1, 3], 1, 2)    = [3]
  5890.      * ArrayUtils.removeElements([1, 3, 1], 1)    = [3, 1]
  5891.      * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
  5892.      * </pre>
  5893.      *
  5894.      * @param array the input array, will not be modified, and may be {@code null}.
  5895.      * @param values  the values to be removed.
  5896.      * @return A new array containing the existing elements except the
  5897.      *         earliest-encountered occurrences of the specified elements.
  5898.      * @since 3.0.1
  5899.      */
  5900.     public static char[] removeElements(final char[] array, final char... values) {
  5901.         if (isEmpty(array) || isEmpty(values)) {
  5902.             return clone(array);
  5903.         }
  5904.         final HashMap<Character, MutableInt> occurrences = new HashMap<>(values.length);
  5905.         for (final char v : values) {
  5906.             increment(occurrences, Character.valueOf(v));
  5907.         }
  5908.         final BitSet toRemove = new BitSet();
  5909.         for (int i = 0; i < array.length; i++) {
  5910.             final char key = array[i];
  5911.             final MutableInt count = occurrences.get(key);
  5912.             if (count != null) {
  5913.                 if (count.decrementAndGet() == 0) {
  5914.                     occurrences.remove(key);
  5915.                 }
  5916.                 toRemove.set(i);
  5917.             }
  5918.         }
  5919.         return (char[]) removeAt(array, toRemove);
  5920.     }

  5921.     /**
  5922.      * Removes occurrences of specified elements, in specified quantities,
  5923.      * from the specified array. All subsequent elements are shifted left.
  5924.      * For any element-to-be-removed specified in greater quantities than
  5925.      * contained in the original array, no change occurs beyond the
  5926.      * removal of the existing matching items.
  5927.      * <p>
  5928.      * This method returns a new array with the same elements of the input
  5929.      * array except for the earliest-encountered occurrences of the specified
  5930.      * elements. The component type of the returned array is always the same
  5931.      * as that of the input array.
  5932.      * </p>
  5933.      * <pre>
  5934.      * ArrayUtils.removeElements(null, 1, 2)      = null
  5935.      * ArrayUtils.removeElements([], 1, 2)        = []
  5936.      * ArrayUtils.removeElements([1], 2, 3)       = [1]
  5937.      * ArrayUtils.removeElements([1, 3], 1, 2)    = [3]
  5938.      * ArrayUtils.removeElements([1, 3, 1], 1)    = [3, 1]
  5939.      * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
  5940.      * </pre>
  5941.      *
  5942.      * @param array the input array, will not be modified, and may be {@code null}.
  5943.      * @param values  the values to be removed.
  5944.      * @return A new array containing the existing elements except the
  5945.      *         earliest-encountered occurrences of the specified elements.
  5946.      * @since 3.0.1
  5947.      */
  5948.     public static double[] removeElements(final double[] array, final double... values) {
  5949.         if (isEmpty(array) || isEmpty(values)) {
  5950.             return clone(array);
  5951.         }
  5952.         final HashMap<Double, MutableInt> occurrences = new HashMap<>(values.length);
  5953.         for (final double v : values) {
  5954.             increment(occurrences, Double.valueOf(v));
  5955.         }
  5956.         final BitSet toRemove = new BitSet();
  5957.         for (int i = 0; i < array.length; i++) {
  5958.             final double key = array[i];
  5959.             final MutableInt count = occurrences.get(key);
  5960.             if (count != null) {
  5961.                 if (count.decrementAndGet() == 0) {
  5962.                     occurrences.remove(key);
  5963.                 }
  5964.                 toRemove.set(i);
  5965.             }
  5966.         }
  5967.         return (double[]) removeAt(array, toRemove);
  5968.     }

  5969.     /**
  5970.      * Removes occurrences of specified elements, in specified quantities,
  5971.      * from the specified array. All subsequent elements are shifted left.
  5972.      * For any element-to-be-removed specified in greater quantities than
  5973.      * contained in the original array, no change occurs beyond the
  5974.      * removal of the existing matching items.
  5975.      * <p>
  5976.      * This method returns a new array with the same elements of the input
  5977.      * array except for the earliest-encountered occurrences of the specified
  5978.      * elements. The component type of the returned array is always the same
  5979.      * as that of the input array.
  5980.      * </p>
  5981.      * <pre>
  5982.      * ArrayUtils.removeElements(null, 1, 2)      = null
  5983.      * ArrayUtils.removeElements([], 1, 2)        = []
  5984.      * ArrayUtils.removeElements([1], 2, 3)       = [1]
  5985.      * ArrayUtils.removeElements([1, 3], 1, 2)    = [3]
  5986.      * ArrayUtils.removeElements([1, 3, 1], 1)    = [3, 1]
  5987.      * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
  5988.      * </pre>
  5989.      *
  5990.      * @param array the input array, will not be modified, and may be {@code null}.
  5991.      * @param values  the values to be removed.
  5992.      * @return A new array containing the existing elements except the
  5993.      *         earliest-encountered occurrences of the specified elements.
  5994.      * @since 3.0.1
  5995.      */
  5996.     public static float[] removeElements(final float[] array, final float... values) {
  5997.         if (isEmpty(array) || isEmpty(values)) {
  5998.             return clone(array);
  5999.         }
  6000.         final HashMap<Float, MutableInt> occurrences = new HashMap<>(values.length);
  6001.         for (final float v : values) {
  6002.             increment(occurrences, Float.valueOf(v));
  6003.         }
  6004.         final BitSet toRemove = new BitSet();
  6005.         for (int i = 0; i < array.length; i++) {
  6006.             final float key = array[i];
  6007.             final MutableInt count = occurrences.get(key);
  6008.             if (count != null) {
  6009.                 if (count.decrementAndGet() == 0) {
  6010.                     occurrences.remove(key);
  6011.                 }
  6012.                 toRemove.set(i);
  6013.             }
  6014.         }
  6015.         return (float[]) removeAt(array, toRemove);
  6016.     }

  6017.     /**
  6018.      * Removes occurrences of specified elements, in specified quantities,
  6019.      * from the specified array. All subsequent elements are shifted left.
  6020.      * For any element-to-be-removed specified in greater quantities than
  6021.      * contained in the original array, no change occurs beyond the
  6022.      * removal of the existing matching items.
  6023.      * <p>
  6024.      * This method returns a new array with the same elements of the input
  6025.      * array except for the earliest-encountered occurrences of the specified
  6026.      * elements. The component type of the returned array is always the same
  6027.      * as that of the input array.
  6028.      * </p>
  6029.      * <pre>
  6030.      * ArrayUtils.removeElements(null, 1, 2)      = null
  6031.      * ArrayUtils.removeElements([], 1, 2)        = []
  6032.      * ArrayUtils.removeElements([1], 2, 3)       = [1]
  6033.      * ArrayUtils.removeElements([1, 3], 1, 2)    = [3]
  6034.      * ArrayUtils.removeElements([1, 3, 1], 1)    = [3, 1]
  6035.      * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
  6036.      * </pre>
  6037.      *
  6038.      * @param array the input array, will not be modified, and may be {@code null}.
  6039.      * @param values  the values to be removed.
  6040.      * @return A new array containing the existing elements except the
  6041.      *         earliest-encountered occurrences of the specified elements.
  6042.      * @since 3.0.1
  6043.      */
  6044.     public static int[] removeElements(final int[] array, final int... values) {
  6045.         if (isEmpty(array) || isEmpty(values)) {
  6046.             return clone(array);
  6047.         }
  6048.         final HashMap<Integer, MutableInt> occurrences = new HashMap<>(values.length);
  6049.         for (final int v : values) {
  6050.             increment(occurrences, Integer.valueOf(v));
  6051.         }
  6052.         final BitSet toRemove = new BitSet();
  6053.         for (int i = 0; i < array.length; i++) {
  6054.             final int key = array[i];
  6055.             final MutableInt count = occurrences.get(key);
  6056.             if (count != null) {
  6057.                 if (count.decrementAndGet() == 0) {
  6058.                     occurrences.remove(key);
  6059.                 }
  6060.                 toRemove.set(i);
  6061.             }
  6062.         }
  6063.         return (int[]) removeAt(array, toRemove);
  6064.     }

  6065.     /**
  6066.      * Removes occurrences of specified elements, in specified quantities,
  6067.      * from the specified array. All subsequent elements are shifted left.
  6068.      * For any element-to-be-removed specified in greater quantities than
  6069.      * contained in the original array, no change occurs beyond the
  6070.      * removal of the existing matching items.
  6071.      * <p>
  6072.      * This method returns a new array with the same elements of the input
  6073.      * array except for the earliest-encountered occurrences of the specified
  6074.      * elements. The component type of the returned array is always the same
  6075.      * as that of the input array.
  6076.      * </p>
  6077.      * <pre>
  6078.      * ArrayUtils.removeElements(null, 1, 2)      = null
  6079.      * ArrayUtils.removeElements([], 1, 2)        = []
  6080.      * ArrayUtils.removeElements([1], 2, 3)       = [1]
  6081.      * ArrayUtils.removeElements([1, 3], 1, 2)    = [3]
  6082.      * ArrayUtils.removeElements([1, 3, 1], 1)    = [3, 1]
  6083.      * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
  6084.      * </pre>
  6085.      *
  6086.      * @param array the input array, will not be modified, and may be {@code null}.
  6087.      * @param values  the values to be removed.
  6088.      * @return A new array containing the existing elements except the
  6089.      *         earliest-encountered occurrences of the specified elements.
  6090.      * @since 3.0.1
  6091.      */
  6092.     public static long[] removeElements(final long[] array, final long... values) {
  6093.         if (isEmpty(array) || isEmpty(values)) {
  6094.             return clone(array);
  6095.         }
  6096.         final HashMap<Long, MutableInt> occurrences = new HashMap<>(values.length);
  6097.         for (final long v : values) {
  6098.             increment(occurrences, Long.valueOf(v));
  6099.         }
  6100.         final BitSet toRemove = new BitSet();
  6101.         for (int i = 0; i < array.length; i++) {
  6102.             final long key = array[i];
  6103.             final MutableInt count = occurrences.get(key);
  6104.             if (count != null) {
  6105.                 if (count.decrementAndGet() == 0) {
  6106.                     occurrences.remove(key);
  6107.                 }
  6108.                 toRemove.set(i);
  6109.             }
  6110.         }
  6111.         return (long[]) removeAt(array, toRemove);
  6112.     }

  6113.     /**
  6114.      * Removes occurrences of specified elements, in specified quantities,
  6115.      * from the specified array. All subsequent elements are shifted left.
  6116.      * For any element-to-be-removed specified in greater quantities than
  6117.      * contained in the original array, no change occurs beyond the
  6118.      * removal of the existing matching items.
  6119.      * <p>
  6120.      * This method returns a new array with the same elements of the input
  6121.      * array except for the earliest-encountered occurrences of the specified
  6122.      * elements. The component type of the returned array is always the same
  6123.      * as that of the input array.
  6124.      * </p>
  6125.      * <pre>
  6126.      * ArrayUtils.removeElements(null, 1, 2)      = null
  6127.      * ArrayUtils.removeElements([], 1, 2)        = []
  6128.      * ArrayUtils.removeElements([1], 2, 3)       = [1]
  6129.      * ArrayUtils.removeElements([1, 3], 1, 2)    = [3]
  6130.      * ArrayUtils.removeElements([1, 3, 1], 1)    = [3, 1]
  6131.      * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
  6132.      * </pre>
  6133.      *
  6134.      * @param array the input array, will not be modified, and may be {@code null}.
  6135.      * @param values  the values to be removed.
  6136.      * @return A new array containing the existing elements except the
  6137.      *         earliest-encountered occurrences of the specified elements.
  6138.      * @since 3.0.1
  6139.      */
  6140.     public static short[] removeElements(final short[] array, final short... values) {
  6141.         if (isEmpty(array) || isEmpty(values)) {
  6142.             return clone(array);
  6143.         }
  6144.         final HashMap<Short, MutableInt> occurrences = new HashMap<>(values.length);
  6145.         for (final short v : values) {
  6146.             increment(occurrences, Short.valueOf(v));
  6147.         }
  6148.         final BitSet toRemove = new BitSet();
  6149.         for (int i = 0; i < array.length; i++) {
  6150.             final short key = array[i];
  6151.             final MutableInt count = occurrences.get(key);
  6152.             if (count != null) {
  6153.                 if (count.decrementAndGet() == 0) {
  6154.                     occurrences.remove(key);
  6155.                 }
  6156.                 toRemove.set(i);
  6157.             }
  6158.         }
  6159.         return (short[]) removeAt(array, toRemove);
  6160.     }

  6161.     /**
  6162.      * Removes occurrences of specified elements, in specified quantities,
  6163.      * from the specified array. All subsequent elements are shifted left.
  6164.      * For any element-to-be-removed specified in greater quantities than
  6165.      * contained in the original array, no change occurs beyond the
  6166.      * removal of the existing matching items.
  6167.      * <p>
  6168.      * This method returns a new array with the same elements of the input
  6169.      * array except for the earliest-encountered occurrences of the specified
  6170.      * elements. The component type of the returned array is always the same
  6171.      * as that of the input array.
  6172.      * </p>
  6173.      * <pre>
  6174.      * ArrayUtils.removeElements(null, "a", "b")            = null
  6175.      * ArrayUtils.removeElements([], "a", "b")              = []
  6176.      * ArrayUtils.removeElements(["a"], "b", "c")           = ["a"]
  6177.      * ArrayUtils.removeElements(["a", "b"], "a", "c")      = ["b"]
  6178.      * ArrayUtils.removeElements(["a", "b", "a"], "a")      = ["b", "a"]
  6179.      * ArrayUtils.removeElements(["a", "b", "a"], "a", "a") = ["b"]
  6180.      * </pre>
  6181.      *
  6182.      * @param <T> the component type of the array
  6183.      * @param array the input array, will not be modified, and may be {@code null}.
  6184.      * @param values  the values to be removed.
  6185.      * @return A new array containing the existing elements except the
  6186.      *         earliest-encountered occurrences of the specified elements.
  6187.      * @since 3.0.1
  6188.      */
  6189.     @SafeVarargs
  6190.     public static <T> T[] removeElements(final T[] array, final T... values) {
  6191.         if (isEmpty(array) || isEmpty(values)) {
  6192.             return clone(array);
  6193.         }
  6194.         final HashMap<T, MutableInt> occurrences = new HashMap<>(values.length);
  6195.         for (final T v : values) {
  6196.             increment(occurrences, v);
  6197.         }
  6198.         final BitSet toRemove = new BitSet();
  6199.         for (int i = 0; i < array.length; i++) {
  6200.             final T key = array[i];
  6201.             final MutableInt count = occurrences.get(key);
  6202.             if (count != null) {
  6203.                 if (count.decrementAndGet() == 0) {
  6204.                     occurrences.remove(key);
  6205.                 }
  6206.                 toRemove.set(i);
  6207.             }
  6208.         }
  6209.         @SuppressWarnings("unchecked") // removeAll() always creates an array of the same type as its input
  6210.         final T[] result = (T[]) removeAt(array, toRemove);
  6211.         return result;
  6212.     }

  6213.     /**
  6214.      * Reverses the order of the given array.
  6215.      * <p>
  6216.      * This method does nothing for a {@code null} input array.
  6217.      * </p>
  6218.      *
  6219.      * @param array  the array to reverse, may be {@code null}.
  6220.      */
  6221.     public static void reverse(final boolean[] array) {
  6222.         if (array == null) {
  6223.             return;
  6224.         }
  6225.         reverse(array, 0, array.length);
  6226.     }

  6227.     /**
  6228.      * Reverses the order of the given array in the given range.
  6229.      * <p>
  6230.      * This method does nothing for a {@code null} input array.
  6231.      * </p>
  6232.      *
  6233.      * @param array
  6234.      *            the array to reverse, may be {@code null}.
  6235.      * @param startIndexInclusive
  6236.      *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
  6237.      *            change.
  6238.      * @param endIndexExclusive
  6239.      *            elements up to endIndex-1 are reversed in the array. Undervalue (&lt; start index) results in no
  6240.      *            change. Overvalue (&gt;array.length) is demoted to array length.
  6241.      * @since 3.2
  6242.      */
  6243.     public static void reverse(final boolean[] array, final int startIndexInclusive, final int endIndexExclusive) {
  6244.         if (array == null) {
  6245.             return;
  6246.         }
  6247.         int i = Math.max(startIndexInclusive, 0);
  6248.         int j = Math.min(array.length, endIndexExclusive) - 1;
  6249.         boolean tmp;
  6250.         while (j > i) {
  6251.             tmp = array[j];
  6252.             array[j] = array[i];
  6253.             array[i] = tmp;
  6254.             j--;
  6255.             i++;
  6256.         }
  6257.     }

  6258.     /**
  6259.      * Reverses the order of the given array.
  6260.      * <p>
  6261.      * This method does nothing for a {@code null} input array.
  6262.      * </p>
  6263.      *
  6264.      * @param array  the array to reverse, may be {@code null}
  6265.      */
  6266.     public static void reverse(final byte[] array) {
  6267.         if (array != null) {
  6268.             reverse(array, 0, array.length);
  6269.         }
  6270.     }

  6271.     /**
  6272.      * Reverses the order of the given array in the given range.
  6273.      * <p>
  6274.      * This method does nothing for a {@code null} input array.
  6275.      * </p>
  6276.      *
  6277.      * @param array
  6278.      *            the array to reverse, may be {@code null}
  6279.      * @param startIndexInclusive
  6280.      *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
  6281.      *            change.
  6282.      * @param endIndexExclusive
  6283.      *            elements up to endIndex-1 are reversed in the array. Undervalue (&lt; start index) results in no
  6284.      *            change. Overvalue (&gt;array.length) is demoted to array length.
  6285.      * @since 3.2
  6286.      */
  6287.     public static void reverse(final byte[] array, final int startIndexInclusive, final int endIndexExclusive) {
  6288.         if (array == null) {
  6289.             return;
  6290.         }
  6291.         int i = Math.max(startIndexInclusive, 0);
  6292.         int j = Math.min(array.length, endIndexExclusive) - 1;
  6293.         byte tmp;
  6294.         while (j > i) {
  6295.             tmp = array[j];
  6296.             array[j] = array[i];
  6297.             array[i] = tmp;
  6298.             j--;
  6299.             i++;
  6300.         }
  6301.     }

  6302.     /**
  6303.      * Reverses the order of the given array.
  6304.      * <p>
  6305.      * This method does nothing for a {@code null} input array.
  6306.      * </p>
  6307.      *
  6308.      * @param array  the array to reverse, may be {@code null}
  6309.      */
  6310.     public static void reverse(final char[] array) {
  6311.         if (array != null) {
  6312.             reverse(array, 0, array.length);
  6313.         }
  6314.     }

  6315.     /**
  6316.      * Reverses the order of the given array in the given range.
  6317.      * <p>
  6318.      * This method does nothing for a {@code null} input array.
  6319.      * </p>
  6320.      *
  6321.      * @param array
  6322.      *            the array to reverse, may be {@code null}
  6323.      * @param startIndexInclusive
  6324.      *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
  6325.      *            change.
  6326.      * @param endIndexExclusive
  6327.      *            elements up to endIndex-1 are reversed in the array. Undervalue (&lt; start index) results in no
  6328.      *            change. Overvalue (&gt;array.length) is demoted to array length.
  6329.      * @since 3.2
  6330.      */
  6331.     public static void reverse(final char[] array, final int startIndexInclusive, final int endIndexExclusive) {
  6332.         if (array == null) {
  6333.             return;
  6334.         }
  6335.         int i = Math.max(startIndexInclusive, 0);
  6336.         int j = Math.min(array.length, endIndexExclusive) - 1;
  6337.         char tmp;
  6338.         while (j > i) {
  6339.             tmp = array[j];
  6340.             array[j] = array[i];
  6341.             array[i] = tmp;
  6342.             j--;
  6343.             i++;
  6344.         }
  6345.     }

  6346.     /**
  6347.      * Reverses the order of the given array.
  6348.      * <p>
  6349.      * This method does nothing for a {@code null} input array.
  6350.      * </p>
  6351.      *
  6352.      * @param array  the array to reverse, may be {@code null}
  6353.      */
  6354.     public static void reverse(final double[] array) {
  6355.         if (array != null) {
  6356.             reverse(array, 0, array.length);
  6357.         }
  6358.     }

  6359.     /**
  6360.      * Reverses the order of the given array in the given range.
  6361.      * <p>
  6362.      * This method does nothing for a {@code null} input array.
  6363.      * </p>
  6364.      *
  6365.      * @param array
  6366.      *            the array to reverse, may be {@code null}
  6367.      * @param startIndexInclusive
  6368.      *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
  6369.      *            change.
  6370.      * @param endIndexExclusive
  6371.      *            elements up to endIndex-1 are reversed in the array. Undervalue (&lt; start index) results in no
  6372.      *            change. Overvalue (&gt;array.length) is demoted to array length.
  6373.      * @since 3.2
  6374.      */
  6375.     public static void reverse(final double[] array, final int startIndexInclusive, final int endIndexExclusive) {
  6376.         if (array == null) {
  6377.             return;
  6378.         }
  6379.         int i = Math.max(startIndexInclusive, 0);
  6380.         int j = Math.min(array.length, endIndexExclusive) - 1;
  6381.         double tmp;
  6382.         while (j > i) {
  6383.             tmp = array[j];
  6384.             array[j] = array[i];
  6385.             array[i] = tmp;
  6386.             j--;
  6387.             i++;
  6388.         }
  6389.     }

  6390.     /**
  6391.      * Reverses the order of the given array.
  6392.      * <p>
  6393.      * This method does nothing for a {@code null} input array.
  6394.      * </p>
  6395.      *
  6396.      * @param array  the array to reverse, may be {@code null}.
  6397.      */
  6398.     public static void reverse(final float[] array) {
  6399.         if (array != null) {
  6400.             reverse(array, 0, array.length);
  6401.         }
  6402.     }

  6403.     /**
  6404.      * Reverses the order of the given array in the given range.
  6405.      * <p>
  6406.      * This method does nothing for a {@code null} input array.
  6407.      * </p>
  6408.      *
  6409.      * @param array
  6410.      *            the array to reverse, may be {@code null}.
  6411.      * @param startIndexInclusive
  6412.      *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
  6413.      *            change.
  6414.      * @param endIndexExclusive
  6415.      *            elements up to endIndex-1 are reversed in the array. Undervalue (&lt; start index) results in no
  6416.      *            change. Overvalue (&gt;array.length) is demoted to array length.
  6417.      * @since 3.2
  6418.      */
  6419.     public static void reverse(final float[] array, final int startIndexInclusive, final int endIndexExclusive) {
  6420.         if (array == null) {
  6421.             return;
  6422.         }
  6423.         int i = Math.max(startIndexInclusive, 0);
  6424.         int j = Math.min(array.length, endIndexExclusive) - 1;
  6425.         float tmp;
  6426.         while (j > i) {
  6427.             tmp = array[j];
  6428.             array[j] = array[i];
  6429.             array[i] = tmp;
  6430.             j--;
  6431.             i++;
  6432.         }
  6433.     }

  6434.     /**
  6435.      * Reverses the order of the given array.
  6436.      * <p>
  6437.      * This method does nothing for a {@code null} input array.
  6438.      * </p>
  6439.      *
  6440.      * @param array  the array to reverse, may be {@code null}.
  6441.      */
  6442.     public static void reverse(final int[] array) {
  6443.         if (array != null) {
  6444.             reverse(array, 0, array.length);
  6445.         }
  6446.     }

  6447.     /**
  6448.      * Reverses the order of the given array in the given range.
  6449.      * <p>
  6450.      * This method does nothing for a {@code null} input array.
  6451.      * </p>
  6452.      *
  6453.      * @param array
  6454.      *            the array to reverse, may be {@code null}.
  6455.      * @param startIndexInclusive
  6456.      *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
  6457.      *            change.
  6458.      * @param endIndexExclusive
  6459.      *            elements up to endIndex-1 are reversed in the array. Undervalue (&lt; start index) results in no
  6460.      *            change. Overvalue (&gt;array.length) is demoted to array length.
  6461.      * @since 3.2
  6462.      */
  6463.     public static void reverse(final int[] array, final int startIndexInclusive, final int endIndexExclusive) {
  6464.         if (array == null) {
  6465.             return;
  6466.         }
  6467.         int i = Math.max(startIndexInclusive, 0);
  6468.         int j = Math.min(array.length, endIndexExclusive) - 1;
  6469.         int tmp;
  6470.         while (j > i) {
  6471.             tmp = array[j];
  6472.             array[j] = array[i];
  6473.             array[i] = tmp;
  6474.             j--;
  6475.             i++;
  6476.         }
  6477.     }

  6478.     /**
  6479.      * Reverses the order of the given array.
  6480.      * <p>
  6481.      * This method does nothing for a {@code null} input array.
  6482.      * </p>
  6483.      *
  6484.      * @param array  the array to reverse, may be {@code null}.
  6485.      */
  6486.     public static void reverse(final long[] array) {
  6487.         if (array != null) {
  6488.             reverse(array, 0, array.length);
  6489.         }
  6490.     }

  6491.     /**
  6492.      * Reverses the order of the given array in the given range.
  6493.      * <p>
  6494.      * This method does nothing for a {@code null} input array.
  6495.      * </p>
  6496.      *
  6497.      * @param array
  6498.      *            the array to reverse, may be {@code null}.
  6499.      * @param startIndexInclusive
  6500.      *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
  6501.      *            change.
  6502.      * @param endIndexExclusive
  6503.      *            elements up to endIndex-1 are reversed in the array. Undervalue (&lt; start index) results in no
  6504.      *            change. Overvalue (&gt;array.length) is demoted to array length.
  6505.      * @since 3.2
  6506.      */
  6507.     public static void reverse(final long[] array, final int startIndexInclusive, final int endIndexExclusive) {
  6508.         if (array == null) {
  6509.             return;
  6510.         }
  6511.         int i = Math.max(startIndexInclusive, 0);
  6512.         int j = Math.min(array.length, endIndexExclusive) - 1;
  6513.         long tmp;
  6514.         while (j > i) {
  6515.             tmp = array[j];
  6516.             array[j] = array[i];
  6517.             array[i] = tmp;
  6518.             j--;
  6519.             i++;
  6520.         }
  6521.     }

  6522.     /**
  6523.      * Reverses the order of the given array.
  6524.      * <p>
  6525.      * There is no special handling for multi-dimensional arrays.
  6526.      * </p>
  6527.      * <p>
  6528.      * This method does nothing for a {@code null} input array.
  6529.      * </p>
  6530.      *
  6531.      * @param array  the array to reverse, may be {@code null}.
  6532.      */
  6533.     public static void reverse(final Object[] array) {
  6534.         if (array != null) {
  6535.             reverse(array, 0, array.length);
  6536.         }
  6537.     }

  6538.     /**
  6539.      * Reverses the order of the given array in the given range.
  6540.      * <p>
  6541.      * This method does nothing for a {@code null} input array.
  6542.      * </p>
  6543.      *
  6544.      * @param array
  6545.      *            the array to reverse, may be {@code null}.
  6546.      * @param startIndexInclusive
  6547.      *            the starting index. Under value (&lt;0) is promoted to 0, over value (&gt;array.length) results in no
  6548.      *            change.
  6549.      * @param endIndexExclusive
  6550.      *            elements up to endIndex-1 are reversed in the array. Under value (&lt; start index) results in no
  6551.      *            change. Over value (&gt;array.length) is demoted to array length.
  6552.      * @since 3.2
  6553.      */
  6554.     public static void reverse(final Object[] array, final int startIndexInclusive, final int endIndexExclusive) {
  6555.         if (array == null) {
  6556.             return;
  6557.         }
  6558.         int i = Math.max(startIndexInclusive, 0);
  6559.         int j = Math.min(array.length, endIndexExclusive) - 1;
  6560.         Object tmp;
  6561.         while (j > i) {
  6562.             tmp = array[j];
  6563.             array[j] = array[i];
  6564.             array[i] = tmp;
  6565.             j--;
  6566.             i++;
  6567.         }
  6568.     }

  6569.     /**
  6570.      * Reverses the order of the given array.
  6571.      * <p>
  6572.      * This method does nothing for a {@code null} input array.
  6573.      * </p>
  6574.      *
  6575.      * @param array  the array to reverse, may be {@code null}.
  6576.      */
  6577.     public static void reverse(final short[] array) {
  6578.         if (array != null) {
  6579.             reverse(array, 0, array.length);
  6580.         }
  6581.     }

  6582.     /**
  6583.      * Reverses the order of the given array in the given range.
  6584.      * <p>
  6585.      * This method does nothing for a {@code null} input array.
  6586.      * </p>
  6587.      *
  6588.      * @param array
  6589.      *            the array to reverse, may be {@code null}.
  6590.      * @param startIndexInclusive
  6591.      *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
  6592.      *            change.
  6593.      * @param endIndexExclusive
  6594.      *            elements up to endIndex-1 are reversed in the array. Undervalue (&lt; start index) results in no
  6595.      *            change. Overvalue (&gt;array.length) is demoted to array length.
  6596.      * @since 3.2
  6597.      */
  6598.     public static void reverse(final short[] array, final int startIndexInclusive, final int endIndexExclusive) {
  6599.         if (array == null) {
  6600.             return;
  6601.         }
  6602.         int i = Math.max(startIndexInclusive, 0);
  6603.         int j = Math.min(array.length, endIndexExclusive) - 1;
  6604.         short tmp;
  6605.         while (j > i) {
  6606.             tmp = array[j];
  6607.             array[j] = array[i];
  6608.             array[i] = tmp;
  6609.             j--;
  6610.             i++;
  6611.         }
  6612.     }

  6613.     /**
  6614.      * Sets all elements of the specified array, using the provided generator supplier to compute each element.
  6615.      * <p>
  6616.      * If the generator supplier throws an exception, it is relayed to the caller and the array is left in an indeterminate
  6617.      * state.
  6618.      * </p>
  6619.      *
  6620.      * @param <T> type of elements of the array, may be {@code null}.
  6621.      * @param array array to be initialized, may be {@code null}.
  6622.      * @param generator a function accepting an index and producing the desired value for that position.
  6623.      * @return the input array
  6624.      * @since 3.13.0
  6625.      */
  6626.     public static <T> T[] setAll(final T[] array, final IntFunction<? extends T> generator) {
  6627.         if (array != null && generator != null) {
  6628.             Arrays.setAll(array, generator);
  6629.         }
  6630.         return array;
  6631.     }

  6632.     /**
  6633.      * Sets all elements of the specified array, using the provided generator supplier to compute each element.
  6634.      * <p>
  6635.      * If the generator supplier throws an exception, it is relayed to the caller and the array is left in an indeterminate
  6636.      * state.
  6637.      * </p>
  6638.      *
  6639.      * @param <T> type of elements of the array, may be {@code null}.
  6640.      * @param array array to be initialized, may be {@code null}.
  6641.      * @param generator a function accepting an index and producing the desired value for that position.
  6642.      * @return the input array
  6643.      * @since 3.13.0
  6644.      */
  6645.     public static <T> T[] setAll(final T[] array, final Supplier<? extends T> generator) {
  6646.         if (array != null && generator != null) {
  6647.             for (int i = 0; i < array.length; i++) {
  6648.                 array[i] = generator.get();
  6649.             }
  6650.         }
  6651.         return array;
  6652.     }

  6653.     /**
  6654.      * Shifts the order of the given boolean array.
  6655.      *
  6656.      * <p>There is no special handling for multi-dimensional arrays. This method
  6657.      * does nothing for {@code null} or empty input arrays.</p>
  6658.      *
  6659.      * @param array  the array to shift, may be {@code null}.
  6660.      * @param offset
  6661.      *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
  6662.      *          rotate, than the effective offset is modulo the number of elements to rotate.
  6663.      * @since 3.5
  6664.      */
  6665.     public static void shift(final boolean[] array, final int offset) {
  6666.         if (array != null) {
  6667.             shift(array, 0, array.length, offset);
  6668.         }
  6669.     }

  6670.     /**
  6671.      * Shifts the order of a series of elements in the given boolean array.
  6672.      *
  6673.      * <p>There is no special handling for multi-dimensional arrays. This method
  6674.      * does nothing for {@code null} or empty input arrays.</p>
  6675.      *
  6676.      * @param array
  6677.      *            the array to shift, may be {@code null}.
  6678.      * @param startIndexInclusive
  6679.      *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
  6680.      *            change.
  6681.      * @param endIndexExclusive
  6682.      *            elements up to endIndex-1 are shifted in the array. Undervalue (&lt; start index) results in no
  6683.      *            change. Overvalue (&gt;array.length) is demoted to array length.
  6684.      * @param offset
  6685.      *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
  6686.      *          rotate, than the effective offset is modulo the number of elements to rotate.
  6687.      * @since 3.5
  6688.      */
  6689.     public static void shift(final boolean[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
  6690.         if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
  6691.             return;
  6692.         }
  6693.         startIndexInclusive = max0(startIndexInclusive);
  6694.         endIndexExclusive = Math.min(endIndexExclusive, array.length);
  6695.         int n = endIndexExclusive - startIndexInclusive;
  6696.         if (n <= 1) {
  6697.             return;
  6698.         }
  6699.         offset %= n;
  6700.         if (offset < 0) {
  6701.             offset += n;
  6702.         }
  6703.         // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
  6704.         // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
  6705.         while (n > 1 && offset > 0) {
  6706.             final int nOffset = n - offset;
  6707.             if (offset > nOffset) {
  6708.                 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset,  nOffset);
  6709.                 n = offset;
  6710.                 offset -= nOffset;
  6711.             } else if (offset < nOffset) {
  6712.                 swap(array, startIndexInclusive, startIndexInclusive + nOffset,  offset);
  6713.                 startIndexInclusive += offset;
  6714.                 n = nOffset;
  6715.             } else {
  6716.                 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
  6717.                 break;
  6718.             }
  6719.         }
  6720.     }

  6721.     /**
  6722.      * Shifts the order of the given byte array.
  6723.      *
  6724.      * <p>There is no special handling for multi-dimensional arrays. This method
  6725.      * does nothing for {@code null} or empty input arrays.</p>
  6726.      *
  6727.      * @param array  the array to shift, may be {@code null}.
  6728.      * @param offset
  6729.      *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
  6730.      *          rotate, than the effective offset is modulo the number of elements to rotate.
  6731.      * @since 3.5
  6732.      */
  6733.     public static void shift(final byte[] array, final int offset) {
  6734.         if (array != null) {
  6735.             shift(array, 0, array.length, offset);
  6736.         }
  6737.     }

  6738.     /**
  6739.      * Shifts the order of a series of elements in the given byte array.
  6740.      *
  6741.      * <p>There is no special handling for multi-dimensional arrays. This method
  6742.      * does nothing for {@code null} or empty input arrays.</p>
  6743.      *
  6744.      * @param array
  6745.      *            the array to shift, may be {@code null}.
  6746.      * @param startIndexInclusive
  6747.      *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
  6748.      *            change.
  6749.      * @param endIndexExclusive
  6750.      *            elements up to endIndex-1 are shifted in the array. Undervalue (&lt; start index) results in no
  6751.      *            change. Overvalue (&gt;array.length) is demoted to array length.
  6752.      * @param offset
  6753.      *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
  6754.      *          rotate, than the effective offset is modulo the number of elements to rotate.
  6755.      * @since 3.5
  6756.      */
  6757.     public static void shift(final byte[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
  6758.         if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
  6759.             return;
  6760.         }
  6761.         startIndexInclusive = max0(startIndexInclusive);
  6762.         endIndexExclusive = Math.min(endIndexExclusive, array.length);
  6763.         int n = endIndexExclusive - startIndexInclusive;
  6764.         if (n <= 1) {
  6765.             return;
  6766.         }
  6767.         offset %= n;
  6768.         if (offset < 0) {
  6769.             offset += n;
  6770.         }
  6771.         // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
  6772.         // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
  6773.         while (n > 1 && offset > 0) {
  6774.             final int nOffset = n - offset;
  6775.             if (offset > nOffset) {
  6776.                 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset,  nOffset);
  6777.                 n = offset;
  6778.                 offset -= nOffset;
  6779.             } else if (offset < nOffset) {
  6780.                 swap(array, startIndexInclusive, startIndexInclusive + nOffset,  offset);
  6781.                 startIndexInclusive += offset;
  6782.                 n = nOffset;
  6783.             } else {
  6784.                 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
  6785.                 break;
  6786.             }
  6787.         }
  6788.     }

  6789.     /**
  6790.      * Shifts the order of the given char array.
  6791.      *
  6792.      * <p>There is no special handling for multi-dimensional arrays. This method
  6793.      * does nothing for {@code null} or empty input arrays.</p>
  6794.      *
  6795.      * @param array  the array to shift, may be {@code null}.
  6796.      * @param offset
  6797.      *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
  6798.      *          rotate, than the effective offset is modulo the number of elements to rotate.
  6799.      * @since 3.5
  6800.      */
  6801.     public static void shift(final char[] array, final int offset) {
  6802.         if (array != null) {
  6803.             shift(array, 0, array.length, offset);
  6804.         }
  6805.     }

  6806.     /**
  6807.      * Shifts the order of a series of elements in the given char array.
  6808.      *
  6809.      * <p>There is no special handling for multi-dimensional arrays. This method
  6810.      * does nothing for {@code null} or empty input arrays.</p>
  6811.      *
  6812.      * @param array
  6813.      *            the array to shift, may be {@code null}.
  6814.      * @param startIndexInclusive
  6815.      *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
  6816.      *            change.
  6817.      * @param endIndexExclusive
  6818.      *            elements up to endIndex-1 are shifted in the array. Undervalue (&lt; start index) results in no
  6819.      *            change. Overvalue (&gt;array.length) is demoted to array length.
  6820.      * @param offset
  6821.      *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
  6822.      *          rotate, than the effective offset is modulo the number of elements to rotate.
  6823.      * @since 3.5
  6824.      */
  6825.     public static void shift(final char[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
  6826.         if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
  6827.             return;
  6828.         }
  6829.         startIndexInclusive = max0(startIndexInclusive);
  6830.         endIndexExclusive = Math.min(endIndexExclusive, array.length);
  6831.         int n = endIndexExclusive - startIndexInclusive;
  6832.         if (n <= 1) {
  6833.             return;
  6834.         }
  6835.         offset %= n;
  6836.         if (offset < 0) {
  6837.             offset += n;
  6838.         }
  6839.         // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
  6840.         // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
  6841.         while (n > 1 && offset > 0) {
  6842.             final int nOffset = n - offset;
  6843.             if (offset > nOffset) {
  6844.                 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset,  nOffset);
  6845.                 n = offset;
  6846.                 offset -= nOffset;
  6847.             } else if (offset < nOffset) {
  6848.                 swap(array, startIndexInclusive, startIndexInclusive + nOffset,  offset);
  6849.                 startIndexInclusive += offset;
  6850.                 n = nOffset;
  6851.             } else {
  6852.                 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
  6853.                 break;
  6854.             }
  6855.         }
  6856.     }

  6857.     /**
  6858.      * Shifts the order of the given double array.
  6859.      *
  6860.      * <p>There is no special handling for multi-dimensional arrays. This method
  6861.      * does nothing for {@code null} or empty input arrays.</p>
  6862.      *
  6863.      * @param array  the array to shift, may be {@code null}.
  6864.      * @param offset
  6865.      *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
  6866.      *          rotate, than the effective offset is modulo the number of elements to rotate.
  6867.      * @since 3.5
  6868.      */
  6869.     public static void shift(final double[] array, final int offset) {
  6870.         if (array != null) {
  6871.             shift(array, 0, array.length, offset);
  6872.         }
  6873.     }

  6874.     /**
  6875.      * Shifts the order of a series of elements in the given double array.
  6876.      *
  6877.      * <p>There is no special handling for multi-dimensional arrays. This method
  6878.      * does nothing for {@code null} or empty input arrays.</p>
  6879.      *
  6880.      * @param array
  6881.      *            the array to shift, may be {@code null}.
  6882.      * @param startIndexInclusive
  6883.      *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
  6884.      *            change.
  6885.      * @param endIndexExclusive
  6886.      *            elements up to endIndex-1 are shifted in the array. Undervalue (&lt; start index) results in no
  6887.      *            change. Overvalue (&gt;array.length) is demoted to array length.
  6888.      * @param offset
  6889.      *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
  6890.      *          rotate, than the effective offset is modulo the number of elements to rotate.
  6891.      * @since 3.5
  6892.      */
  6893.     public static void shift(final double[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
  6894.         if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
  6895.             return;
  6896.         }
  6897.         startIndexInclusive = max0(startIndexInclusive);
  6898.         endIndexExclusive = Math.min(endIndexExclusive, array.length);
  6899.         int n = endIndexExclusive - startIndexInclusive;
  6900.         if (n <= 1) {
  6901.             return;
  6902.         }
  6903.         offset %= n;
  6904.         if (offset < 0) {
  6905.             offset += n;
  6906.         }
  6907.         // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
  6908.         // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
  6909.         while (n > 1 && offset > 0) {
  6910.             final int nOffset = n - offset;
  6911.             if (offset > nOffset) {
  6912.                 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset,  nOffset);
  6913.                 n = offset;
  6914.                 offset -= nOffset;
  6915.             } else if (offset < nOffset) {
  6916.                 swap(array, startIndexInclusive, startIndexInclusive + nOffset,  offset);
  6917.                 startIndexInclusive += offset;
  6918.                 n = nOffset;
  6919.             } else {
  6920.                 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
  6921.                 break;
  6922.             }
  6923.         }
  6924.     }

  6925.     /**
  6926.      * Shifts the order of the given float array.
  6927.      *
  6928.      * <p>There is no special handling for multi-dimensional arrays. This method
  6929.      * does nothing for {@code null} or empty input arrays.</p>
  6930.      *
  6931.      * @param array  the array to shift, may be {@code null}.
  6932.      * @param offset
  6933.      *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
  6934.      *          rotate, than the effective offset is modulo the number of elements to rotate.
  6935.      * @since 3.5
  6936.      */
  6937.     public static void shift(final float[] array, final int offset) {
  6938.         if (array != null) {
  6939.             shift(array, 0, array.length, offset);
  6940.         }
  6941.     }

  6942.     /**
  6943.      * Shifts the order of a series of elements in the given float array.
  6944.      *
  6945.      * <p>There is no special handling for multi-dimensional arrays. This method
  6946.      * does nothing for {@code null} or empty input arrays.</p>
  6947.      *
  6948.      * @param array
  6949.      *            the array to shift, may be {@code null}.
  6950.      * @param startIndexInclusive
  6951.      *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
  6952.      *            change.
  6953.      * @param endIndexExclusive
  6954.      *            elements up to endIndex-1 are shifted in the array. Undervalue (&lt; start index) results in no
  6955.      *            change. Overvalue (&gt;array.length) is demoted to array length.
  6956.      * @param offset
  6957.      *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
  6958.      *          rotate, than the effective offset is modulo the number of elements to rotate.
  6959.      * @since 3.5
  6960.      */
  6961.     public static void shift(final float[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
  6962.         if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
  6963.             return;
  6964.         }
  6965.         startIndexInclusive = max0(startIndexInclusive);
  6966.         endIndexExclusive = Math.min(endIndexExclusive, array.length);
  6967.         int n = endIndexExclusive - startIndexInclusive;
  6968.         if (n <= 1) {
  6969.             return;
  6970.         }
  6971.         offset %= n;
  6972.         if (offset < 0) {
  6973.             offset += n;
  6974.         }
  6975.         // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
  6976.         // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
  6977.         while (n > 1 && offset > 0) {
  6978.             final int nOffset = n - offset;
  6979.             if (offset > nOffset) {
  6980.                 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset,  nOffset);
  6981.                 n = offset;
  6982.                 offset -= nOffset;
  6983.             } else if (offset < nOffset) {
  6984.                 swap(array, startIndexInclusive, startIndexInclusive + nOffset,  offset);
  6985.                 startIndexInclusive += offset;
  6986.                 n = nOffset;
  6987.             } else {
  6988.                 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
  6989.                 break;
  6990.             }
  6991.         }
  6992.     }

  6993.     /**
  6994.      * Shifts the order of the given int array.
  6995.      *
  6996.      * <p>There is no special handling for multi-dimensional arrays. This method
  6997.      * does nothing for {@code null} or empty input arrays.</p>
  6998.      *
  6999.      * @param array  the array to shift, may be {@code null}.
  7000.      * @param offset
  7001.      *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
  7002.      *          rotate, than the effective offset is modulo the number of elements to rotate.
  7003.      * @since 3.5
  7004.      */
  7005.     public static void shift(final int[] array, final int offset) {
  7006.         if (array != null) {
  7007.             shift(array, 0, array.length, offset);
  7008.         }
  7009.     }

  7010.     /**
  7011.      * Shifts the order of a series of elements in the given int array.
  7012.      *
  7013.      * <p>There is no special handling for multi-dimensional arrays. This method
  7014.      * does nothing for {@code null} or empty input arrays.</p>
  7015.      *
  7016.      * @param array
  7017.      *            the array to shift, may be {@code null}.
  7018.      * @param startIndexInclusive
  7019.      *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
  7020.      *            change.
  7021.      * @param endIndexExclusive
  7022.      *            elements up to endIndex-1 are shifted in the array. Undervalue (&lt; start index) results in no
  7023.      *            change. Overvalue (&gt;array.length) is demoted to array length.
  7024.      * @param offset
  7025.      *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
  7026.      *          rotate, than the effective offset is modulo the number of elements to rotate.
  7027.      * @since 3.5
  7028.      */
  7029.     public static void shift(final int[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
  7030.         if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
  7031.             return;
  7032.         }
  7033.         startIndexInclusive = max0(startIndexInclusive);
  7034.         endIndexExclusive = Math.min(endIndexExclusive, array.length);
  7035.         int n = endIndexExclusive - startIndexInclusive;
  7036.         if (n <= 1) {
  7037.             return;
  7038.         }
  7039.         offset %= n;
  7040.         if (offset < 0) {
  7041.             offset += n;
  7042.         }
  7043.         // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
  7044.         // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
  7045.         while (n > 1 && offset > 0) {
  7046.             final int nOffset = n - offset;
  7047.             if (offset > nOffset) {
  7048.                 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset,  nOffset);
  7049.                 n = offset;
  7050.                 offset -= nOffset;
  7051.             } else if (offset < nOffset) {
  7052.                 swap(array, startIndexInclusive, startIndexInclusive + nOffset,  offset);
  7053.                 startIndexInclusive += offset;
  7054.                 n = nOffset;
  7055.             } else {
  7056.                 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
  7057.                 break;
  7058.             }
  7059.         }
  7060.     }

  7061.     /**
  7062.      * Shifts the order of the given long array.
  7063.      *
  7064.      * <p>There is no special handling for multi-dimensional arrays. This method
  7065.      * does nothing for {@code null} or empty input arrays.</p>
  7066.      *
  7067.      * @param array  the array to shift, may be {@code null}.
  7068.      * @param offset
  7069.      *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
  7070.      *          rotate, than the effective offset is modulo the number of elements to rotate.
  7071.      * @since 3.5
  7072.      */
  7073.     public static void shift(final long[] array, final int offset) {
  7074.         if (array != null) {
  7075.             shift(array, 0, array.length, offset);
  7076.         }
  7077.     }

  7078.     /**
  7079.      * Shifts the order of a series of elements in the given long array.
  7080.      *
  7081.      * <p>There is no special handling for multi-dimensional arrays. This method
  7082.      * does nothing for {@code null} or empty input arrays.</p>
  7083.      *
  7084.      * @param array
  7085.      *            the array to shift, may be {@code null}.
  7086.      * @param startIndexInclusive
  7087.      *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
  7088.      *            change.
  7089.      * @param endIndexExclusive
  7090.      *            elements up to endIndex-1 are shifted in the array. Undervalue (&lt; start index) results in no
  7091.      *            change. Overvalue (&gt;array.length) is demoted to array length.
  7092.      * @param offset
  7093.      *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
  7094.      *          rotate, than the effective offset is modulo the number of elements to rotate.
  7095.      * @since 3.5
  7096.      */
  7097.     public static void shift(final long[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
  7098.         if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
  7099.             return;
  7100.         }
  7101.         startIndexInclusive = max0(startIndexInclusive);
  7102.         endIndexExclusive = Math.min(endIndexExclusive, array.length);
  7103.         int n = endIndexExclusive - startIndexInclusive;
  7104.         if (n <= 1) {
  7105.             return;
  7106.         }
  7107.         offset %= n;
  7108.         if (offset < 0) {
  7109.             offset += n;
  7110.         }
  7111.         // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
  7112.         // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
  7113.         while (n > 1 && offset > 0) {
  7114.             final int nOffset = n - offset;
  7115.             if (offset > nOffset) {
  7116.                 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset,  nOffset);
  7117.                 n = offset;
  7118.                 offset -= nOffset;
  7119.             } else if (offset < nOffset) {
  7120.                 swap(array, startIndexInclusive, startIndexInclusive + nOffset,  offset);
  7121.                 startIndexInclusive += offset;
  7122.                 n = nOffset;
  7123.             } else {
  7124.                 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
  7125.                 break;
  7126.             }
  7127.         }
  7128.     }

  7129.     /**
  7130.      * Shifts the order of the given array.
  7131.      *
  7132.      * <p>There is no special handling for multi-dimensional arrays. This method
  7133.      * does nothing for {@code null} or empty input arrays.</p>
  7134.      *
  7135.      * @param array  the array to shift, may be {@code null}.
  7136.      * @param offset
  7137.      *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
  7138.      *          rotate, than the effective offset is modulo the number of elements to rotate.
  7139.      * @since 3.5
  7140.      */
  7141.     public static void shift(final Object[] array, final int offset) {
  7142.         if (array != null) {
  7143.             shift(array, 0, array.length, offset);
  7144.         }
  7145.     }

  7146.     /**
  7147.      * Shifts the order of a series of elements in the given array.
  7148.      *
  7149.      * <p>There is no special handling for multi-dimensional arrays. This method
  7150.      * does nothing for {@code null} or empty input arrays.</p>
  7151.      *
  7152.      * @param array
  7153.      *            the array to shift, may be {@code null}.
  7154.      * @param startIndexInclusive
  7155.      *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
  7156.      *            change.
  7157.      * @param endIndexExclusive
  7158.      *            elements up to endIndex-1 are shifted in the array. Undervalue (&lt; start index) results in no
  7159.      *            change. Overvalue (&gt;array.length) is demoted to array length.
  7160.      * @param offset
  7161.      *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
  7162.      *          rotate, than the effective offset is modulo the number of elements to rotate.
  7163.      * @since 3.5
  7164.      */
  7165.     public static void shift(final Object[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
  7166.         if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
  7167.             return;
  7168.         }
  7169.         startIndexInclusive = max0(startIndexInclusive);
  7170.         endIndexExclusive = Math.min(endIndexExclusive, array.length);
  7171.         int n = endIndexExclusive - startIndexInclusive;
  7172.         if (n <= 1) {
  7173.             return;
  7174.         }
  7175.         offset %= n;
  7176.         if (offset < 0) {
  7177.             offset += n;
  7178.         }
  7179.         // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
  7180.         // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
  7181.         while (n > 1 && offset > 0) {
  7182.             final int nOffset = n - offset;
  7183.             if (offset > nOffset) {
  7184.                 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset,  nOffset);
  7185.                 n = offset;
  7186.                 offset -= nOffset;
  7187.             } else if (offset < nOffset) {
  7188.                 swap(array, startIndexInclusive, startIndexInclusive + nOffset,  offset);
  7189.                 startIndexInclusive += offset;
  7190.                 n = nOffset;
  7191.             } else {
  7192.                 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
  7193.                 break;
  7194.             }
  7195.         }
  7196.     }

  7197.     /**
  7198.      * Shifts the order of the given short array.
  7199.      *
  7200.      * <p>There is no special handling for multi-dimensional arrays. This method
  7201.      * does nothing for {@code null} or empty input arrays.</p>
  7202.      *
  7203.      * @param array  the array to shift, may be {@code null}.
  7204.      * @param offset
  7205.      *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
  7206.      *          rotate, than the effective offset is modulo the number of elements to rotate.
  7207.      * @since 3.5
  7208.      */
  7209.     public static void shift(final short[] array, final int offset) {
  7210.         if (array != null) {
  7211.             shift(array, 0, array.length, offset);
  7212.         }
  7213.     }

  7214.     /**
  7215.      * Shifts the order of a series of elements in the given short array.
  7216.      *
  7217.      * <p>There is no special handling for multi-dimensional arrays. This method
  7218.      * does nothing for {@code null} or empty input arrays.</p>
  7219.      *
  7220.      * @param array
  7221.      *            the array to shift, may be {@code null}.
  7222.      * @param startIndexInclusive
  7223.      *            the starting index. Undervalue (&lt;0) is promoted to 0, overvalue (&gt;array.length) results in no
  7224.      *            change.
  7225.      * @param endIndexExclusive
  7226.      *            elements up to endIndex-1 are shifted in the array. Undervalue (&lt; start index) results in no
  7227.      *            change. Overvalue (&gt;array.length) is demoted to array length.
  7228.      * @param offset
  7229.      *          The number of positions to rotate the elements.  If the offset is larger than the number of elements to
  7230.      *          rotate, than the effective offset is modulo the number of elements to rotate.
  7231.      * @since 3.5
  7232.      */
  7233.     public static void shift(final short[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
  7234.         if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
  7235.             return;
  7236.         }
  7237.         startIndexInclusive = max0(startIndexInclusive);
  7238.         endIndexExclusive = Math.min(endIndexExclusive, array.length);
  7239.         int n = endIndexExclusive - startIndexInclusive;
  7240.         if (n <= 1) {
  7241.             return;
  7242.         }
  7243.         offset %= n;
  7244.         if (offset < 0) {
  7245.             offset += n;
  7246.         }
  7247.         // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
  7248.         // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
  7249.         while (n > 1 && offset > 0) {
  7250.             final int nOffset = n - offset;
  7251.             if (offset > nOffset) {
  7252.                 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset,  nOffset);
  7253.                 n = offset;
  7254.                 offset -= nOffset;
  7255.             } else if (offset < nOffset) {
  7256.                 swap(array, startIndexInclusive, startIndexInclusive + nOffset,  offset);
  7257.                 startIndexInclusive += offset;
  7258.                 n = nOffset;
  7259.             } else {
  7260.                 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
  7261.                 break;
  7262.             }
  7263.         }
  7264.     }

  7265.     /**
  7266.      * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
  7267.      * algorithm</a>.
  7268.      * <p>
  7269.      * This method uses the current {@link ThreadLocalRandom} as its random number generator.
  7270.      * </p>
  7271.      * <p>
  7272.      * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
  7273.      * with a {@link SecureRandom} argument.
  7274.      * </p>
  7275.      *
  7276.      * @param array the array to shuffle.
  7277.      * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
  7278.      * @since 3.6
  7279.      */
  7280.     public static void shuffle(final boolean[] array) {
  7281.         shuffle(array, random());
  7282.     }

  7283.     /**
  7284.      * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
  7285.      * algorithm</a>.
  7286.      *
  7287.      * @param array  the array to shuffle
  7288.      * @param random the source of randomness used to permute the elements
  7289.      * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
  7290.      * @since 3.6
  7291.      */
  7292.     public static void shuffle(final boolean[] array, final Random random) {
  7293.         for (int i = array.length; i > 1; i--) {
  7294.             swap(array, i - 1, random.nextInt(i), 1);
  7295.         }
  7296.     }

  7297.     /**
  7298.      * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
  7299.      * algorithm</a>.
  7300.      * <p>
  7301.      * This method uses the current {@link ThreadLocalRandom} as its random number generator.
  7302.      * </p>
  7303.      * <p>
  7304.      * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
  7305.      * with a {@link SecureRandom} argument.
  7306.      * </p>
  7307.      *
  7308.      * @param array the array to shuffle.
  7309.      * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
  7310.      * @since 3.6
  7311.      */
  7312.     public static void shuffle(final byte[] array) {
  7313.         shuffle(array, random());
  7314.     }

  7315.     /**
  7316.      * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
  7317.      * algorithm</a>.
  7318.      *
  7319.      * @param array  the array to shuffle
  7320.      * @param random the source of randomness used to permute the elements
  7321.      * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
  7322.      * @since 3.6
  7323.      */
  7324.     public static void shuffle(final byte[] array, final Random random) {
  7325.         for (int i = array.length; i > 1; i--) {
  7326.             swap(array, i - 1, random.nextInt(i), 1);
  7327.         }
  7328.     }

  7329.     /**
  7330.      * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
  7331.      * algorithm</a>.
  7332.      * <p>
  7333.      * This method uses the current {@link ThreadLocalRandom} as its random number generator.
  7334.      * </p>
  7335.      * <p>
  7336.      * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
  7337.      * with a {@link SecureRandom} argument.
  7338.      * </p>
  7339.      *
  7340.      * @param array the array to shuffle.
  7341.      * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
  7342.      * @since 3.6
  7343.      */
  7344.     public static void shuffle(final char[] array) {
  7345.         shuffle(array, random());
  7346.     }

  7347.     /**
  7348.      * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
  7349.      * algorithm</a>.
  7350.      *
  7351.      * @param array  the array to shuffle
  7352.      * @param random the source of randomness used to permute the elements
  7353.      * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
  7354.      * @since 3.6
  7355.      */
  7356.     public static void shuffle(final char[] array, final Random random) {
  7357.         for (int i = array.length; i > 1; i--) {
  7358.             swap(array, i - 1, random.nextInt(i), 1);
  7359.         }
  7360.     }

  7361.     /**
  7362.      * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
  7363.      * algorithm</a>.
  7364.      * <p>
  7365.      * This method uses the current {@link ThreadLocalRandom} as its random number generator.
  7366.      * </p>
  7367.      * <p>
  7368.      * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
  7369.      * with a {@link SecureRandom} argument.
  7370.      * </p>
  7371.      *
  7372.      * @param array the array to shuffle.
  7373.      * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
  7374.      * @since 3.6
  7375.      */
  7376.     public static void shuffle(final double[] array) {
  7377.         shuffle(array, random());
  7378.     }

  7379.     /**
  7380.      * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
  7381.      * algorithm</a>.
  7382.      *
  7383.      * @param array  the array to shuffle
  7384.      * @param random the source of randomness used to permute the elements
  7385.      * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
  7386.      * @since 3.6
  7387.      */
  7388.     public static void shuffle(final double[] array, final Random random) {
  7389.         for (int i = array.length; i > 1; i--) {
  7390.             swap(array, i - 1, random.nextInt(i), 1);
  7391.         }
  7392.     }

  7393.     /**
  7394.      * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
  7395.      * algorithm</a>.
  7396.      * <p>
  7397.      * This method uses the current {@link ThreadLocalRandom} as its random number generator.
  7398.      * </p>
  7399.      * <p>
  7400.      * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
  7401.      * with a {@link SecureRandom} argument.
  7402.      * </p>
  7403.      *
  7404.      * @param array the array to shuffle.
  7405.      * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
  7406.      * @since 3.6
  7407.      */
  7408.     public static void shuffle(final float[] array) {
  7409.         shuffle(array, random());
  7410.     }

  7411.     /**
  7412.      * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
  7413.      * algorithm</a>.
  7414.      *
  7415.      * @param array  the array to shuffle
  7416.      * @param random the source of randomness used to permute the elements
  7417.      * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
  7418.      * @since 3.6
  7419.      */
  7420.     public static void shuffle(final float[] array, final Random random) {
  7421.         for (int i = array.length; i > 1; i--) {
  7422.             swap(array, i - 1, random.nextInt(i), 1);
  7423.         }
  7424.     }

  7425.     /**
  7426.      * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
  7427.      * algorithm</a>.
  7428.      * <p>
  7429.      * This method uses the current {@link ThreadLocalRandom} as its random number generator.
  7430.      * </p>
  7431.      * <p>
  7432.      * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
  7433.      * with a {@link SecureRandom} argument.
  7434.      * </p>
  7435.      *
  7436.      * @param array the array to shuffle.
  7437.      * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
  7438.      * @since 3.6
  7439.      */
  7440.     public static void shuffle(final int[] array) {
  7441.         shuffle(array, random());
  7442.     }

  7443.     /**
  7444.      * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
  7445.      * algorithm</a>.
  7446.      *
  7447.      * @param array  the array to shuffle
  7448.      * @param random the source of randomness used to permute the elements
  7449.      * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
  7450.      * @since 3.6
  7451.      */
  7452.     public static void shuffle(final int[] array, final Random random) {
  7453.         for (int i = array.length; i > 1; i--) {
  7454.             swap(array, i - 1, random.nextInt(i), 1);
  7455.         }
  7456.     }

  7457.     /**
  7458.      * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
  7459.      * algorithm</a>.
  7460.      * <p>
  7461.      * This method uses the current {@link ThreadLocalRandom} as its random number generator.
  7462.      * </p>
  7463.      * <p>
  7464.      * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
  7465.      * with a {@link SecureRandom} argument.
  7466.      * </p>
  7467.      *
  7468.      * @param array the array to shuffle.
  7469.      * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
  7470.      * @since 3.6
  7471.      */
  7472.     public static void shuffle(final long[] array) {
  7473.         shuffle(array, random());
  7474.     }

  7475.     /**
  7476.      * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
  7477.      * algorithm</a>.
  7478.      *
  7479.      * @param array  the array to shuffle
  7480.      * @param random the source of randomness used to permute the elements
  7481.      * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
  7482.      * @since 3.6
  7483.      */
  7484.     public static void shuffle(final long[] array, final Random random) {
  7485.         for (int i = array.length; i > 1; i--) {
  7486.             swap(array, i - 1, random.nextInt(i), 1);
  7487.         }
  7488.     }

  7489.     /**
  7490.      * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
  7491.      * algorithm</a>.
  7492.      * <p>
  7493.      * This method uses the current {@link ThreadLocalRandom} as its random number generator.
  7494.      * </p>
  7495.      * <p>
  7496.      * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
  7497.      * with a {@link SecureRandom} argument.
  7498.      * </p>
  7499.      *
  7500.      * @param array the array to shuffle.
  7501.      * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
  7502.      * @since 3.6
  7503.      */
  7504.     public static void shuffle(final Object[] array) {
  7505.         shuffle(array, random());
  7506.     }

  7507.     /**
  7508.      * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
  7509.      * algorithm</a>.
  7510.      *
  7511.      * @param array  the array to shuffle
  7512.      * @param random the source of randomness used to permute the elements
  7513.      * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
  7514.      * @since 3.6
  7515.      */
  7516.     public static void shuffle(final Object[] array, final Random random) {
  7517.         for (int i = array.length; i > 1; i--) {
  7518.             swap(array, i - 1, random.nextInt(i), 1);
  7519.         }
  7520.     }

  7521.     /**
  7522.      * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
  7523.      * algorithm</a>.
  7524.      * <p>
  7525.      * This method uses the current {@link ThreadLocalRandom} as its random number generator.
  7526.      * </p>
  7527.      * <p>
  7528.      * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
  7529.      * with a {@link SecureRandom} argument.
  7530.      * </p>
  7531.      *
  7532.      * @param array the array to shuffle.
  7533.      * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
  7534.      * @since 3.6
  7535.      */
  7536.     public static void shuffle(final short[] array) {
  7537.         shuffle(array, random());
  7538.     }

  7539.     /**
  7540.      * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
  7541.      * algorithm</a>.
  7542.      *
  7543.      * @param array  the array to shuffle
  7544.      * @param random the source of randomness used to permute the elements
  7545.      * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
  7546.      * @since 3.6
  7547.      */
  7548.     public static void shuffle(final short[] array, final Random random) {
  7549.         for (int i = array.length; i > 1; i--) {
  7550.             swap(array, i - 1, random.nextInt(i), 1);
  7551.         }
  7552.     }

  7553.     /**
  7554.      * Tests whether the given data array starts with an expected array, for example, signature bytes.
  7555.      * <p>
  7556.      * If both arrays are null, the method returns true. The method return false when one array is null and the other not.
  7557.      * </p>
  7558.      *
  7559.      * @param data     The data to search, maybe larger than the expected data.
  7560.      * @param expected The expected data to find.
  7561.      * @return whether a match was found.
  7562.      * @since 3.18.0
  7563.      */
  7564.     public static boolean startsWith(final byte[] data, final byte[] expected) {
  7565.         if (data == expected) {
  7566.             return true;
  7567.         }
  7568.         if (data == null || expected == null) {
  7569.             return false;
  7570.         }
  7571.         final int dataLen = data.length;
  7572.         if (expected.length > dataLen) {
  7573.             return false;
  7574.         }
  7575.         if (expected.length == dataLen) {
  7576.             // delegate to Arrays.equals() which has optimizations on Java > 8
  7577.             return Arrays.equals(data, expected);
  7578.         }
  7579.         // Once we are on Java 9+ we can delegate to Arrays here as well (or not).
  7580.         for (int i = 0; i < expected.length; i++) {
  7581.             if (data[i] != expected[i]) {
  7582.                 return false;
  7583.             }
  7584.         }
  7585.         return true;
  7586.     }

  7587.     /**
  7588.      * Produces a new {@code boolean} array containing the elements
  7589.      * between the start and end indices.
  7590.      * <p>
  7591.      * The start index is inclusive, the end index exclusive.
  7592.      * Null array input produces null output.
  7593.      * </p>
  7594.      *
  7595.      * @param array  the array
  7596.      * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
  7597.      *      is promoted to 0, overvalue (&gt;array.length) results
  7598.      *      in an empty array.
  7599.      * @param endIndexExclusive  elements up to endIndex-1 are present in the
  7600.      *      returned subarray. Undervalue (&lt; startIndex) produces
  7601.      *      empty array, overvalue (&gt;array.length) is demoted to
  7602.      *      array length.
  7603.      * @return a new array containing the elements between
  7604.      *      the start and end indices.
  7605.      * @since 2.1
  7606.      * @see Arrays#copyOfRange(boolean[], int, int)
  7607.      */
  7608.     public static boolean[] subarray(final boolean[] array, int startIndexInclusive, int endIndexExclusive) {
  7609.         if (array == null) {
  7610.             return null;
  7611.         }
  7612.         startIndexInclusive = max0(startIndexInclusive);
  7613.         endIndexExclusive = Math.min(endIndexExclusive, array.length);
  7614.         final int newSize = endIndexExclusive - startIndexInclusive;
  7615.         if (newSize <= 0) {
  7616.             return EMPTY_BOOLEAN_ARRAY;
  7617.         }
  7618.         return arraycopy(array, startIndexInclusive, 0, newSize, boolean[]::new);
  7619.     }

  7620.     /**
  7621.      * Produces a new {@code byte} array containing the elements
  7622.      * between the start and end indices.
  7623.      * <p>
  7624.      * The start index is inclusive, the end index exclusive.
  7625.      * Null array input produces null output.
  7626.      * </p>
  7627.      *
  7628.      * @param array  the array
  7629.      * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
  7630.      *      is promoted to 0, overvalue (&gt;array.length) results
  7631.      *      in an empty array.
  7632.      * @param endIndexExclusive  elements up to endIndex-1 are present in the
  7633.      *      returned subarray. Undervalue (&lt; startIndex) produces
  7634.      *      empty array, overvalue (&gt;array.length) is demoted to
  7635.      *      array length.
  7636.      * @return a new array containing the elements between
  7637.      *      the start and end indices.
  7638.      * @since 2.1
  7639.      * @see Arrays#copyOfRange(byte[], int, int)
  7640.      */
  7641.     public static byte[] subarray(final byte[] array, int startIndexInclusive, int endIndexExclusive) {
  7642.         if (array == null) {
  7643.             return null;
  7644.         }
  7645.         startIndexInclusive = max0(startIndexInclusive);
  7646.         endIndexExclusive = Math.min(endIndexExclusive, array.length);
  7647.         final int newSize = endIndexExclusive - startIndexInclusive;
  7648.         if (newSize <= 0) {
  7649.             return EMPTY_BYTE_ARRAY;
  7650.         }
  7651.         return arraycopy(array, startIndexInclusive, 0, newSize, byte[]::new);
  7652.     }

  7653.     /**
  7654.      * Produces a new {@code char} array containing the elements
  7655.      * between the start and end indices.
  7656.      * <p>
  7657.      * The start index is inclusive, the end index exclusive.
  7658.      * Null array input produces null output.
  7659.      * </p>
  7660.      *
  7661.      * @param array  the array
  7662.      * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
  7663.      *      is promoted to 0, overvalue (&gt;array.length) results
  7664.      *      in an empty array.
  7665.      * @param endIndexExclusive  elements up to endIndex-1 are present in the
  7666.      *      returned subarray. Undervalue (&lt; startIndex) produces
  7667.      *      empty array, overvalue (&gt;array.length) is demoted to
  7668.      *      array length.
  7669.      * @return a new array containing the elements between
  7670.      *      the start and end indices.
  7671.      * @since 2.1
  7672.      * @see Arrays#copyOfRange(char[], int, int)
  7673.      */
  7674.     public static char[] subarray(final char[] array, int startIndexInclusive, int endIndexExclusive) {
  7675.         if (array == null) {
  7676.             return null;
  7677.         }
  7678.         startIndexInclusive = max0(startIndexInclusive);
  7679.         endIndexExclusive = Math.min(endIndexExclusive, array.length);
  7680.         final int newSize = endIndexExclusive - startIndexInclusive;
  7681.         if (newSize <= 0) {
  7682.             return EMPTY_CHAR_ARRAY;
  7683.         }
  7684.         return arraycopy(array, startIndexInclusive, 0, newSize, char[]::new);
  7685.     }

  7686.     /**
  7687.      * Produces a new {@code double} array containing the elements
  7688.      * between the start and end indices.
  7689.      * <p>
  7690.      * The start index is inclusive, the end index exclusive.
  7691.      * Null array input produces null output.
  7692.      * </p>
  7693.      *
  7694.      * @param array  the array
  7695.      * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
  7696.      *      is promoted to 0, overvalue (&gt;array.length) results
  7697.      *      in an empty array.
  7698.      * @param endIndexExclusive  elements up to endIndex-1 are present in the
  7699.      *      returned subarray. Undervalue (&lt; startIndex) produces
  7700.      *      empty array, overvalue (&gt;array.length) is demoted to
  7701.      *      array length.
  7702.      * @return a new array containing the elements between
  7703.      *      the start and end indices.
  7704.      * @since 2.1
  7705.      * @see Arrays#copyOfRange(double[], int, int)
  7706.      */
  7707.     public static double[] subarray(final double[] array, int startIndexInclusive, int endIndexExclusive) {
  7708.         if (array == null) {
  7709.             return null;
  7710.         }
  7711.         startIndexInclusive = max0(startIndexInclusive);
  7712.         endIndexExclusive = Math.min(endIndexExclusive, array.length);
  7713.         final int newSize = endIndexExclusive - startIndexInclusive;
  7714.         if (newSize <= 0) {
  7715.             return EMPTY_DOUBLE_ARRAY;
  7716.         }
  7717.         return arraycopy(array, startIndexInclusive, 0, newSize, double[]::new);
  7718.     }

  7719.     /**
  7720.      * Produces a new {@code float} array containing the elements
  7721.      * between the start and end indices.
  7722.      * <p>
  7723.      * The start index is inclusive, the end index exclusive.
  7724.      * Null array input produces null output.
  7725.      * </p>
  7726.      *
  7727.      * @param array  the array
  7728.      * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
  7729.      *      is promoted to 0, overvalue (&gt;array.length) results
  7730.      *      in an empty array.
  7731.      * @param endIndexExclusive  elements up to endIndex-1 are present in the
  7732.      *      returned subarray. Undervalue (&lt; startIndex) produces
  7733.      *      empty array, overvalue (&gt;array.length) is demoted to
  7734.      *      array length.
  7735.      * @return a new array containing the elements between
  7736.      *      the start and end indices.
  7737.      * @since 2.1
  7738.      * @see Arrays#copyOfRange(float[], int, int)
  7739.      */
  7740.     public static float[] subarray(final float[] array, int startIndexInclusive, int endIndexExclusive) {
  7741.         if (array == null) {
  7742.             return null;
  7743.         }
  7744.         startIndexInclusive = max0(startIndexInclusive);
  7745.         endIndexExclusive = Math.min(endIndexExclusive, array.length);
  7746.         final int newSize = endIndexExclusive - startIndexInclusive;
  7747.         if (newSize <= 0) {
  7748.             return EMPTY_FLOAT_ARRAY;
  7749.         }
  7750.         return arraycopy(array, startIndexInclusive, 0, newSize, float[]::new);
  7751.     }

  7752.     /**
  7753.      * Produces a new {@code int} array containing the elements
  7754.      * between the start and end indices.
  7755.      * <p>
  7756.      * The start index is inclusive, the end index exclusive.
  7757.      * Null array input produces null output.
  7758.      * </p>
  7759.      *
  7760.      * @param array  the array
  7761.      * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
  7762.      *      is promoted to 0, overvalue (&gt;array.length) results
  7763.      *      in an empty array.
  7764.      * @param endIndexExclusive  elements up to endIndex-1 are present in the
  7765.      *      returned subarray. Undervalue (&lt; startIndex) produces
  7766.      *      empty array, overvalue (&gt;array.length) is demoted to
  7767.      *      array length.
  7768.      * @return a new array containing the elements between
  7769.      *      the start and end indices.
  7770.      * @since 2.1
  7771.      * @see Arrays#copyOfRange(int[], int, int)
  7772.      */
  7773.     public static int[] subarray(final int[] array, int startIndexInclusive, int endIndexExclusive) {
  7774.         if (array == null) {
  7775.             return null;
  7776.         }
  7777.         startIndexInclusive = max0(startIndexInclusive);
  7778.         endIndexExclusive = Math.min(endIndexExclusive, array.length);
  7779.         final int newSize = endIndexExclusive - startIndexInclusive;
  7780.         if (newSize <= 0) {
  7781.             return EMPTY_INT_ARRAY;
  7782.         }
  7783.         return arraycopy(array, startIndexInclusive, 0, newSize, int[]::new);
  7784.     }

  7785.     /**
  7786.      * Produces a new {@code long} array containing the elements
  7787.      * between the start and end indices.
  7788.      * <p>
  7789.      * The start index is inclusive, the end index exclusive.
  7790.      * Null array input produces null output.
  7791.      * </p>
  7792.      *
  7793.      * @param array  the array
  7794.      * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
  7795.      *      is promoted to 0, overvalue (&gt;array.length) results
  7796.      *      in an empty array.
  7797.      * @param endIndexExclusive  elements up to endIndex-1 are present in the
  7798.      *      returned subarray. Undervalue (&lt; startIndex) produces
  7799.      *      empty array, overvalue (&gt;array.length) is demoted to
  7800.      *      array length.
  7801.      * @return a new array containing the elements between
  7802.      *      the start and end indices.
  7803.      * @since 2.1
  7804.      * @see Arrays#copyOfRange(long[], int, int)
  7805.      */
  7806.     public static long[] subarray(final long[] array, int startIndexInclusive, int endIndexExclusive) {
  7807.         if (array == null) {
  7808.             return null;
  7809.         }
  7810.         startIndexInclusive = max0(startIndexInclusive);
  7811.         endIndexExclusive = Math.min(endIndexExclusive, array.length);
  7812.         final int newSize = endIndexExclusive - startIndexInclusive;
  7813.         if (newSize <= 0) {
  7814.             return EMPTY_LONG_ARRAY;
  7815.         }
  7816.         return arraycopy(array, startIndexInclusive, 0, newSize, long[]::new);
  7817.     }

  7818.     /**
  7819.      * Produces a new {@code short} array containing the elements
  7820.      * between the start and end indices.
  7821.      * <p>
  7822.      * The start index is inclusive, the end index exclusive.
  7823.      * Null array input produces null output.
  7824.      * </p>
  7825.      *
  7826.      * @param array  the array
  7827.      * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
  7828.      *      is promoted to 0, overvalue (&gt;array.length) results
  7829.      *      in an empty array.
  7830.      * @param endIndexExclusive  elements up to endIndex-1 are present in the
  7831.      *      returned subarray. Undervalue (&lt; startIndex) produces
  7832.      *      empty array, overvalue (&gt;array.length) is demoted to
  7833.      *      array length.
  7834.      * @return a new array containing the elements between
  7835.      *      the start and end indices.
  7836.      * @since 2.1
  7837.      * @see Arrays#copyOfRange(short[], int, int)
  7838.      */
  7839.     public static short[] subarray(final short[] array, int startIndexInclusive, int endIndexExclusive) {
  7840.         if (array == null) {
  7841.             return null;
  7842.         }
  7843.         startIndexInclusive = max0(startIndexInclusive);
  7844.         endIndexExclusive = Math.min(endIndexExclusive, array.length);
  7845.         final int newSize = endIndexExclusive - startIndexInclusive;
  7846.         if (newSize <= 0) {
  7847.             return EMPTY_SHORT_ARRAY;
  7848.         }
  7849.         return arraycopy(array, startIndexInclusive, 0, newSize, short[]::new);
  7850.     }

  7851.     /**
  7852.      * Produces a new array containing the elements between
  7853.      * the start and end indices.
  7854.      * <p>
  7855.      * The start index is inclusive, the end index exclusive.
  7856.      * Null array input produces null output.
  7857.      * </p>
  7858.      * <p>
  7859.      * The component type of the subarray is always the same as
  7860.      * that of the input array. Thus, if the input is an array of type
  7861.      * {@link Date}, the following usage is envisaged:
  7862.      * </p>
  7863.      * <pre>
  7864.      * Date[] someDates = (Date[]) ArrayUtils.subarray(allDates, 2, 5);
  7865.      * </pre>
  7866.      *
  7867.      * @param <T> the component type of the array
  7868.      * @param array  the array
  7869.      * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
  7870.      *      is promoted to 0, overvalue (&gt;array.length) results
  7871.      *      in an empty array.
  7872.      * @param endIndexExclusive  elements up to endIndex-1 are present in the
  7873.      *      returned subarray. Undervalue (&lt; startIndex) produces
  7874.      *      empty array, overvalue (&gt;array.length) is demoted to
  7875.      *      array length.
  7876.      * @return a new array containing the elements between
  7877.      *      the start and end indices.
  7878.      * @since 2.1
  7879.      * @see Arrays#copyOfRange(Object[], int, int)
  7880.      */
  7881.     public static <T> T[] subarray(final T[] array, int startIndexInclusive, int endIndexExclusive) {
  7882.         if (array == null) {
  7883.             return null;
  7884.         }
  7885.         startIndexInclusive = max0(startIndexInclusive);
  7886.         endIndexExclusive = Math.min(endIndexExclusive, array.length);
  7887.         final int newSize = endIndexExclusive - startIndexInclusive;
  7888.         final Class<T> type = getComponentType(array);
  7889.         if (newSize <= 0) {
  7890.             return newInstance(type, 0);
  7891.         }
  7892.         return arraycopy(array, startIndexInclusive, 0, newSize, () -> newInstance(type, newSize));
  7893.     }

  7894.     /**
  7895.      * Swaps two elements in the given boolean array.
  7896.      *
  7897.      * <p>There is no special handling for multi-dimensional arrays. This method
  7898.      * does nothing for a {@code null} or empty input array or for overflow indices.
  7899.      * Negative indices are promoted to 0(zero).</p>
  7900.      *
  7901.      * Examples:
  7902.      * <ul>
  7903.      *     <li>ArrayUtils.swap([1, 2, 3], 0, 2) -&gt; [3, 2, 1]</li>
  7904.      *     <li>ArrayUtils.swap([1, 2, 3], 0, 0) -&gt; [1, 2, 3]</li>
  7905.      *     <li>ArrayUtils.swap([1, 2, 3], 1, 0) -&gt; [2, 1, 3]</li>
  7906.      *     <li>ArrayUtils.swap([1, 2, 3], 0, 5) -&gt; [1, 2, 3]</li>
  7907.      *     <li>ArrayUtils.swap([1, 2, 3], -1, 1) -&gt; [2, 1, 3]</li>
  7908.      * </ul>
  7909.      *
  7910.      * @param array  the array to swap, may be {@code null}.
  7911.      * @param offset1 the index of the first element to swap
  7912.      * @param offset2 the index of the second element to swap
  7913.      * @since 3.5
  7914.      */
  7915.     public static void swap(final boolean[] array, final int offset1, final int offset2) {
  7916.         swap(array, offset1, offset2, 1);
  7917.     }

  7918.     /**
  7919.      * Swaps a series of elements in the given boolean array.
  7920.      *
  7921.      * <p>This method does nothing for a {@code null} or empty input array or
  7922.      * for overflow indices. Negative indices are promoted to 0(zero). If any
  7923.      * of the sub-arrays to swap falls outside of the given array, then the
  7924.      * swap is stopped at the end of the array and as many as possible elements
  7925.      * are swapped.</p>
  7926.      *
  7927.      * Examples:
  7928.      * <ul>
  7929.      *     <li>ArrayUtils.swap([true, false, true, false], 0, 2, 1) -&gt; [true, false, true, false]</li>
  7930.      *     <li>ArrayUtils.swap([true, false, true, false], 0, 0, 1) -&gt; [true, false, true, false]</li>
  7931.      *     <li>ArrayUtils.swap([true, false, true, false], 0, 2, 2) -&gt; [true, false, true, false]</li>
  7932.      *     <li>ArrayUtils.swap([true, false, true, false], -3, 2, 2) -&gt; [true, false, true, false]</li>
  7933.      *     <li>ArrayUtils.swap([true, false, true, false], 0, 3, 3) -&gt; [false, false, true, true]</li>
  7934.      * </ul>
  7935.      *
  7936.      * @param array the array to swap, may be {@code null}.
  7937.      * @param offset1 the index of the first element in the series to swap
  7938.      * @param offset2 the index of the second element in the series to swap
  7939.      * @param len the number of elements to swap starting with the given indices
  7940.      * @since 3.5
  7941.      */
  7942.     public static void swap(final boolean[] array, int offset1, int offset2, int len) {
  7943.         if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
  7944.             return;
  7945.         }
  7946.         offset1 = max0(offset1);
  7947.         offset2 = max0(offset2);
  7948.         len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
  7949.         for (int i = 0; i < len; i++, offset1++, offset2++) {
  7950.             final boolean aux = array[offset1];
  7951.             array[offset1] = array[offset2];
  7952.             array[offset2] = aux;
  7953.         }
  7954.     }

  7955.     /**
  7956.      * Swaps two elements in the given byte array.
  7957.      *
  7958.      * <p>There is no special handling for multi-dimensional arrays. This method
  7959.      * does nothing for a {@code null} or empty input array or for overflow indices.
  7960.      * Negative indices are promoted to 0(zero).</p>
  7961.      *
  7962.      * Examples:
  7963.      * <ul>
  7964.      *     <li>ArrayUtils.swap([1, 2, 3], 0, 2) -&gt; [3, 2, 1]</li>
  7965.      *     <li>ArrayUtils.swap([1, 2, 3], 0, 0) -&gt; [1, 2, 3]</li>
  7966.      *     <li>ArrayUtils.swap([1, 2, 3], 1, 0) -&gt; [2, 1, 3]</li>
  7967.      *     <li>ArrayUtils.swap([1, 2, 3], 0, 5) -&gt; [1, 2, 3]</li>
  7968.      *     <li>ArrayUtils.swap([1, 2, 3], -1, 1) -&gt; [2, 1, 3]</li>
  7969.      * </ul>
  7970.      *
  7971.      * @param array  the array to swap, may be {@code null}.
  7972.      * @param offset1 the index of the first element to swap
  7973.      * @param offset2 the index of the second element to swap
  7974.      * @since 3.5
  7975.      */
  7976.     public static void swap(final byte[] array, final int offset1, final int offset2) {
  7977.         swap(array, offset1, offset2, 1);
  7978.     }

  7979.     /**
  7980.      * Swaps a series of elements in the given byte array.
  7981.      *
  7982.      * <p>This method does nothing for a {@code null} or empty input array or
  7983.      * for overflow indices. Negative indices are promoted to 0(zero). If any
  7984.      * of the sub-arrays to swap falls outside of the given array, then the
  7985.      * swap is stopped at the end of the array and as many as possible elements
  7986.      * are swapped.</p>
  7987.      *
  7988.      * Examples:
  7989.      * <ul>
  7990.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -&gt; [3, 2, 1, 4]</li>
  7991.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -&gt; [1, 2, 3, 4]</li>
  7992.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -&gt; [3, 4, 1, 2]</li>
  7993.      *     <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -&gt; [3, 4, 1, 2]</li>
  7994.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -&gt; [4, 2, 3, 1]</li>
  7995.      * </ul>
  7996.      *
  7997.      * @param array the array to swap, may be {@code null}.
  7998.      * @param offset1 the index of the first element in the series to swap
  7999.      * @param offset2 the index of the second element in the series to swap
  8000.      * @param len the number of elements to swap starting with the given indices
  8001.      * @since 3.5
  8002.      */
  8003.     public static void swap(final byte[] array, int offset1, int offset2, int len) {
  8004.         if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
  8005.             return;
  8006.         }
  8007.         offset1 = max0(offset1);
  8008.         offset2 = max0(offset2);
  8009.         len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
  8010.         for (int i = 0; i < len; i++, offset1++, offset2++) {
  8011.             final byte aux = array[offset1];
  8012.             array[offset1] = array[offset2];
  8013.             array[offset2] = aux;
  8014.         }
  8015.     }

  8016.     /**
  8017.      * Swaps two elements in the given char array.
  8018.      *
  8019.      * <p>There is no special handling for multi-dimensional arrays. This method
  8020.      * does nothing for a {@code null} or empty input array or for overflow indices.
  8021.      * Negative indices are promoted to 0(zero).</p>
  8022.      *
  8023.      * Examples:
  8024.      * <ul>
  8025.      *     <li>ArrayUtils.swap([1, 2, 3], 0, 2) -&gt; [3, 2, 1]</li>
  8026.      *     <li>ArrayUtils.swap([1, 2, 3], 0, 0) -&gt; [1, 2, 3]</li>
  8027.      *     <li>ArrayUtils.swap([1, 2, 3], 1, 0) -&gt; [2, 1, 3]</li>
  8028.      *     <li>ArrayUtils.swap([1, 2, 3], 0, 5) -&gt; [1, 2, 3]</li>
  8029.      *     <li>ArrayUtils.swap([1, 2, 3], -1, 1) -&gt; [2, 1, 3]</li>
  8030.      * </ul>
  8031.      *
  8032.      * @param array  the array to swap, may be {@code null}.
  8033.      * @param offset1 the index of the first element to swap
  8034.      * @param offset2 the index of the second element to swap
  8035.      * @since 3.5
  8036.      */
  8037.     public static void swap(final char[] array, final int offset1, final int offset2) {
  8038.         swap(array, offset1, offset2, 1);
  8039.     }

  8040.     /**
  8041.      * Swaps a series of elements in the given char array.
  8042.      *
  8043.      * <p>This method does nothing for a {@code null} or empty input array or
  8044.      * for overflow indices. Negative indices are promoted to 0(zero). If any
  8045.      * of the sub-arrays to swap falls outside of the given array, then the
  8046.      * swap is stopped at the end of the array and as many as possible elements
  8047.      * are swapped.</p>
  8048.      *
  8049.      * Examples:
  8050.      * <ul>
  8051.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -&gt; [3, 2, 1, 4]</li>
  8052.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -&gt; [1, 2, 3, 4]</li>
  8053.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -&gt; [3, 4, 1, 2]</li>
  8054.      *     <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -&gt; [3, 4, 1, 2]</li>
  8055.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -&gt; [4, 2, 3, 1]</li>
  8056.      * </ul>
  8057.      *
  8058.      * @param array the array to swap, may be {@code null}.
  8059.      * @param offset1 the index of the first element in the series to swap
  8060.      * @param offset2 the index of the second element in the series to swap
  8061.      * @param len the number of elements to swap starting with the given indices
  8062.      * @since 3.5
  8063.      */
  8064.     public static void swap(final char[] array, int offset1, int offset2, int len) {
  8065.         if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
  8066.             return;
  8067.         }
  8068.         offset1 = max0(offset1);
  8069.         offset2 = max0(offset2);
  8070.         len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
  8071.         for (int i = 0; i < len; i++, offset1++, offset2++) {
  8072.             final char aux = array[offset1];
  8073.             array[offset1] = array[offset2];
  8074.             array[offset2] = aux;
  8075.         }
  8076.     }

  8077.     /**
  8078.      * Swaps two elements in the given double array.
  8079.      *
  8080.      * <p>There is no special handling for multi-dimensional arrays. This method
  8081.      * does nothing for a {@code null} or empty input array or for overflow indices.
  8082.      * Negative indices are promoted to 0(zero).</p>
  8083.      *
  8084.      * Examples:
  8085.      * <ul>
  8086.      *     <li>ArrayUtils.swap([1, 2, 3], 0, 2) -&gt; [3, 2, 1]</li>
  8087.      *     <li>ArrayUtils.swap([1, 2, 3], 0, 0) -&gt; [1, 2, 3]</li>
  8088.      *     <li>ArrayUtils.swap([1, 2, 3], 1, 0) -&gt; [2, 1, 3]</li>
  8089.      *     <li>ArrayUtils.swap([1, 2, 3], 0, 5) -&gt; [1, 2, 3]</li>
  8090.      *     <li>ArrayUtils.swap([1, 2, 3], -1, 1) -&gt; [2, 1, 3]</li>
  8091.      * </ul>
  8092.      *
  8093.      * @param array  the array to swap, may be {@code null}.
  8094.      * @param offset1 the index of the first element to swap
  8095.      * @param offset2 the index of the second element to swap
  8096.      * @since 3.5
  8097.      */
  8098.     public static void swap(final double[] array, final int offset1, final int offset2) {
  8099.         swap(array, offset1, offset2, 1);
  8100.     }

  8101.     /**
  8102.      * Swaps a series of elements in the given double array.
  8103.      *
  8104.      * <p>This method does nothing for a {@code null} or empty input array or
  8105.      * for overflow indices. Negative indices are promoted to 0(zero). If any
  8106.      * of the sub-arrays to swap falls outside of the given array, then the
  8107.      * swap is stopped at the end of the array and as many as possible elements
  8108.      * are swapped.</p>
  8109.      *
  8110.      * Examples:
  8111.      * <ul>
  8112.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -&gt; [3, 2, 1, 4]</li>
  8113.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -&gt; [1, 2, 3, 4]</li>
  8114.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -&gt; [3, 4, 1, 2]</li>
  8115.      *     <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -&gt; [3, 4, 1, 2]</li>
  8116.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -&gt; [4, 2, 3, 1]</li>
  8117.      * </ul>
  8118.      *
  8119.      * @param array the array to swap, may be {@code null}.
  8120.      * @param offset1 the index of the first element in the series to swap
  8121.      * @param offset2 the index of the second element in the series to swap
  8122.      * @param len the number of elements to swap starting with the given indices
  8123.      * @since 3.5
  8124.      */
  8125.     public static void swap(final double[] array,  int offset1, int offset2, int len) {
  8126.         if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
  8127.             return;
  8128.         }
  8129.         offset1 = max0(offset1);
  8130.         offset2 = max0(offset2);
  8131.         len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
  8132.         for (int i = 0; i < len; i++, offset1++, offset2++) {
  8133.             final double aux = array[offset1];
  8134.             array[offset1] = array[offset2];
  8135.             array[offset2] = aux;
  8136.         }
  8137.     }

  8138.     /**
  8139.      * Swaps two elements in the given float array.
  8140.      *
  8141.      * <p>There is no special handling for multi-dimensional arrays. This method
  8142.      * does nothing for a {@code null} or empty input array or for overflow indices.
  8143.      * Negative indices are promoted to 0(zero).</p>
  8144.      *
  8145.      * Examples:
  8146.      * <ul>
  8147.      *     <li>ArrayUtils.swap([1, 2, 3], 0, 2) -&gt; [3, 2, 1]</li>
  8148.      *     <li>ArrayUtils.swap([1, 2, 3], 0, 0) -&gt; [1, 2, 3]</li>
  8149.      *     <li>ArrayUtils.swap([1, 2, 3], 1, 0) -&gt; [2, 1, 3]</li>
  8150.      *     <li>ArrayUtils.swap([1, 2, 3], 0, 5) -&gt; [1, 2, 3]</li>
  8151.      *     <li>ArrayUtils.swap([1, 2, 3], -1, 1) -&gt; [2, 1, 3]</li>
  8152.      * </ul>
  8153.      *
  8154.      * @param array  the array to swap, may be {@code null}.
  8155.      * @param offset1 the index of the first element to swap
  8156.      * @param offset2 the index of the second element to swap
  8157.      * @since 3.5
  8158.      */
  8159.     public static void swap(final float[] array, final int offset1, final int offset2) {
  8160.         swap(array, offset1, offset2, 1);
  8161.     }

  8162.     /**
  8163.      * Swaps a series of elements in the given float array.
  8164.      *
  8165.      * <p>This method does nothing for a {@code null} or empty input array or
  8166.      * for overflow indices. Negative indices are promoted to 0(zero). If any
  8167.      * of the sub-arrays to swap falls outside of the given array, then the
  8168.      * swap is stopped at the end of the array and as many as possible elements
  8169.      * are swapped.</p>
  8170.      *
  8171.      * Examples:
  8172.      * <ul>
  8173.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -&gt; [3, 2, 1, 4]</li>
  8174.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -&gt; [1, 2, 3, 4]</li>
  8175.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -&gt; [3, 4, 1, 2]</li>
  8176.      *     <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -&gt; [3, 4, 1, 2]</li>
  8177.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -&gt; [4, 2, 3, 1]</li>
  8178.      * </ul>
  8179.      *
  8180.      * @param array the array to swap, may be {@code null}.
  8181.      * @param offset1 the index of the first element in the series to swap
  8182.      * @param offset2 the index of the second element in the series to swap
  8183.      * @param len the number of elements to swap starting with the given indices
  8184.      * @since 3.5
  8185.      */
  8186.     public static void swap(final float[] array, int offset1, int offset2, int len) {
  8187.         if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
  8188.             return;
  8189.         }
  8190.         offset1 = max0(offset1);
  8191.         offset2 = max0(offset2);
  8192.         len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
  8193.         for (int i = 0; i < len; i++, offset1++, offset2++) {
  8194.             final float aux = array[offset1];
  8195.             array[offset1] = array[offset2];
  8196.             array[offset2] = aux;
  8197.         }

  8198.     }

  8199.     /**
  8200.      * Swaps two elements in the given int array.
  8201.      *
  8202.      * <p>There is no special handling for multi-dimensional arrays. This method
  8203.      * does nothing for a {@code null} or empty input array or for overflow indices.
  8204.      * Negative indices are promoted to 0(zero).</p>
  8205.      *
  8206.      * Examples:
  8207.      * <ul>
  8208.      *     <li>ArrayUtils.swap([1, 2, 3], 0, 2) -&gt; [3, 2, 1]</li>
  8209.      *     <li>ArrayUtils.swap([1, 2, 3], 0, 0) -&gt; [1, 2, 3]</li>
  8210.      *     <li>ArrayUtils.swap([1, 2, 3], 1, 0) -&gt; [2, 1, 3]</li>
  8211.      *     <li>ArrayUtils.swap([1, 2, 3], 0, 5) -&gt; [1, 2, 3]</li>
  8212.      *     <li>ArrayUtils.swap([1, 2, 3], -1, 1) -&gt; [2, 1, 3]</li>
  8213.      * </ul>
  8214.      *
  8215.      * @param array  the array to swap, may be {@code null}
  8216.      * @param offset1 the index of the first element to swap
  8217.      * @param offset2 the index of the second element to swap
  8218.      * @since 3.5
  8219.      */
  8220.     public static void swap(final int[] array, final int offset1, final int offset2) {
  8221.         swap(array, offset1, offset2, 1);
  8222.     }

  8223.     /**
  8224.      * Swaps a series of elements in the given int array.
  8225.      *
  8226.      * <p>This method does nothing for a {@code null} or empty input array or
  8227.      * for overflow indices. Negative indices are promoted to 0(zero). If any
  8228.      * of the sub-arrays to swap falls outside of the given array, then the
  8229.      * swap is stopped at the end of the array and as many as possible elements
  8230.      * are swapped.</p>
  8231.      *
  8232.      * Examples:
  8233.      * <ul>
  8234.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -&gt; [3, 2, 1, 4]</li>
  8235.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -&gt; [1, 2, 3, 4]</li>
  8236.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -&gt; [3, 4, 1, 2]</li>
  8237.      *     <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -&gt; [3, 4, 1, 2]</li>
  8238.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -&gt; [4, 2, 3, 1]</li>
  8239.      * </ul>
  8240.      *
  8241.      * @param array the array to swap, may be {@code null}
  8242.      * @param offset1 the index of the first element in the series to swap
  8243.      * @param offset2 the index of the second element in the series to swap
  8244.      * @param len the number of elements to swap starting with the given indices
  8245.      * @since 3.5
  8246.      */
  8247.     public static void swap(final int[] array,  int offset1, int offset2, int len) {
  8248.         if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
  8249.             return;
  8250.         }
  8251.         offset1 = max0(offset1);
  8252.         offset2 = max0(offset2);
  8253.         len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
  8254.         for (int i = 0; i < len; i++, offset1++, offset2++) {
  8255.             final int aux = array[offset1];
  8256.             array[offset1] = array[offset2];
  8257.             array[offset2] = aux;
  8258.         }
  8259.     }

  8260.     /**
  8261.      * Swaps two elements in the given long array.
  8262.      *
  8263.      * <p>There is no special handling for multi-dimensional arrays. This method
  8264.      * does nothing for a {@code null} or empty input array or for overflow indices.
  8265.      * Negative indices are promoted to 0(zero).</p>
  8266.      *
  8267.      * Examples:
  8268.      * <ul>
  8269.      *     <li>ArrayUtils.swap([true, false, true], 0, 2) -&gt; [true, false, true]</li>
  8270.      *     <li>ArrayUtils.swap([true, false, true], 0, 0) -&gt; [true, false, true]</li>
  8271.      *     <li>ArrayUtils.swap([true, false, true], 1, 0) -&gt; [false, true, true]</li>
  8272.      *     <li>ArrayUtils.swap([true, false, true], 0, 5) -&gt; [true, false, true]</li>
  8273.      *     <li>ArrayUtils.swap([true, false, true], -1, 1) -&gt; [false, true, true]</li>
  8274.      * </ul>
  8275.      *
  8276.      * @param array  the array to swap, may be {@code null}
  8277.      * @param offset1 the index of the first element to swap
  8278.      * @param offset2 the index of the second element to swap
  8279.      * @since 3.5
  8280.      */
  8281.     public static void swap(final long[] array, final int offset1, final int offset2) {
  8282.         swap(array, offset1, offset2, 1);
  8283.     }

  8284.     /**
  8285.      * Swaps a series of elements in the given long array.
  8286.      *
  8287.      * <p>This method does nothing for a {@code null} or empty input array or
  8288.      * for overflow indices. Negative indices are promoted to 0(zero). If any
  8289.      * of the sub-arrays to swap falls outside of the given array, then the
  8290.      * swap is stopped at the end of the array and as many as possible elements
  8291.      * are swapped.</p>
  8292.      *
  8293.      * Examples:
  8294.      * <ul>
  8295.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -&gt; [3, 2, 1, 4]</li>
  8296.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -&gt; [1, 2, 3, 4]</li>
  8297.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -&gt; [3, 4, 1, 2]</li>
  8298.      *     <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -&gt; [3, 4, 1, 2]</li>
  8299.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -&gt; [4, 2, 3, 1]</li>
  8300.      * </ul>
  8301.      *
  8302.      * @param array the array to swap, may be {@code null}
  8303.      * @param offset1 the index of the first element in the series to swap
  8304.      * @param offset2 the index of the second element in the series to swap
  8305.      * @param len the number of elements to swap starting with the given indices
  8306.      * @since 3.5
  8307.      */
  8308.     public static void swap(final long[] array,  int offset1, int offset2, int len) {
  8309.         if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
  8310.             return;
  8311.         }
  8312.         offset1 = max0(offset1);
  8313.         offset2 = max0(offset2);
  8314.         len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
  8315.         for (int i = 0; i < len; i++, offset1++, offset2++) {
  8316.             final long aux = array[offset1];
  8317.             array[offset1] = array[offset2];
  8318.             array[offset2] = aux;
  8319.         }
  8320.     }

  8321.     /**
  8322.      * Swaps two elements in the given array.
  8323.      *
  8324.      * <p>There is no special handling for multi-dimensional arrays. This method
  8325.      * does nothing for a {@code null} or empty input array or for overflow indices.
  8326.      * Negative indices are promoted to 0(zero).</p>
  8327.      *
  8328.      * Examples:
  8329.      * <ul>
  8330.      *     <li>ArrayUtils.swap(["1", "2", "3"], 0, 2) -&gt; ["3", "2", "1"]</li>
  8331.      *     <li>ArrayUtils.swap(["1", "2", "3"], 0, 0) -&gt; ["1", "2", "3"]</li>
  8332.      *     <li>ArrayUtils.swap(["1", "2", "3"], 1, 0) -&gt; ["2", "1", "3"]</li>
  8333.      *     <li>ArrayUtils.swap(["1", "2", "3"], 0, 5) -&gt; ["1", "2", "3"]</li>
  8334.      *     <li>ArrayUtils.swap(["1", "2", "3"], -1, 1) -&gt; ["2", "1", "3"]</li>
  8335.      * </ul>
  8336.      *
  8337.      * @param array the array to swap, may be {@code null}
  8338.      * @param offset1 the index of the first element to swap
  8339.      * @param offset2 the index of the second element to swap
  8340.      * @since 3.5
  8341.      */
  8342.     public static void swap(final Object[] array, final int offset1, final int offset2) {
  8343.         swap(array, offset1, offset2, 1);
  8344.     }

  8345.     /**
  8346.      * Swaps a series of elements in the given array.
  8347.      *
  8348.      * <p>This method does nothing for a {@code null} or empty input array or
  8349.      * for overflow indices. Negative indices are promoted to 0(zero). If any
  8350.      * of the sub-arrays to swap falls outside of the given array, then the
  8351.      * swap is stopped at the end of the array and as many as possible elements
  8352.      * are swapped.</p>
  8353.      *
  8354.      * Examples:
  8355.      * <ul>
  8356.      *     <li>ArrayUtils.swap(["1", "2", "3", "4"], 0, 2, 1) -&gt; ["3", "2", "1", "4"]</li>
  8357.      *     <li>ArrayUtils.swap(["1", "2", "3", "4"], 0, 0, 1) -&gt; ["1", "2", "3", "4"]</li>
  8358.      *     <li>ArrayUtils.swap(["1", "2", "3", "4"], 2, 0, 2) -&gt; ["3", "4", "1", "2"]</li>
  8359.      *     <li>ArrayUtils.swap(["1", "2", "3", "4"], -3, 2, 2) -&gt; ["3", "4", "1", "2"]</li>
  8360.      *     <li>ArrayUtils.swap(["1", "2", "3", "4"], 0, 3, 3) -&gt; ["4", "2", "3", "1"]</li>
  8361.      * </ul>
  8362.      *
  8363.      * @param array the array to swap, may be {@code null}
  8364.      * @param offset1 the index of the first element in the series to swap
  8365.      * @param offset2 the index of the second element in the series to swap
  8366.      * @param len the number of elements to swap starting with the given indices
  8367.      * @since 3.5
  8368.      */
  8369.     public static void swap(final Object[] array,  int offset1, int offset2, int len) {
  8370.         if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
  8371.             return;
  8372.         }
  8373.         offset1 = max0(offset1);
  8374.         offset2 = max0(offset2);
  8375.         len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
  8376.         for (int i = 0; i < len; i++, offset1++, offset2++) {
  8377.             final Object aux = array[offset1];
  8378.             array[offset1] = array[offset2];
  8379.             array[offset2] = aux;
  8380.         }
  8381.     }

  8382.     /**
  8383.      * Swaps two elements in the given short array.
  8384.      *
  8385.      * <p>There is no special handling for multi-dimensional arrays. This method
  8386.      * does nothing for a {@code null} or empty input array or for overflow indices.
  8387.      * Negative indices are promoted to 0(zero).</p>
  8388.      *
  8389.      * Examples:
  8390.      * <ul>
  8391.      *     <li>ArrayUtils.swap([1, 2, 3], 0, 2) -&gt; [3, 2, 1]</li>
  8392.      *     <li>ArrayUtils.swap([1, 2, 3], 0, 0) -&gt; [1, 2, 3]</li>
  8393.      *     <li>ArrayUtils.swap([1, 2, 3], 1, 0) -&gt; [2, 1, 3]</li>
  8394.      *     <li>ArrayUtils.swap([1, 2, 3], 0, 5) -&gt; [1, 2, 3]</li>
  8395.      *     <li>ArrayUtils.swap([1, 2, 3], -1, 1) -&gt; [2, 1, 3]</li>
  8396.      * </ul>
  8397.      *
  8398.      * @param array  the array to swap, may be {@code null}
  8399.      * @param offset1 the index of the first element to swap
  8400.      * @param offset2 the index of the second element to swap
  8401.      * @since 3.5
  8402.      */
  8403.     public static void swap(final short[] array, final int offset1, final int offset2) {
  8404.         swap(array, offset1, offset2, 1);
  8405.     }

  8406.     /**
  8407.      * Swaps a series of elements in the given short array.
  8408.      *
  8409.      * <p>This method does nothing for a {@code null} or empty input array or
  8410.      * for overflow indices. Negative indices are promoted to 0(zero). If any
  8411.      * of the sub-arrays to swap falls outside of the given array, then the
  8412.      * swap is stopped at the end of the array and as many as possible elements
  8413.      * are swapped.</p>
  8414.      *
  8415.      * Examples:
  8416.      * <ul>
  8417.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -&gt; [3, 2, 1, 4]</li>
  8418.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -&gt; [1, 2, 3, 4]</li>
  8419.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -&gt; [3, 4, 1, 2]</li>
  8420.      *     <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -&gt; [3, 4, 1, 2]</li>
  8421.      *     <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -&gt; [4, 2, 3, 1]</li>
  8422.      * </ul>
  8423.      *
  8424.      * @param array the array to swap, may be {@code null}
  8425.      * @param offset1 the index of the first element in the series to swap
  8426.      * @param offset2 the index of the second element in the series to swap
  8427.      * @param len the number of elements to swap starting with the given indices
  8428.      * @since 3.5
  8429.      */
  8430.     public static void swap(final short[] array, int offset1, int offset2, int len) {
  8431.         if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
  8432.             return;
  8433.         }
  8434.         offset1 = max0(offset1);
  8435.         offset2 = max0(offset2);
  8436.         if (offset1 == offset2) {
  8437.             return;
  8438.         }
  8439.         len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
  8440.         for (int i = 0; i < len; i++, offset1++, offset2++) {
  8441.             final short aux = array[offset1];
  8442.             array[offset1] = array[offset2];
  8443.             array[offset2] = aux;
  8444.         }
  8445.     }

  8446.     /**
  8447.      * Create a type-safe generic array.
  8448.      * <p>
  8449.      * The Java language does not allow an array to be created from a generic type:
  8450.      * </p>
  8451.      * <pre>
  8452.     public static &lt;T&gt; T[] createAnArray(int size) {
  8453.         return new T[size]; // compiler error here
  8454.     }
  8455.     public static &lt;T&gt; T[] createAnArray(int size) {
  8456.         return (T[]) new Object[size]; // ClassCastException at runtime
  8457.     }
  8458.      * </pre>
  8459.      * <p>
  8460.      * Therefore new arrays of generic types can be created with this method.
  8461.      * For example, an array of Strings can be created:
  8462.      * </p>
  8463.      * <pre>{@code
  8464.      * String[] array = ArrayUtils.toArray("1", "2");
  8465.      * String[] emptyArray = ArrayUtils.<String>toArray();
  8466.      * }</pre>
  8467.      * <p>
  8468.      * The method is typically used in scenarios, where the caller itself uses generic types
  8469.      * that have to be combined into an array.
  8470.      * </p>
  8471.      * <p>
  8472.      * Note, this method makes only sense to provide arguments of the same type so that the
  8473.      * compiler can deduce the type of the array itself. While it is possible to select the
  8474.      * type explicitly like in
  8475.      * {@code Number[] array = ArrayUtils.<Number>toArray(Integer.valueOf(42), Double.valueOf(Math.PI))},
  8476.      * there is no real advantage when compared to
  8477.      * {@code new Number[] {Integer.valueOf(42), Double.valueOf(Math.PI)}}.
  8478.      * </p>
  8479.      *
  8480.      * @param  <T>   the array's element type
  8481.      * @param  items  the varargs array items, null allowed
  8482.      * @return the array, not null unless a null array is passed in
  8483.      * @since 3.0
  8484.      */
  8485.     public static <T> T[] toArray(@SuppressWarnings("unchecked") final T... items) {
  8486.         return items;
  8487.     }

  8488.     /**
  8489.      * Converts the given array into a {@link java.util.Map}. Each element of the array
  8490.      * must be either a {@link java.util.Map.Entry} or an Array, containing at least two
  8491.      * elements, where the first element is used as key and the second as
  8492.      * value.
  8493.      * <p>
  8494.      * This method can be used to initialize:
  8495.      * </p>
  8496.      * <pre>
  8497.      * // Create a Map mapping colors.
  8498.      * Map colorMap = ArrayUtils.toMap(new String[][] {
  8499.      *     {"RED", "#FF0000"},
  8500.      *     {"GREEN", "#00FF00"},
  8501.      *     {"BLUE", "#0000FF"}});
  8502.      * </pre>
  8503.      * <p>
  8504.      * This method returns {@code null} for a {@code null} input array.
  8505.      * </p>
  8506.      *
  8507.      * @param array  an array whose elements are either a {@link java.util.Map.Entry} or
  8508.      *  an Array containing at least two elements, may be {@code null}
  8509.      * @return a {@link Map} that was created from the array
  8510.      * @throws IllegalArgumentException  if one element of this Array is
  8511.      *  itself an Array containing less than two elements
  8512.      * @throws IllegalArgumentException  if the array contains elements other
  8513.      *  than {@link java.util.Map.Entry} and an Array
  8514.      */
  8515.     public static Map<Object, Object> toMap(final Object[] array) {
  8516.         if (array == null) {
  8517.             return null;
  8518.         }
  8519.         final Map<Object, Object> map = new HashMap<>((int) (array.length * 1.5));
  8520.         for (int i = 0; i < array.length; i++) {
  8521.             final Object object = array[i];
  8522.             if (object instanceof Map.Entry<?, ?>) {
  8523.                 final Map.Entry<?, ?> entry = (Map.Entry<?, ?>) object;
  8524.                 map.put(entry.getKey(), entry.getValue());
  8525.             } else if (object instanceof Object[]) {
  8526.                 final Object[] entry = (Object[]) object;
  8527.                 if (entry.length < 2) {
  8528.                     throw new IllegalArgumentException("Array element " + i + ", '"
  8529.                         + object
  8530.                         + "', has a length less than 2");
  8531.                 }
  8532.                 map.put(entry[0], entry[1]);
  8533.             } else {
  8534.                 throw new IllegalArgumentException("Array element " + i + ", '"
  8535.                         + object
  8536.                         + "', is neither of type Map.Entry nor an Array");
  8537.             }
  8538.         }
  8539.         return map;
  8540.     }

  8541.     /**
  8542.      * Converts an array of primitive booleans to objects.
  8543.      *
  8544.      * <p>This method returns {@code null} for a {@code null} input array.</p>
  8545.      *
  8546.      * @param array  a {@code boolean} array
  8547.      * @return a {@link Boolean} array, {@code null} if null array input
  8548.      */
  8549.     public static Boolean[] toObject(final boolean[] array) {
  8550.         if (array == null) {
  8551.             return null;
  8552.         }
  8553.         if (array.length == 0) {
  8554.             return EMPTY_BOOLEAN_OBJECT_ARRAY;
  8555.         }
  8556.         return setAll(new Boolean[array.length], i -> array[i] ? Boolean.TRUE : Boolean.FALSE);
  8557.     }

  8558.     /**
  8559.      * Converts an array of primitive bytes to objects.
  8560.      *
  8561.      * <p>This method returns {@code null} for a {@code null} input array.</p>
  8562.      *
  8563.      * @param array  a {@code byte} array
  8564.      * @return a {@link Byte} array, {@code null} if null array input
  8565.      */
  8566.     public static Byte[] toObject(final byte[] array) {
  8567.         if (array == null) {
  8568.             return null;
  8569.         }
  8570.         if (array.length == 0) {
  8571.             return EMPTY_BYTE_OBJECT_ARRAY;
  8572.         }
  8573.         return setAll(new Byte[array.length], i -> Byte.valueOf(array[i]));
  8574.     }

  8575.     /**
  8576.      * Converts an array of primitive chars to objects.
  8577.      *
  8578.      * <p>This method returns {@code null} for a {@code null} input array.</p>
  8579.      *
  8580.      * @param array a {@code char} array
  8581.      * @return a {@link Character} array, {@code null} if null array input
  8582.      */
  8583.     public static Character[] toObject(final char[] array) {
  8584.         if (array == null) {
  8585.             return null;
  8586.         }
  8587.         if (array.length == 0) {
  8588.             return EMPTY_CHARACTER_OBJECT_ARRAY;
  8589.         }
  8590.         return setAll(new Character[array.length], i -> Character.valueOf(array[i]));
  8591.      }

  8592.     /**
  8593.      * Converts an array of primitive doubles to objects.
  8594.      *
  8595.      * <p>This method returns {@code null} for a {@code null} input array.</p>
  8596.      *
  8597.      * @param array  a {@code double} array
  8598.      * @return a {@link Double} array, {@code null} if null array input
  8599.      */
  8600.     public static Double[] toObject(final double[] array) {
  8601.         if (array == null) {
  8602.             return null;
  8603.         }
  8604.         if (array.length == 0) {
  8605.             return EMPTY_DOUBLE_OBJECT_ARRAY;
  8606.         }
  8607.         return setAll(new Double[array.length], i -> Double.valueOf(array[i]));
  8608.     }

  8609.     /**
  8610.      * Converts an array of primitive floats to objects.
  8611.      *
  8612.      * <p>This method returns {@code null} for a {@code null} input array.</p>
  8613.      *
  8614.      * @param array  a {@code float} array
  8615.      * @return a {@link Float} array, {@code null} if null array input
  8616.      */
  8617.     public static Float[] toObject(final float[] array) {
  8618.         if (array == null) {
  8619.             return null;
  8620.         }
  8621.         if (array.length == 0) {
  8622.             return EMPTY_FLOAT_OBJECT_ARRAY;
  8623.         }
  8624.         return setAll(new Float[array.length], i -> Float.valueOf(array[i]));
  8625.     }

  8626.     /**
  8627.      * Converts an array of primitive ints to objects.
  8628.      *
  8629.      * <p>This method returns {@code null} for a {@code null} input array.</p>
  8630.      *
  8631.      * @param array  an {@code int} array
  8632.      * @return an {@link Integer} array, {@code null} if null array input
  8633.      */
  8634.     public static Integer[] toObject(final int[] array) {
  8635.         if (array == null) {
  8636.             return null;
  8637.         }
  8638.         if (array.length == 0) {
  8639.             return EMPTY_INTEGER_OBJECT_ARRAY;
  8640.         }
  8641.         return setAll(new Integer[array.length], i -> Integer.valueOf(array[i]));
  8642.     }

  8643.     /**
  8644.      * Converts an array of primitive longs to objects.
  8645.      *
  8646.      * <p>This method returns {@code null} for a {@code null} input array.</p>
  8647.      *
  8648.      * @param array  a {@code long} array
  8649.      * @return a {@link Long} array, {@code null} if null array input
  8650.      */
  8651.     public static Long[] toObject(final long[] array) {
  8652.         if (array == null) {
  8653.             return null;
  8654.         }
  8655.         if (array.length == 0) {
  8656.             return EMPTY_LONG_OBJECT_ARRAY;
  8657.         }
  8658.         return setAll(new Long[array.length], i -> Long.valueOf(array[i]));
  8659.     }

  8660.     /**
  8661.      * Converts an array of primitive shorts to objects.
  8662.      *
  8663.      * <p>This method returns {@code null} for a {@code null} input array.</p>
  8664.      *
  8665.      * @param array  a {@code short} array
  8666.      * @return a {@link Short} array, {@code null} if null array input
  8667.      */
  8668.     public static Short[] toObject(final short[] array) {
  8669.         if (array == null) {
  8670.             return null;
  8671.         }
  8672.         if (array.length == 0) {
  8673.             return EMPTY_SHORT_OBJECT_ARRAY;
  8674.         }
  8675.         return setAll(new Short[array.length], i -> Short.valueOf(array[i]));
  8676.     }

  8677.     /**
  8678.      * Converts an array of object Booleans to primitives.
  8679.      * <p>
  8680.      * This method returns {@code null} for a {@code null} input array.
  8681.      * </p>
  8682.      * <p>
  8683.      * Null array elements map to false, like {@code Boolean.parseBoolean(null)} and its callers return false.
  8684.      * </p>
  8685.      *
  8686.      * @param array a {@link Boolean} array, may be {@code null}
  8687.      * @return a {@code boolean} array, {@code null} if null array input
  8688.      */
  8689.     public static boolean[] toPrimitive(final Boolean[] array) {
  8690.         return toPrimitive(array, false);
  8691.     }

  8692.     /**
  8693.      * Converts an array of object Booleans to primitives handling {@code null}.
  8694.      * <p>
  8695.      * This method returns {@code null} for a {@code null} input array.
  8696.      * </p>
  8697.      *
  8698.      * @param array  a {@link Boolean} array, may be {@code null}
  8699.      * @param valueForNull  the value to insert if {@code null} found
  8700.      * @return a {@code boolean} array, {@code null} if null array input
  8701.      */
  8702.     public static boolean[] toPrimitive(final Boolean[] array, final boolean valueForNull) {
  8703.         if (array == null) {
  8704.             return null;
  8705.         }
  8706.         if (array.length == 0) {
  8707.             return EMPTY_BOOLEAN_ARRAY;
  8708.         }
  8709.         final boolean[] result = new boolean[array.length];
  8710.         for (int i = 0; i < array.length; i++) {
  8711.             final Boolean b = array[i];
  8712.             result[i] = b == null ? valueForNull : b.booleanValue();
  8713.         }
  8714.         return result;
  8715.     }

  8716.     /**
  8717.      * Converts an array of object Bytes to primitives.
  8718.      * <p>
  8719.      * This method returns {@code null} for a {@code null} input array.
  8720.      * </p>
  8721.      *
  8722.      * @param array  a {@link Byte} array, may be {@code null}
  8723.      * @return a {@code byte} array, {@code null} if null array input
  8724.      * @throws NullPointerException if an array element is {@code null}
  8725.      */
  8726.     public static byte[] toPrimitive(final Byte[] array) {
  8727.         if (array == null) {
  8728.             return null;
  8729.         }
  8730.         if (array.length == 0) {
  8731.             return EMPTY_BYTE_ARRAY;
  8732.         }
  8733.         final byte[] result = new byte[array.length];
  8734.         for (int i = 0; i < array.length; i++) {
  8735.             result[i] = array[i].byteValue();
  8736.         }
  8737.         return result;
  8738.     }

  8739.     /**
  8740.      * Converts an array of object Bytes to primitives handling {@code null}.
  8741.      * <p>
  8742.      * This method returns {@code null} for a {@code null} input array.
  8743.      * </p>
  8744.      *
  8745.      * @param array  a {@link Byte} array, may be {@code null}
  8746.      * @param valueForNull  the value to insert if {@code null} found
  8747.      * @return a {@code byte} array, {@code null} if null array input
  8748.      */
  8749.     public static byte[] toPrimitive(final Byte[] array, final byte valueForNull) {
  8750.         if (array == null) {
  8751.             return null;
  8752.         }
  8753.         if (array.length == 0) {
  8754.             return EMPTY_BYTE_ARRAY;
  8755.         }
  8756.         final byte[] result = new byte[array.length];
  8757.         for (int i = 0; i < array.length; i++) {
  8758.             final Byte b = array[i];
  8759.             result[i] = b == null ? valueForNull : b.byteValue();
  8760.         }
  8761.         return result;
  8762.     }

  8763.     /**
  8764.      * Converts an array of object Characters to primitives.
  8765.      * <p>
  8766.      * This method returns {@code null} for a {@code null} input array.
  8767.      * </p>
  8768.      *
  8769.      * @param array  a {@link Character} array, may be {@code null}
  8770.      * @return a {@code char} array, {@code null} if null array input
  8771.      * @throws NullPointerException if an array element is {@code null}
  8772.      */
  8773.     public static char[] toPrimitive(final Character[] array) {
  8774.         if (array == null) {
  8775.             return null;
  8776.         }
  8777.         if (array.length == 0) {
  8778.             return EMPTY_CHAR_ARRAY;
  8779.         }
  8780.         final char[] result = new char[array.length];
  8781.         for (int i = 0; i < array.length; i++) {
  8782.             result[i] = array[i].charValue();
  8783.         }
  8784.         return result;
  8785.     }

  8786.     /**
  8787.      * Converts an array of object Character to primitives handling {@code null}.
  8788.      * <p>
  8789.      * This method returns {@code null} for a {@code null} input array.
  8790.      * </p>
  8791.      *
  8792.      * @param array  a {@link Character} array, may be {@code null}
  8793.      * @param valueForNull  the value to insert if {@code null} found
  8794.      * @return a {@code char} array, {@code null} if null array input
  8795.      */
  8796.     public static char[] toPrimitive(final Character[] array, final char valueForNull) {
  8797.         if (array == null) {
  8798.             return null;
  8799.         }
  8800.         if (array.length == 0) {
  8801.             return EMPTY_CHAR_ARRAY;
  8802.         }
  8803.         final char[] result = new char[array.length];
  8804.         for (int i = 0; i < array.length; i++) {
  8805.             final Character b = array[i];
  8806.             result[i] = b == null ? valueForNull : b.charValue();
  8807.         }
  8808.         return result;
  8809.     }

  8810.     /**
  8811.      * Converts an array of object Doubles to primitives.
  8812.      * <p>
  8813.      * This method returns {@code null} for a {@code null} input array.
  8814.      * </p>
  8815.      *
  8816.      * @param array  a {@link Double} array, may be {@code null}
  8817.      * @return a {@code double} array, {@code null} if null array input
  8818.      * @throws NullPointerException if an array element is {@code null}
  8819.      */
  8820.     public static double[] toPrimitive(final Double[] array) {
  8821.         if (array == null) {
  8822.             return null;
  8823.         }
  8824.         if (array.length == 0) {
  8825.             return EMPTY_DOUBLE_ARRAY;
  8826.         }
  8827.         final double[] result = new double[array.length];
  8828.         for (int i = 0; i < array.length; i++) {
  8829.             result[i] = array[i].doubleValue();
  8830.         }
  8831.         return result;
  8832.     }

  8833.     /**
  8834.      * Converts an array of object Doubles to primitives handling {@code null}.
  8835.      * <p>
  8836.      * This method returns {@code null} for a {@code null} input array.
  8837.      * </p>
  8838.      *
  8839.      * @param array  a {@link Double} array, may be {@code null}
  8840.      * @param valueForNull  the value to insert if {@code null} found
  8841.      * @return a {@code double} array, {@code null} if null array input
  8842.      */
  8843.     public static double[] toPrimitive(final Double[] array, final double valueForNull) {
  8844.         if (array == null) {
  8845.             return null;
  8846.         }
  8847.         if (array.length == 0) {
  8848.             return EMPTY_DOUBLE_ARRAY;
  8849.         }
  8850.         final double[] result = new double[array.length];
  8851.         for (int i = 0; i < array.length; i++) {
  8852.             final Double b = array[i];
  8853.             result[i] = b == null ? valueForNull : b.doubleValue();
  8854.         }
  8855.         return result;
  8856.     }

  8857.     /**
  8858.      * Converts an array of object Floats to primitives.
  8859.      * <p>
  8860.      * This method returns {@code null} for a {@code null} input array.
  8861.      * </p>
  8862.      *
  8863.      * @param array  a {@link Float} array, may be {@code null}
  8864.      * @return a {@code float} array, {@code null} if null array input
  8865.      * @throws NullPointerException if an array element is {@code null}
  8866.      */
  8867.     public static float[] toPrimitive(final Float[] array) {
  8868.         if (array == null) {
  8869.             return null;
  8870.         }
  8871.         if (array.length == 0) {
  8872.             return EMPTY_FLOAT_ARRAY;
  8873.         }
  8874.         final float[] result = new float[array.length];
  8875.         for (int i = 0; i < array.length; i++) {
  8876.             result[i] = array[i].floatValue();
  8877.         }
  8878.         return result;
  8879.     }

  8880.     /**
  8881.      * Converts an array of object Floats to primitives handling {@code null}.
  8882.      * <p>
  8883.      * This method returns {@code null} for a {@code null} input array.
  8884.      * </p>
  8885.      *
  8886.      * @param array  a {@link Float} array, may be {@code null}
  8887.      * @param valueForNull  the value to insert if {@code null} found
  8888.      * @return a {@code float} array, {@code null} if null array input
  8889.      */
  8890.     public static float[] toPrimitive(final Float[] array, final float valueForNull) {
  8891.         if (array == null) {
  8892.             return null;
  8893.         }
  8894.         if (array.length == 0) {
  8895.             return EMPTY_FLOAT_ARRAY;
  8896.         }
  8897.         final float[] result = new float[array.length];
  8898.         for (int i = 0; i < array.length; i++) {
  8899.             final Float b = array[i];
  8900.             result[i] = b == null ? valueForNull : b.floatValue();
  8901.         }
  8902.         return result;
  8903.     }

  8904.     /**
  8905.      * Converts an array of object Integers to primitives.
  8906.      * <p>
  8907.      * This method returns {@code null} for a {@code null} input array.
  8908.      * </p>
  8909.      *
  8910.      * @param array  a {@link Integer} array, may be {@code null}
  8911.      * @return an {@code int} array, {@code null} if null array input
  8912.      * @throws NullPointerException if an array element is {@code null}
  8913.      */
  8914.     public static int[] toPrimitive(final Integer[] array) {
  8915.         if (array == null) {
  8916.             return null;
  8917.         }
  8918.         if (array.length == 0) {
  8919.             return EMPTY_INT_ARRAY;
  8920.         }
  8921.         final int[] result = new int[array.length];
  8922.         for (int i = 0; i < array.length; i++) {
  8923.             result[i] = array[i].intValue();
  8924.         }
  8925.         return result;
  8926.     }

  8927.     /**
  8928.      * Converts an array of object Integer to primitives handling {@code null}.
  8929.      * <p>
  8930.      * This method returns {@code null} for a {@code null} input array.
  8931.      * </p>
  8932.      *
  8933.      * @param array  a {@link Integer} array, may be {@code null}
  8934.      * @param valueForNull  the value to insert if {@code null} found
  8935.      * @return an {@code int} array, {@code null} if null array input
  8936.      */
  8937.     public static int[] toPrimitive(final Integer[] array, final int valueForNull) {
  8938.         if (array == null) {
  8939.             return null;
  8940.         }
  8941.         if (array.length == 0) {
  8942.             return EMPTY_INT_ARRAY;
  8943.         }
  8944.         final int[] result = new int[array.length];
  8945.         for (int i = 0; i < array.length; i++) {
  8946.             final Integer b = array[i];
  8947.             result[i] = b == null ? valueForNull : b.intValue();
  8948.         }
  8949.         return result;
  8950.     }

  8951.     /**
  8952.      * Converts an array of object Longs to primitives.
  8953.      * <p>
  8954.      * This method returns {@code null} for a {@code null} input array.
  8955.      * </p>
  8956.      *
  8957.      * @param array  a {@link Long} array, may be {@code null}
  8958.      * @return a {@code long} array, {@code null} if null array input
  8959.      * @throws NullPointerException if an array element is {@code null}
  8960.      */
  8961.     public static long[] toPrimitive(final Long[] array) {
  8962.         if (array == null) {
  8963.             return null;
  8964.         }
  8965.         if (array.length == 0) {
  8966.             return EMPTY_LONG_ARRAY;
  8967.         }
  8968.         final long[] result = new long[array.length];
  8969.         for (int i = 0; i < array.length; i++) {
  8970.             result[i] = array[i].longValue();
  8971.         }
  8972.         return result;
  8973.     }

  8974.     /**
  8975.      * Converts an array of object Long to primitives handling {@code null}.
  8976.      * <p>
  8977.      * This method returns {@code null} for a {@code null} input array.
  8978.      * </p>
  8979.      *
  8980.      * @param array  a {@link Long} array, may be {@code null}
  8981.      * @param valueForNull  the value to insert if {@code null} found
  8982.      * @return a {@code long} array, {@code null} if null array input
  8983.      */
  8984.     public static long[] toPrimitive(final Long[] array, final long valueForNull) {
  8985.         if (array == null) {
  8986.             return null;
  8987.         }
  8988.         if (array.length == 0) {
  8989.             return EMPTY_LONG_ARRAY;
  8990.         }
  8991.         final long[] result = new long[array.length];
  8992.         for (int i = 0; i < array.length; i++) {
  8993.             final Long b = array[i];
  8994.             result[i] = b == null ? valueForNull : b.longValue();
  8995.         }
  8996.         return result;
  8997.     }

  8998.     /**
  8999.      * Create an array of primitive type from an array of wrapper types.
  9000.      * <p>
  9001.      * This method returns {@code null} for a {@code null} input array.
  9002.      * </p>
  9003.      *
  9004.      * @param array  an array of wrapper object
  9005.      * @return an array of the corresponding primitive type, or the original array
  9006.      * @since 3.5
  9007.      */
  9008.     public static Object toPrimitive(final Object array) {
  9009.         if (array == null) {
  9010.             return null;
  9011.         }
  9012.         final Class<?> ct = array.getClass().getComponentType();
  9013.         final Class<?> pt = ClassUtils.wrapperToPrimitive(ct);
  9014.         if (Boolean.TYPE.equals(pt)) {
  9015.             return toPrimitive((Boolean[]) array);
  9016.         }
  9017.         if (Character.TYPE.equals(pt)) {
  9018.             return toPrimitive((Character[]) array);
  9019.         }
  9020.         if (Byte.TYPE.equals(pt)) {
  9021.             return toPrimitive((Byte[]) array);
  9022.         }
  9023.         if (Integer.TYPE.equals(pt)) {
  9024.             return toPrimitive((Integer[]) array);
  9025.         }
  9026.         if (Long.TYPE.equals(pt)) {
  9027.             return toPrimitive((Long[]) array);
  9028.         }
  9029.         if (Short.TYPE.equals(pt)) {
  9030.             return toPrimitive((Short[]) array);
  9031.         }
  9032.         if (Double.TYPE.equals(pt)) {
  9033.             return toPrimitive((Double[]) array);
  9034.         }
  9035.         if (Float.TYPE.equals(pt)) {
  9036.             return toPrimitive((Float[]) array);
  9037.         }
  9038.         return array;
  9039.     }

  9040.     /**
  9041.      * Converts an array of object Shorts to primitives.
  9042.      * <p>
  9043.      * This method returns {@code null} for a {@code null} input array.
  9044.      * </p>
  9045.      *
  9046.      * @param array  a {@link Short} array, may be {@code null}
  9047.      * @return a {@code byte} array, {@code null} if null array input
  9048.      * @throws NullPointerException if an array element is {@code null}
  9049.      */
  9050.     public static short[] toPrimitive(final Short[] array) {
  9051.         if (array == null) {
  9052.             return null;
  9053.         }
  9054.         if (array.length == 0) {
  9055.             return EMPTY_SHORT_ARRAY;
  9056.         }
  9057.         final short[] result = new short[array.length];
  9058.         for (int i = 0; i < array.length; i++) {
  9059.             result[i] = array[i].shortValue();
  9060.         }
  9061.         return result;
  9062.     }

  9063.     /**
  9064.      * Converts an array of object Short to primitives handling {@code null}.
  9065.      * <p>
  9066.      * This method returns {@code null} for a {@code null} input array.
  9067.      * </p>
  9068.      *
  9069.      * @param array  a {@link Short} array, may be {@code null}
  9070.      * @param valueForNull  the value to insert if {@code null} found
  9071.      * @return a {@code byte} array, {@code null} if null array input
  9072.      */
  9073.     public static short[] toPrimitive(final Short[] array, final short valueForNull) {
  9074.         if (array == null) {
  9075.             return null;
  9076.         }
  9077.         if (array.length == 0) {
  9078.             return EMPTY_SHORT_ARRAY;
  9079.         }
  9080.         final short[] result = new short[array.length];
  9081.         for (int i = 0; i < array.length; i++) {
  9082.             final Short b = array[i];
  9083.             result[i] = b == null ? valueForNull : b.shortValue();
  9084.         }
  9085.         return result;
  9086.     }

  9087.     /**
  9088.      * Outputs an array as a String, treating {@code null} as an empty array.
  9089.      * <p>
  9090.      * Multi-dimensional arrays are handled correctly, including
  9091.      * multi-dimensional primitive arrays.
  9092.      * </p>
  9093.      * <p>
  9094.      * The format is that of Java source code, for example {@code {a,b}}.
  9095.      * </p>
  9096.      *
  9097.      * @param array  the array to get a toString for, may be {@code null}
  9098.      * @return a String representation of the array, '{}' if null array input
  9099.      */
  9100.     public static String toString(final Object array) {
  9101.         return toString(array, "{}");
  9102.     }

  9103.     /**
  9104.      * Outputs an array as a String handling {@code null}s.
  9105.      * <p>
  9106.      * Multi-dimensional arrays are handled correctly, including
  9107.      * multi-dimensional primitive arrays.
  9108.      * </p>
  9109.      * <p>
  9110.      * The format is that of Java source code, for example {@code {a,b}}.
  9111.      * </p>
  9112.      *
  9113.      * @param array  the array to get a toString for, may be {@code null}
  9114.      * @param stringIfNull  the String to return if the array is {@code null}
  9115.      * @return a String representation of the array
  9116.      */
  9117.     public static String toString(final Object array, final String stringIfNull) {
  9118.         if (array == null) {
  9119.             return stringIfNull;
  9120.         }
  9121.         return new ToStringBuilder(array, ToStringStyle.SIMPLE_STYLE).append(array).toString();
  9122.     }

  9123.     /**
  9124.      * Returns an array containing the string representation of each element in the argument array.
  9125.      * <p>
  9126.      * This method returns {@code null} for a {@code null} input array.
  9127.      * </p>
  9128.      *
  9129.      * @param array the {@code Object[]} to be processed, may be {@code null}.
  9130.      * @return {@code String[]} of the same size as the source with its element's string representation,
  9131.      * {@code null} if null array input
  9132.      * @since 3.6
  9133.      */
  9134.     public static String[] toStringArray(final Object[] array) {
  9135.         return toStringArray(array, "null");
  9136.     }

  9137.     /**
  9138.      * Returns an array containing the string representation of each element in the argument
  9139.      * array handling {@code null} elements.
  9140.      * <p>
  9141.      * This method returns {@code null} for a {@code null} input array.
  9142.      * </p>
  9143.      *
  9144.      * @param array the Object[] to be processed, may be {@code null}.
  9145.      * @param valueForNullElements the value to insert if {@code null} is found
  9146.      * @return a {@link String} array, {@code null} if null array input
  9147.      * @since 3.6
  9148.      */
  9149.     public static String[] toStringArray(final Object[] array, final String valueForNullElements) {
  9150.         if (null == array) {
  9151.             return null;
  9152.         }
  9153.         if (array.length == 0) {
  9154.             return EMPTY_STRING_ARRAY;
  9155.         }
  9156.         return map(array, String.class, e -> Objects.toString(e, valueForNullElements));
  9157.     }

  9158.     /**
  9159.      * ArrayUtils instances should NOT be constructed in standard programming.
  9160.      * Instead, the class should be used as {@code ArrayUtils.clone(new int[] {2})}.
  9161.      * <p>
  9162.      * This constructor is public to permit tools that require a JavaBean instance
  9163.      * to operate.
  9164.      * </p>
  9165.      *
  9166.      * @deprecated TODO Make private in 4.0.
  9167.      */
  9168.     @Deprecated
  9169.     public ArrayUtils() {
  9170.         // empty
  9171.     }
  9172. }