`

ArrayUtil

    博客分类:
  • Util
阅读更多
package com.xxx.util;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 有关数组处理的工具类。
 * <p>
 * 这个类中的每个方法都可以“安全”地处理<code>null</code>,而不会抛出<code>NullPointerException</code>。
 * </p>
 * <p>
 * 本工具类是对JDK <code>Arrays</code>的补充。
 * </p>
 *
 * @author admin
 */
public class ArrayUtil {
    // ==========================================================================
    // 取得数组长度。
    // ==========================================================================

    /**
     * 取得数组的长度。
     * <p>
     * 此方法比<code>Array.getLength()</code>要快得多。
     * </p>
     *
     * @param array 要检查的数组
     * @return 如果为空,或者非数组,则返回<code>0</code>。
     */
    public static int arrayLength(Object array) {
        return arrayLength(array, 0, 0);
    }

    private static int arrayLength(Object array, int defaultIfNull, int defaultIfNotArray) {
        if (array == null) {
            return defaultIfNull; // null
        } else if (array instanceof Object[]) {
            return ((Object[]) array).length;
        } else if (array instanceof long[]) {
            return ((long[]) array).length;
        } else if (array instanceof int[]) {
            return ((int[]) array).length;
        } else if (array instanceof short[]) {
            return ((short[]) array).length;
        } else if (array instanceof byte[]) {
            return ((byte[]) array).length;
        } else if (array instanceof double[]) {
            return ((double[]) array).length;
        } else if (array instanceof float[]) {
            return ((float[]) array).length;
        } else if (array instanceof boolean[]) {
            return ((boolean[]) array).length;
        } else if (array instanceof char[]) {
            return ((char[]) array).length;
        } else {
            return defaultIfNotArray; // not an array
        }
    }

    // ==========================================================================
    // 判空函数。
    //
    // 判断一个数组是否为null或包含0个元素。
    // ==========================================================================

    /**
     * 检查数组是否为<code>null</code>或空数组<code>[]</code>。
     * <p/>
     * <pre>
     * ArrayUtil.isEmptyArray(null)              = true
     * ArrayUtil.isEmptyArray(new int[0])        = true
     * ArrayUtil.isEmptyArray(new int[10])       = false
     * </pre>
     *
     * @param array 要检查的数组
     * @return 如果为空, 则返回<code>true</code>
     */
    public static boolean isEmptyArray(Object array) {
        return arrayLength(array, 0, -1) == 0;
    }

    // ==========================================================================
    // 默认值函数。
    //
    // 当数组为空时,取得默认数组值。
    // 注:判断数组为null时,可用更通用的ObjectUtil.defaultIfNull。
    // ==========================================================================

    /**
     * 如果数组是<code>null</code>或空数组<code>[]</code>,则返回指定数组默认值。
     * <p/>
     * <pre>
     * ArrayUtil.defaultIfEmpty(null, defaultArray)           = defaultArray
     * ArrayUtil.defaultIfEmpty(new String[0], defaultArray)  = 数组本身
     * ArrayUtil.defaultIfEmpty(new String[10], defaultArray) = 数组本身
     * </pre>
     *
     * @param array        要转换的数组
     * @param defaultArray 默认数组
     * @return 数组本身或默认数组
     */
    public static <T, S extends T> T defaultIfEmptyArray(T array, S defaultValue) {
        return isEmptyArray(array) ? defaultValue : array;
    }

    // ==========================================================================
    // 将数组转换成集合类。
    // ==========================================================================

    /**
     * 将数组转换成<code>Iterable</code>列表。
     * <p>
     * 如果输入数组为<code>null</code>,则视作空数组。
     * </p>
     * <p>
     * 该方法返回的<code>Iterable</code>对象是轻量而高效的,不会产生复制数组的开销。你可以使用
     * <code>CollectionUtil.createArrayList(asIterable(componentType, array))</code>或
     * <code>CollectionUtil.createLinkedList(asIterable(componentType, array))</code>
     * 来进一步将 <code>Iterable</code>转换成指定类型的 <code>List</code>对象。
     * </p>
     *
     * @param componentType <code>Iterable</code>元素的类型,必须和数组类型兼容。例如对于
     *                      <code>int[]</code>数组, <code>componentType</code>必须为
     *                      <code>Integer.class</code>。
     * @param array         要转换的数组
     * @return 被创建的<code>Iterable</code>对象
     */
    public static <T> Iterable<T> arrayAsIterable(final Class<T> componentType, Object array) {
        Assert.assertNotNull(componentType, "componentType");

        if (array == null) {
            return new ArrayIterable<T>(0) {
                @Override
                protected T get(int i) {
                    Assert.unreachableCode();
                    return null;
                }
            };
        } else if (array instanceof Object[]) {
            final Object[] objectArray = (Object[]) array;

            return new ArrayIterable<T>(objectArray.length) {
                @Override
                protected T get(int i) {
                    return componentType.cast(objectArray[i]);
                }
            };
        } else if (array instanceof int[]) {
            final int[] intArray = (int[]) array;

            return new ArrayIterable<T>(intArray.length) {
                @Override
                protected T get(int i) {
                    return componentType.cast(intArray[i]);
                }
            };
        } else if (array instanceof long[]) {
            final long[] longArray = (long[]) array;

            return new ArrayIterable<T>(longArray.length) {
                @Override
                protected T get(int i) {
                    return componentType.cast(longArray[i]);
                }
            };
        } else if (array instanceof short[]) {
            final short[] shortArray = (short[]) array;

            return new ArrayIterable<T>(shortArray.length) {
                @Override
                protected T get(int i) {
                    return componentType.cast(shortArray[i]);
                }
            };
        } else if (array instanceof byte[]) {
            final byte[] byteArray = (byte[]) array;

            return new ArrayIterable<T>(byteArray.length) {
                @Override
                protected T get(int i) {
                    return componentType.cast(byteArray[i]);
                }
            };
        } else if (array instanceof double[]) {
            final double[] doubleArray = (double[]) array;

            return new ArrayIterable<T>(doubleArray.length) {
                @Override
                protected T get(int i) {
                    return componentType.cast(doubleArray[i]);
                }
            };
        } else if (array instanceof float[]) {
            final float[] floatArray = (float[]) array;

            return new ArrayIterable<T>(floatArray.length) {
                @Override
                protected T get(int i) {
                    return componentType.cast(floatArray[i]);
                }
            };
        } else if (array instanceof boolean[]) {
            final boolean[] booleanArray = (boolean[]) array;

            return new ArrayIterable<T>(booleanArray.length) {
                @Override
                protected T get(int i) {
                    return componentType.cast(booleanArray[i]);
                }
            };
        } else if (array instanceof char[]) {
            final char[] charArray = (char[]) array;

            return new ArrayIterable<T>(charArray.length) {
                @Override
                protected T get(int i) {
                    return componentType.cast(charArray[i]);
                }
            };
        } else {
            throw new IllegalArgumentException(array + " is not an array");
        }
    }

    private static abstract class ArrayIterable<T> implements Iterable<T> {
        private final int length;

        public ArrayIterable(int length) {
            this.length = length;
        }

        public final Iterator<T> iterator() {
            return new Iterator<T>() {
                private int index;

                public final boolean hasNext() {
                    return index < length;
                }

                public final T next() {
                    if (index >= length) {
                        throw new ArrayIndexOutOfBoundsException(index);
                    }

                    return get(index++);
                }

                public final void remove() {
                    Assert.unsupportedOperation("remove");
                }
            };
        }

        protected abstract T get(int i);
    }

    /**
     * 将数组转换成<code>Map</code>。数组的元素必须是元素个数多于2的子数组。
     * <p/>
     * <pre>
     * Map colorMap = ArrayUtil.toMap(new String[][] {{
     *     {"RED", 0xFF0000},
     *     {"GREEN", 0x00FF00},
     *     {"BLUE", 0x0000FF}}, String.class, Integer.class);
     * </pre>
     *
     * @param keyValueArray 要转换的数组
     * @param keyType       key的类型,数组元素<code>keyValueArray[n][0]</code>的类型必须与之兼容
     * @param valueType     value的类型,数组元素<code>keyValueArray[n][1]</code>的类型必须与之兼容
     * @return 被创建的map
     */
    public static <K, V> Map<K, V> arrayToMap(Object[][] keyValueArray, Class<K> keyType, Class<V> valueType) {
        return arrayToMap(keyValueArray, keyType, valueType, null);
    }

    /**
     * 将数组转换成<code>Map</code>。数组的元素必须是元素个数多于2的子数组。
     * <p/>
     * <pre>
     * Map colorMap = ArrayUtil.toMap(new String[][] {{
     *     {"RED", 0xFF0000},
     *     {"GREEN", 0x00FF00},
     *     {"BLUE", 0x0000FF}}, String.class, Integer.class, map);
     * </pre>
     *
     * @param keyValueArray 要转换的数组
     * @param keyType       key的类型,数组元素<code>keyValueArray[n][0]</code>的类型必须与之兼容
     * @param valueType     value的类型,数组元素<code>keyValueArray[n][1]</code>的类型必须与之兼容
     * @param map           要填充的map,如果为<code>null</code>则自动创建之
     * @return 被创建或填充的map
     */
    public static <K, V> Map<K, V> arrayToMap(Object[][] keyValueArray, Class<K> keyType, Class<V> valueType,
                                              Map<K, V> map) {
        Assert.assertNotNull(keyType, "keyType");
        Assert.assertNotNull(valueType, "valueType");

        if (keyValueArray == null) {
            return map;
        }

        if (map == null) {
            map = new LinkedHashMap<K, V>((int) (keyValueArray.length * 1.5));
        }

        for (int i = 0; i < keyValueArray.length; i++) {
            Object[] keyValue = keyValueArray[i];
            Object[] entry = keyValue;

            if (entry == null || entry.length < 2) {
                throw new IllegalArgumentException("Array element " + i + " is not an array of 2 elements");
            }

            map.put(keyType.cast(entry[0]), valueType.cast(entry[1]));
        }

        return map;
    }

    // ==========================================================================
    // 比较数组的长度。
    // ==========================================================================

    /**
     * 判断两个数组是否具有相同的长度。如果数组为<code>null</code>则被看作长度为<code>0</code>。
     *
     * @param array1 数组1
     * @param array2 数组2
     * @return 如果两个数组长度相同,则返回<code>true</code>
     */
    public static boolean isArraySameLength(Object[] array1, Object[] array2) {
        int length1 = array1 == null ? 0 : array1.length;
        int length2 = array2 == null ? 0 : array2.length;

        return length1 == length2;
    }

    /**
     * 判断两个数组是否具有相同的长度。如果数组为<code>null</code>则被看作长度为<code>0</code>。
     *
     * @param array1 数组1
     * @param array2 数组2
     * @return 如果两个数组长度相同,则返回<code>true</code>
     */
    public static boolean isArraySameLength(long[] array1, long[] array2) {
        int length1 = array1 == null ? 0 : array1.length;
        int length2 = array2 == null ? 0 : array2.length;

        return length1 == length2;
    }

    /**
     * 判断两个数组是否具有相同的长度。如果数组为<code>null</code>则被看作长度为<code>0</code>。
     *
     * @param array1 数组1
     * @param array2 数组2
     * @return 如果两个数组长度相同,则返回<code>true</code>
     */
    public static boolean isArraySameLength(int[] array1, int[] array2) {
        int length1 = array1 == null ? 0 : array1.length;
        int length2 = array2 == null ? 0 : array2.length;

        return length1 == length2;
    }

    /**
     * 判断两个数组是否具有相同的长度。如果数组为<code>null</code>则被看作长度为<code>0</code>。
     *
     * @param array1 数组1
     * @param array2 数组2
     * @return 如果两个数组长度相同,则返回<code>true</code>
     */
    public static boolean isArraySameLength(short[] array1, short[] array2) {
        int length1 = array1 == null ? 0 : array1.length;
        int length2 = array2 == null ? 0 : array2.length;

        return length1 == length2;
    }

    /**
     * 判断两个数组是否具有相同的长度。如果数组为<code>null</code>则被看作长度为<code>0</code>。
     *
     * @param array1 数组1
     * @param array2 数组2
     * @return 如果两个数组长度相同,则返回<code>true</code>
     */
    public static boolean isArraySameLength(byte[] array1, byte[] array2) {
        int length1 = array1 == null ? 0 : array1.length;
        int length2 = array2 == null ? 0 : array2.length;

        return length1 == length2;
    }

    /**
     * 判断两个数组是否具有相同的长度。如果数组为<code>null</code>则被看作长度为<code>0</code>。
     *
     * @param array1 数组1
     * @param array2 数组2
     * @return 如果两个数组长度相同,则返回<code>true</code>
     */
    public static boolean isArraySameLength(double[] array1, double[] array2) {
        int length1 = array1 == null ? 0 : array1.length;
        int length2 = array2 == null ? 0 : array2.length;

        return length1 == length2;
    }

    /**
     * 判断两个数组是否具有相同的长度。如果数组为<code>null</code>则被看作长度为<code>0</code>。
     *
     * @param array1 数组1
     * @param array2 数组2
     * @return 如果两个数组长度相同,则返回<code>true</code>
     */
    public static boolean isArraySameLength(float[] array1, float[] array2) {
        int length1 = array1 == null ? 0 : array1.length;
        int length2 = array2 == null ? 0 : array2.length;

        return length1 == length2;
    }

    /**
     * 判断两个数组是否具有相同的长度。如果数组为<code>null</code>则被看作长度为<code>0</code>。
     *
     * @param array1 数组1
     * @param array2 数组2
     * @return 如果两个数组长度相同,则返回<code>true</code>
     */
    public static boolean isArraySameLength(boolean[] array1, boolean[] array2) {
        int length1 = array1 == null ? 0 : array1.length;
        int length2 = array2 == null ? 0 : array2.length;

        return length1 == length2;
    }

    /**
     * 判断两个数组是否具有相同的长度。如果数组为<code>null</code>则被看作长度为<code>0</code>。
     *
     * @param array1 数组1
     * @param array2 数组2
     * @return 如果两个数组长度相同,则返回<code>true</code>
     */
    public static boolean isArraySameLength(char[] array1, char[] array2) {
        int length1 = array1 == null ? 0 : array1.length;
        int length2 = array2 == null ? 0 : array2.length;

        return length1 == length2;
    }

    // ==========================================================================
    // 反转数组的元素顺序。
    // ==========================================================================

    /**
     * 反转数组的元素顺序。如果数组为<code>null</code>,则什么也不做。
     *
     * @param array 要反转的数组
     */
    public static void arrayReverse(Object[] array) {
        if (array == null) {
            return;
        }

        Object tmp;

        for (int i = 0, j = array.length - 1; j > i; i++, j--) {
            tmp = array[j];
            array[j] = array[i];
            array[i] = tmp;
        }
    }

    /**
     * 反转数组的元素顺序。如果数组为<code>null</code>,则什么也不做。
     *
     * @param array 要反转的数组
     */
    public static void arrayReverse(long[] array) {
        if (array == null) {
            return;
        }

        long tmp;

        for (int i = 0, j = array.length - 1; j > i; i++, j--) {
            tmp = array[j];
            array[j] = array[i];
            array[i] = tmp;
        }
    }

    /**
     * 反转数组的元素顺序。如果数组为<code>null</code>,则什么也不做。
     *
     * @param array 要反转的数组
     */
    public static void arrayReverse(int[] array) {
        if (array == null) {
            return;
        }

        int tmp;

        for (int i = 0, j = array.length - 1; j > i; i++, j--) {
            tmp = array[j];
            array[j] = array[i];
            array[i] = tmp;
        }
    }

    /**
     * 反转数组的元素顺序。如果数组为<code>null</code>,则什么也不做。
     *
     * @param array 要反转的数组
     */
    public static void arrayReverse(short[] array) {
        if (array == null) {
            return;
        }

        short tmp;

        for (int i = 0, j = array.length - 1; j > i; i++, j--) {
            tmp = array[j];
            array[j] = array[i];
            array[i] = tmp;
        }
    }

    /**
     * 反转数组的元素顺序。如果数组为<code>null</code>,则什么也不做。
     *
     * @param array 要反转的数组
     */
    public static void arrayReverse(byte[] array) {
        if (array == null) {
            return;
        }

        byte tmp;

        for (int i = 0, j = array.length - 1; j > i; i++, j--) {
            tmp = array[j];
            array[j] = array[i];
            array[i] = tmp;
        }
    }

    /**
     * 反转数组的元素顺序。如果数组为<code>null</code>,则什么也不做。
     *
     * @param array 要反转的数组
     */
    public static void arrayReverse(double[] array) {
        if (array == null) {
            return;
        }

        double tmp;

        for (int i = 0, j = array.length - 1; j > i; i++, j--) {
            tmp = array[j];
            array[j] = array[i];
            array[i] = tmp;
        }
    }

    /**
     * 反转数组的元素顺序。如果数组为<code>null</code>,则什么也不做。
     *
     * @param array 要反转的数组
     */
    public static void arrayReverse(float[] array) {
        if (array == null) {
            return;
        }

        float tmp;

        for (int i = 0, j = array.length - 1; j > i; i++, j--) {
            tmp = array[j];
            array[j] = array[i];
            array[i] = tmp;
        }
    }

    /**
     * 反转数组的元素顺序。如果数组为<code>null</code>,则什么也不做。
     *
     * @param array 要反转的数组
     */
    public static void arrayReverse(boolean[] array) {
        if (array == null) {
            return;
        }

        boolean tmp;

        for (int i = 0, j = array.length - 1; j > i; i++, j--) {
            tmp = array[j];
            array[j] = array[i];
            array[i] = tmp;
        }
    }

    /**
     * 反转数组的元素顺序。如果数组为<code>null</code>,则什么也不做。
     *
     * @param array 要反转的数组
     */
    public static void arrayReverse(char[] array) {
        if (array == null) {
            return;
        }

        char tmp;

        for (int i = 0, j = array.length - 1; j > i; i++, j--) {
            tmp = array[j];
            array[j] = array[i];
            array[i] = tmp;
        }
    }

    // ==========================================================================
    // 在数组中查找一个元素或一个元素序列。
    //
    // 类型:Object[]
    // ==========================================================================

    /**
     * 在数组中查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array        要扫描的数组
     * @param objectToFind 要查找的元素
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(Object[] array, Object objectToFind) {
        return arrayIndexOf(array, objectToFind, 0);
    }

    /**
     * 在数组中查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(Object[] array, Object[] arrayToFind) {
        return arrayIndexOf(array, arrayToFind, 0);
    }

    /**
     * 在数组中查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则看作<code>0</code>,超出数组长度的起始索引则返回<code>-1</code>。
     * </p>
     *
     * @param array        要扫描的数组
     * @param objectToFind 要查找的元素
     * @param startIndex   起始索引
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(Object[] array, Object objectToFind, int startIndex) {
        if (array == null) {
            return -1;
        }

        if (startIndex < 0) {
            startIndex = 0;
        }

        if (objectToFind == null) {
            for (int i = startIndex; i < array.length; i++) {
                if (array[i] == null) {
                    return i;
                }
            }
        } else {
            for (int i = startIndex; i < array.length; i++) {
                if (objectToFind.equals(array[i])) {
                    return i;
                }
            }
        }

        return -1;
    }

    /**
     * 在数组中查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则看作<code>0</code>,超出数组长度的起始索引则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param startIndex  起始索引
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(Object[] array, Object[] arrayToFind, int startIndex) {
        if (array == null || arrayToFind == null) {
            return -1;
        }

        int sourceLength = array.length;
        int targetLength = arrayToFind.length;

        if (startIndex >= sourceLength) {
            return targetLength == 0 ? sourceLength : -1;
        }

        if (startIndex < 0) {
            startIndex = 0;
        }

        if (targetLength == 0) {
            return startIndex;
        }

        Object first = arrayToFind[0];
        int i = startIndex;
        int max = sourceLength - targetLength;

        startSearchForFirst:
        while (true) {
            // 查找第一个元素
            while (i <= max && !Objects.deepEquals(array[i], first)) {
                i++;
            }

            if (i > max) {
                return -1;
            }

            // 已经找到第一个元素,接着找
            int j = i + 1;
            int end = j + targetLength - 1;
            int k = 1;

            while (j < end) {
                if (!Objects.deepEquals(array[j++], arrayToFind[k++])) {
                    i++;

                    // 重新查找第一个元素
                    continue startSearchForFirst;
                }
            }

            // 找到了
            return i;
        }
    }

    /**
     * 在数组中从末尾开始查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array        要扫描的数组
     * @param objectToFind 要查找的元素
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(Object[] array, Object objectToFind) {
        return arrayLastIndexOf(array, objectToFind, Integer.MAX_VALUE);
    }

    /**
     * 在数组中从末尾开始查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(Object[] array, Object[] arrayToFind) {
        return arrayLastIndexOf(array, arrayToFind, Integer.MAX_VALUE);
    }

    /**
     * 在数组中从末尾开始查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则返回<code>-1</code>,超出数组长度的起始索引则从数组末尾开始找。
     * </p>
     *
     * @param array        要扫描的数组
     * @param objectToFind 要查找的元素
     * @param startIndex   起始索引
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(Object[] array, Object objectToFind, int startIndex) {
        if (array == null) {
            return -1;
        }

        if (startIndex < 0) {
            return -1;
        } else if (startIndex >= array.length) {
            startIndex = array.length - 1;
        }

        if (objectToFind == null) {
            for (int i = startIndex; i >= 0; i--) {
                if (array[i] == null) {
                    return i;
                }
            }
        } else {
            for (int i = startIndex; i >= 0; i--) {
                if (objectToFind.equals(array[i])) {
                    return i;
                }
            }
        }

        return -1;
    }

    /**
     * 在数组中从末尾开始查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则返回<code>-1</code>,超出数组长度的起始索引则从数组末尾开始找。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param startIndex  起始索引
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(Object[] array, Object[] arrayToFind, int startIndex) {
        if (array == null || arrayToFind == null) {
            return -1;
        }

        int sourceLength = array.length;
        int targetLength = arrayToFind.length;

        int rightIndex = sourceLength - targetLength;

        if (startIndex < 0) {
            return -1;
        }

        if (startIndex > rightIndex) {
            startIndex = rightIndex;
        }

        if (targetLength == 0) {
            return startIndex;
        }

        int lastIndex = targetLength - 1;
        Object last = arrayToFind[lastIndex];
        int min = targetLength - 1;
        int i = min + startIndex;

        startSearchForLast:
        while (true) {
            while (i >= min && !Objects.deepEquals(array[i], last)) {
                i--;
            }

            if (i < min) {
                return -1;
            }

            int j = i - 1;
            int start = j - (targetLength - 1);
            int k = lastIndex - 1;

            while (j > start) {
                if (!Objects.deepEquals(array[j--], arrayToFind[k--])) {
                    i--;
                    continue startSearchForLast;
                }
            }

            return start + 1;
        }
    }

    /**
     * 判断指定对象是否存在于指定数组中。
     * <p>
     * 如果数组为<code>null</code>则返回<code>false</code>。
     * </p>
     *
     * @param array        要扫描的数组
     * @param objectToFind 要查找的元素
     * @return 如果找到则返回<code>true</code>
     */
    public static boolean arrayContains(Object[] array, Object objectToFind) {
        return arrayIndexOf(array, objectToFind) != -1;
    }

    /**
     * 判断指定元素序列是否存在于指定数组中。
     * <p>
     * 如果数组为<code>null</code>则返回<code>false</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 如果找到则返回<code>true</code>
     */
    public static boolean arrayContains(Object[] array, Object[] arrayToFind) {
        return arrayIndexOf(array, arrayToFind) != -1;
    }

    // ==========================================================================
    // 在数组中查找一个元素或一个元素序列。
    //
    // 类型:long[]
    // ==========================================================================

    /**
     * 在数组中查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array      要扫描的数组
     * @param longToFind 要查找的元素
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(long[] array, long longToFind) {
        return arrayIndexOf(array, longToFind, 0);
    }

    /**
     * 在数组中查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(long[] array, long[] arrayToFind) {
        return arrayIndexOf(array, arrayToFind, 0);
    }

    /**
     * 在数组中查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则看作<code>0</code>,超出数组长度的起始索引则返回<code>-1</code>。
     * </p>
     *
     * @param array      要扫描的数组
     * @param longToFind 要查找的元素
     * @param startIndex 起始索引
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(long[] array, long longToFind, int startIndex) {
        if (array == null) {
            return -1;
        }

        if (startIndex < 0) {
            startIndex = 0;
        }

        for (int i = startIndex; i < array.length; i++) {
            if (longToFind == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 在数组中查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则看作<code>0</code>,超出数组长度的起始索引则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param startIndex  起始索引
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(long[] array, long[] arrayToFind, int startIndex) {
        if (array == null || arrayToFind == null) {
            return -1;
        }

        int sourceLength = array.length;
        int targetLength = arrayToFind.length;

        if (startIndex >= sourceLength) {
            return targetLength == 0 ? sourceLength : -1;
        }

        if (startIndex < 0) {
            startIndex = 0;
        }

        if (targetLength == 0) {
            return startIndex;
        }

        long first = arrayToFind[0];
        int i = startIndex;
        int max = sourceLength - targetLength;

        startSearchForFirst:
        while (true) {
            // 查找第一个元素
            while (i <= max && array[i] != first) {
                i++;
            }

            if (i > max) {
                return -1;
            }

            // 已经找到第一个元素,接着找
            int j = i + 1;
            int end = j + targetLength - 1;
            int k = 1;

            while (j < end) {
                if (array[j++] != arrayToFind[k++]) {
                    i++;

                    // 重新查找第一个元素
                    continue startSearchForFirst;
                }
            }

            // 找到了
            return i;
        }
    }

    /**
     * 在数组中从末尾开始查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array      要扫描的数组
     * @param longToFind 要查找的元素
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(long[] array, long longToFind) {
        return arrayLastIndexOf(array, longToFind, Integer.MAX_VALUE);
    }

    /**
     * 在数组中从末尾开始查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(long[] array, long[] arrayToFind) {
        return arrayLastIndexOf(array, arrayToFind, Integer.MAX_VALUE);
    }

    /**
     * 在数组中从末尾开始查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则返回<code>-1</code>,超出数组长度的起始索引则从数组末尾开始找。
     * </p>
     *
     * @param array      要扫描的数组
     * @param longToFind 要查找的元素
     * @param startIndex 起始索引
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(long[] array, long longToFind, int startIndex) {
        if (array == null) {
            return -1;
        }

        if (startIndex < 0) {
            return -1;
        } else if (startIndex >= array.length) {
            startIndex = array.length - 1;
        }

        for (int i = startIndex; i >= 0; i--) {
            if (longToFind == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 在数组中从末尾开始查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则返回<code>-1</code>,超出数组长度的起始索引则从数组末尾开始找。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param startIndex  起始索引
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(long[] array, long[] arrayToFind, int startIndex) {
        if (array == null || arrayToFind == null) {
            return -1;
        }

        int sourceLength = array.length;
        int targetLength = arrayToFind.length;

        int rightIndex = sourceLength - targetLength;

        if (startIndex < 0) {
            return -1;
        }

        if (startIndex > rightIndex) {
            startIndex = rightIndex;
        }

        if (targetLength == 0) {
            return startIndex;
        }

        int lastIndex = targetLength - 1;
        long last = arrayToFind[lastIndex];
        int min = targetLength - 1;
        int i = min + startIndex;

        startSearchForLast:
        while (true) {
            while (i >= min && array[i] != last) {
                i--;
            }

            if (i < min) {
                return -1;
            }

            int j = i - 1;
            int start = j - (targetLength - 1);
            int k = lastIndex - 1;

            while (j > start) {
                if (array[j--] != arrayToFind[k--]) {
                    i--;
                    continue startSearchForLast;
                }
            }

            return start + 1;
        }
    }

    /**
     * 判断指定对象是否存在于指定数组中。
     * <p>
     * 如果数组为<code>null</code>则返回<code>false</code>。
     * </p>
     *
     * @param array      要扫描的数组
     * @param longToFind 要查找的元素
     * @return 如果找到则返回<code>true</code>
     */
    public static boolean arrayContains(long[] array, long longToFind) {
        return arrayIndexOf(array, longToFind) != -1;
    }

    /**
     * 判断指定元素序列是否存在于指定数组中。
     * <p>
     * 如果数组为<code>null</code>则返回<code>false</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 如果找到则返回<code>true</code>
     */
    public static boolean arrayContains(long[] array, long[] arrayToFind) {
        return arrayIndexOf(array, arrayToFind) != -1;
    }

    // ==========================================================================
    // 在数组中查找一个元素或一个元素序列。
    //
    // 类型:int[]
    // ==========================================================================

    /**
     * 在数组中查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array     要扫描的数组
     * @param intToFind 要查找的元素
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(int[] array, int intToFind) {
        return arrayIndexOf(array, intToFind, 0);
    }

    /**
     * 在数组中查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(int[] array, int[] arrayToFind) {
        return arrayIndexOf(array, arrayToFind, 0);
    }

    /**
     * 在数组中查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则看作<code>0</code>,超出数组长度的起始索引则返回<code>-1</code>。
     * </p>
     *
     * @param array      要扫描的数组
     * @param intToFind  要查找的元素
     * @param startIndex 起始索引
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(int[] array, int intToFind, int startIndex) {
        if (array == null) {
            return -1;
        }

        if (startIndex < 0) {
            startIndex = 0;
        }

        for (int i = startIndex; i < array.length; i++) {
            if (intToFind == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 在数组中查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则看作<code>0</code>,超出数组长度的起始索引则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param startIndex  起始索引
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(int[] array, int[] arrayToFind, int startIndex) {
        if (array == null || arrayToFind == null) {
            return -1;
        }

        int sourceLength = array.length;
        int targetLength = arrayToFind.length;

        if (startIndex >= sourceLength) {
            return targetLength == 0 ? sourceLength : -1;
        }

        if (startIndex < 0) {
            startIndex = 0;
        }

        if (targetLength == 0) {
            return startIndex;
        }

        int first = arrayToFind[0];
        int i = startIndex;
        int max = sourceLength - targetLength;

        startSearchForFirst:
        while (true) {
            // 查找第一个元素
            while (i <= max && array[i] != first) {
                i++;
            }

            if (i > max) {
                return -1;
            }

            // 已经找到第一个元素,接着找
            int j = i + 1;
            int end = j + targetLength - 1;
            int k = 1;

            while (j < end) {
                if (array[j++] != arrayToFind[k++]) {
                    i++;

                    // 重新查找第一个元素
                    continue startSearchForFirst;
                }
            }

            // 找到了
            return i;
        }
    }

    /**
     * 在数组中从末尾开始查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array     要扫描的数组
     * @param intToFind 要查找的元素
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(int[] array, int intToFind) {
        return arrayLastIndexOf(array, intToFind, Integer.MAX_VALUE);
    }

    /**
     * 在数组中从末尾开始查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(int[] array, int[] arrayToFind) {
        return arrayLastIndexOf(array, arrayToFind, Integer.MAX_VALUE);
    }

    /**
     * 在数组中从末尾开始查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则返回<code>-1</code>,超出数组长度的起始索引则从数组末尾开始找。
     * </p>
     *
     * @param array      要扫描的数组
     * @param intToFind  要查找的元素
     * @param startIndex 起始索引
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(int[] array, int intToFind, int startIndex) {
        if (array == null) {
            return -1;
        }

        if (startIndex < 0) {
            return -1;
        } else if (startIndex >= array.length) {
            startIndex = array.length - 1;
        }

        for (int i = startIndex; i >= 0; i--) {
            if (intToFind == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 在数组中从末尾开始查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则返回<code>-1</code>,超出数组长度的起始索引则从数组末尾开始找。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param startIndex  起始索引
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(int[] array, int[] arrayToFind, int startIndex) {
        if (array == null || arrayToFind == null) {
            return -1;
        }

        int sourceLength = array.length;
        int targetLength = arrayToFind.length;

        int rightIndex = sourceLength - targetLength;

        if (startIndex < 0) {
            return -1;
        }

        if (startIndex > rightIndex) {
            startIndex = rightIndex;
        }

        if (targetLength == 0) {
            return startIndex;
        }

        int lastIndex = targetLength - 1;
        int last = arrayToFind[lastIndex];
        int min = targetLength - 1;
        int i = min + startIndex;

        startSearchForLast:
        while (true) {
            while (i >= min && array[i] != last) {
                i--;
            }

            if (i < min) {
                return -1;
            }

            int j = i - 1;
            int start = j - (targetLength - 1);
            int k = lastIndex - 1;

            while (j > start) {
                if (array[j--] != arrayToFind[k--]) {
                    i--;
                    continue startSearchForLast;
                }
            }

            return start + 1;
        }
    }

    /**
     * 判断指定对象是否存在于指定数组中。
     * <p>
     * 如果数组为<code>null</code>则返回<code>false</code>。
     * </p>
     *
     * @param array     要扫描的数组
     * @param intToFind 要查找的元素
     * @return 如果找到则返回<code>true</code>
     */
    public static boolean arrayContains(int[] array, int intToFind) {
        return arrayIndexOf(array, intToFind) != -1;
    }

    /**
     * 判断指定元素序列是否存在于指定数组中。
     * <p>
     * 如果数组为<code>null</code>则返回<code>false</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 如果找到则返回<code>true</code>
     */
    public static boolean arrayContains(int[] array, int[] arrayToFind) {
        return arrayIndexOf(array, arrayToFind) != -1;
    }

    // ==========================================================================
    // 在数组中查找一个元素或一个元素序列。
    //
    // 类型:short[]
    // ==========================================================================

    /**
     * 在数组中查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param shortToFind 要查找的元素
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(short[] array, short shortToFind) {
        return arrayIndexOf(array, shortToFind, 0);
    }

    /**
     * 在数组中查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(short[] array, short[] arrayToFind) {
        return arrayIndexOf(array, arrayToFind, 0);
    }

    /**
     * 在数组中查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则看作<code>0</code>,超出数组长度的起始索引则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param shortToFind 要查找的元素
     * @param startIndex  起始索引
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(short[] array, short shortToFind, int startIndex) {
        if (array == null) {
            return -1;
        }

        if (startIndex < 0) {
            startIndex = 0;
        }

        for (int i = startIndex; i < array.length; i++) {
            if (shortToFind == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 在数组中查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则看作<code>0</code>,超出数组长度的起始索引则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param startIndex  起始索引
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(short[] array, short[] arrayToFind, int startIndex) {
        if (array == null || arrayToFind == null) {
            return -1;
        }

        int sourceLength = array.length;
        int targetLength = arrayToFind.length;

        if (startIndex >= sourceLength) {
            return targetLength == 0 ? sourceLength : -1;
        }

        if (startIndex < 0) {
            startIndex = 0;
        }

        if (targetLength == 0) {
            return startIndex;
        }

        short first = arrayToFind[0];
        int i = startIndex;
        int max = sourceLength - targetLength;

        startSearchForFirst:
        while (true) {
            // 查找第一个元素
            while (i <= max && array[i] != first) {
                i++;
            }

            if (i > max) {
                return -1;
            }

            // 已经找到第一个元素,接着找
            int j = i + 1;
            int end = j + targetLength - 1;
            int k = 1;

            while (j < end) {
                if (array[j++] != arrayToFind[k++]) {
                    i++;

                    // 重新查找第一个元素
                    continue startSearchForFirst;
                }
            }

            // 找到了
            return i;
        }
    }

    /**
     * 在数组中从末尾开始查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param shortToFind 要查找的元素
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(short[] array, short shortToFind) {
        return arrayLastIndexOf(array, shortToFind, Integer.MAX_VALUE);
    }

    /**
     * 在数组中从末尾开始查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(short[] array, short[] arrayToFind) {
        return arrayLastIndexOf(array, arrayToFind, Integer.MAX_VALUE);
    }

    /**
     * 在数组中从末尾开始查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则返回<code>-1</code>,超出数组长度的起始索引则从数组末尾开始找。
     * </p>
     *
     * @param array       要扫描的数组
     * @param shortToFind 要查找的元素
     * @param startIndex  起始索引
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(short[] array, short shortToFind, int startIndex) {
        if (array == null) {
            return -1;
        }

        if (startIndex < 0) {
            return -1;
        } else if (startIndex >= array.length) {
            startIndex = array.length - 1;
        }

        for (int i = startIndex; i >= 0; i--) {
            if (shortToFind == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 在数组中从末尾开始查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则返回<code>-1</code>,超出数组长度的起始索引则从数组末尾开始找。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param startIndex  起始索引
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(short[] array, short[] arrayToFind, int startIndex) {
        if (array == null || arrayToFind == null) {
            return -1;
        }

        int sourceLength = array.length;
        int targetLength = arrayToFind.length;

        int rightIndex = sourceLength - targetLength;

        if (startIndex < 0) {
            return -1;
        }

        if (startIndex > rightIndex) {
            startIndex = rightIndex;
        }

        if (targetLength == 0) {
            return startIndex;
        }

        int lastIndex = targetLength - 1;
        short last = arrayToFind[lastIndex];
        int min = targetLength - 1;
        int i = min + startIndex;

        startSearchForLast:
        while (true) {
            while (i >= min && array[i] != last) {
                i--;
            }

            if (i < min) {
                return -1;
            }

            int j = i - 1;
            int start = j - (targetLength - 1);
            int k = lastIndex - 1;

            while (j > start) {
                if (array[j--] != arrayToFind[k--]) {
                    i--;
                    continue startSearchForLast;
                }
            }

            return start + 1;
        }
    }

    /**
     * 判断指定对象是否存在于指定数组中。
     * <p>
     * 如果数组为<code>null</code>则返回<code>false</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param shortToFind 要查找的元素
     * @return 如果找到则返回<code>true</code>
     */
    public static boolean arrayContains(short[] array, short shortToFind) {
        return arrayIndexOf(array, shortToFind) != -1;
    }

    /**
     * 判断指定元素序列是否存在于指定数组中。
     * <p>
     * 如果数组为<code>null</code>则返回<code>false</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 如果找到则返回<code>true</code>
     */
    public static boolean arrayContains(short[] array, short[] arrayToFind) {
        return arrayIndexOf(array, arrayToFind) != -1;
    }

    // ==========================================================================
    // 在数组中查找一个元素或一个元素序列。
    //
    // 类型:byte[]
    // ==========================================================================

    /**
     * 在数组中查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array      要扫描的数组
     * @param byteToFind 要查找的元素
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(byte[] array, byte byteToFind) {
        return arrayIndexOf(array, byteToFind, 0);
    }

    /**
     * 在数组中查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(byte[] array, byte[] arrayToFind) {
        return arrayIndexOf(array, arrayToFind, 0);
    }

    /**
     * 在数组中查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则看作<code>0</code>,超出数组长度的起始索引则返回<code>-1</code>。
     * </p>
     *
     * @param array      要扫描的数组
     * @param byteToFind 要查找的元素
     * @param startIndex 起始索引
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(byte[] array, byte byteToFind, int startIndex) {
        if (array == null) {
            return -1;
        }

        if (startIndex < 0) {
            startIndex = 0;
        }

        for (int i = startIndex; i < array.length; i++) {
            if (byteToFind == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 在数组中查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则看作<code>0</code>,超出数组长度的起始索引则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param startIndex  起始索引
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(byte[] array, byte[] arrayToFind, int startIndex) {
        if (array == null || arrayToFind == null) {
            return -1;
        }

        int sourceLength = array.length;
        int targetLength = arrayToFind.length;

        if (startIndex >= sourceLength) {
            return targetLength == 0 ? sourceLength : -1;
        }

        if (startIndex < 0) {
            startIndex = 0;
        }

        if (targetLength == 0) {
            return startIndex;
        }

        byte first = arrayToFind[0];
        int i = startIndex;
        int max = sourceLength - targetLength;

        startSearchForFirst:
        while (true) {
            // 查找第一个元素
            while (i <= max && array[i] != first) {
                i++;
            }

            if (i > max) {
                return -1;
            }

            // 已经找到第一个元素,接着找
            int j = i + 1;
            int end = j + targetLength - 1;
            int k = 1;

            while (j < end) {
                if (array[j++] != arrayToFind[k++]) {
                    i++;

                    // 重新查找第一个元素
                    continue startSearchForFirst;
                }
            }

            // 找到了
            return i;
        }
    }

    /**
     * 在数组中从末尾开始查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array      要扫描的数组
     * @param byteToFind 要查找的元素
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(byte[] array, byte byteToFind) {
        return arrayLastIndexOf(array, byteToFind, Integer.MAX_VALUE);
    }

    /**
     * 在数组中从末尾开始查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(byte[] array, byte[] arrayToFind) {
        return arrayLastIndexOf(array, arrayToFind, Integer.MAX_VALUE);
    }

    /**
     * 在数组中从末尾开始查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则返回<code>-1</code>,超出数组长度的起始索引则从数组末尾开始找。
     * </p>
     *
     * @param array      要扫描的数组
     * @param byteToFind 要查找的元素
     * @param startIndex 起始索引
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(byte[] array, byte byteToFind, int startIndex) {
        if (array == null) {
            return -1;
        }

        if (startIndex < 0) {
            return -1;
        } else if (startIndex >= array.length) {
            startIndex = array.length - 1;
        }

        for (int i = startIndex; i >= 0; i--) {
            if (byteToFind == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 在数组中从末尾开始查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则返回<code>-1</code>,超出数组长度的起始索引则从数组末尾开始找。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param startIndex  起始索引
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(byte[] array, byte[] arrayToFind, int startIndex) {
        if (array == null || arrayToFind == null) {
            return -1;
        }

        int sourceLength = array.length;
        int targetLength = arrayToFind.length;

        int rightIndex = sourceLength - targetLength;

        if (startIndex < 0) {
            return -1;
        }

        if (startIndex > rightIndex) {
            startIndex = rightIndex;
        }

        if (targetLength == 0) {
            return startIndex;
        }

        int lastIndex = targetLength - 1;
        byte last = arrayToFind[lastIndex];
        int min = targetLength - 1;
        int i = min + startIndex;

        startSearchForLast:
        while (true) {
            while (i >= min && array[i] != last) {
                i--;
            }

            if (i < min) {
                return -1;
            }

            int j = i - 1;
            int start = j - (targetLength - 1);
            int k = lastIndex - 1;

            while (j > start) {
                if (array[j--] != arrayToFind[k--]) {
                    i--;
                    continue startSearchForLast;
                }
            }

            return start + 1;
        }
    }

    /**
     * 判断指定对象是否存在于指定数组中。
     * <p>
     * 如果数组为<code>null</code>则返回<code>false</code>。
     * </p>
     *
     * @param array      要扫描的数组
     * @param byteToFind 要查找的元素
     * @return 如果找到则返回<code>true</code>
     */
    public static boolean arrayContains(byte[] array, byte byteToFind) {
        return arrayIndexOf(array, byteToFind) != -1;
    }

    /**
     * 判断指定元素序列是否存在于指定数组中。
     * <p>
     * 如果数组为<code>null</code>则返回<code>false</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 如果找到则返回<code>true</code>
     */
    public static boolean arrayContains(byte[] array, byte[] arrayToFind) {
        return arrayIndexOf(array, arrayToFind) != -1;
    }

    // ==========================================================================
    // 在数组中查找一个元素或一个元素序列。
    //
    // 类型:double[]
    // ==========================================================================

    /**
     * 在数组中查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array        要扫描的数组
     * @param doubleToFind 要查找的元素
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(double[] array, double doubleToFind) {
        return arrayIndexOf(array, doubleToFind, 0, 0);
    }

    /**
     * 在数组中查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array        要扫描的数组
     * @param doubleToFind 要查找的元素
     * @param tolerance    误差
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(double[] array, double doubleToFind, double tolerance) {
        return arrayIndexOf(array, doubleToFind, 0, tolerance);
    }

    /**
     * 在数组中查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(double[] array, double[] arrayToFind) {
        return arrayIndexOf(array, arrayToFind, 0, 0);
    }

    /**
     * 在数组中查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param tolerance   误差
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(double[] array, double[] arrayToFind, double tolerance) {
        return arrayIndexOf(array, arrayToFind, 0, tolerance);
    }

    /**
     * 在数组中查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则看作<code>0</code>,超出数组长度的起始索引则返回<code>-1</code>。
     * </p>
     *
     * @param array        要扫描的数组
     * @param doubleToFind 要查找的元素
     * @param startIndex   起始索引
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(double[] array, double doubleToFind, int startIndex) {
        return arrayIndexOf(array, doubleToFind, startIndex, 0);
    }

    /**
     * 在数组中查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则看作<code>0</code>,超出数组长度的起始索引则返回<code>-1</code>。
     * </p>
     *
     * @param array        要扫描的数组
     * @param doubleToFind 要查找的元素
     * @param startIndex   起始索引
     * @param tolerance    误差
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(double[] array, double doubleToFind, int startIndex, double tolerance) {
        if (array == null) {
            return -1;
        }

        if (startIndex < 0) {
            startIndex = 0;
        }

        double min = doubleToFind - tolerance;
        double max = doubleToFind + tolerance;

        for (int i = startIndex; i < array.length; i++) {
            if (array[i] >= min && array[i] <= max) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 在数组中查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则看作<code>0</code>,超出数组长度的起始索引则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param startIndex  起始索引
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(double[] array, double[] arrayToFind, int startIndex) {
        return arrayIndexOf(array, arrayToFind, startIndex, 0);
    }

    /**
     * 在数组中查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则看作<code>0</code>,超出数组长度的起始索引则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param startIndex  起始索引
     * @param tolerance   误差
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(double[] array, double[] arrayToFind, int startIndex, double tolerance) {
        if (array == null || arrayToFind == null) {
            return -1;
        }

        int sourceLength = array.length;
        int targetLength = arrayToFind.length;

        if (startIndex >= sourceLength) {
            return targetLength == 0 ? sourceLength : -1;
        }

        if (startIndex < 0) {
            startIndex = 0;
        }

        if (targetLength == 0) {
            return startIndex;
        }

        double firstMin = arrayToFind[0] - tolerance;
        double firstMax = arrayToFind[0] + tolerance;
        int i = startIndex;
        int max = sourceLength - targetLength;

        startSearchForFirst:
        while (true) {
            // 查找第一个元素
            while (i <= max && (array[i] < firstMin || array[i] > firstMax)) {
                i++;
            }

            if (i > max) {
                return -1;
            }

            // 已经找到第一个元素,接着找
            int j = i + 1;
            int end = j + targetLength - 1;
            int k = 1;

            while (j < end) {
                if (Math.abs(array[j++] - arrayToFind[k++]) > tolerance) {
                    i++;

                    // 重新查找第一个元素
                    continue startSearchForFirst;
                }
            }

            // 找到了
            return i;
        }
    }

    /**
     * 在数组中从末尾开始查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array        要扫描的数组
     * @param doubleToFind 要查找的元素
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(double[] array, double doubleToFind) {
        return arrayLastIndexOf(array, doubleToFind, Integer.MAX_VALUE, 0);
    }

    /**
     * 在数组中从末尾开始查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array        要扫描的数组
     * @param doubleToFind 要查找的元素
     * @param tolerance    误差
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(double[] array, double doubleToFind, double tolerance) {
        return arrayLastIndexOf(array, doubleToFind, Integer.MAX_VALUE, tolerance);
    }

    /**
     * 在数组中从末尾开始查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(double[] array, double[] arrayToFind) {
        return arrayLastIndexOf(array, arrayToFind, Integer.MAX_VALUE, 0);
    }

    /**
     * 在数组中从末尾开始查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param tolerance   误差
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(double[] array, double[] arrayToFind, double tolerance) {
        return arrayLastIndexOf(array, arrayToFind, Integer.MAX_VALUE, tolerance);
    }

    /**
     * 在数组中从末尾开始查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则返回<code>-1</code>,超出数组长度的起始索引则从数组末尾开始找。
     * </p>
     *
     * @param array        要扫描的数组
     * @param doubleToFind 要查找的元素
     * @param startIndex   起始索引
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(double[] array, double doubleToFind, int startIndex) {
        return arrayLastIndexOf(array, doubleToFind, startIndex, 0);
    }

    /**
     * 在数组中从末尾开始查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则返回<code>-1</code>,超出数组长度的起始索引则从数组末尾开始找。
     * </p>
     *
     * @param array        要扫描的数组
     * @param doubleToFind 要查找的元素
     * @param startIndex   起始索引
     * @param tolerance    误差
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(double[] array, double doubleToFind, int startIndex, double tolerance) {
        if (array == null) {
            return -1;
        }

        if (startIndex < 0) {
            return -1;
        } else if (startIndex >= array.length) {
            startIndex = array.length - 1;
        }

        double min = doubleToFind - tolerance;
        double max = doubleToFind + tolerance;

        for (int i = startIndex; i >= 0; i--) {
            if (array[i] >= min && array[i] <= max) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 在数组中从末尾开始查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则返回<code>-1</code>,超出数组长度的起始索引则从数组末尾开始找。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param startIndex  起始索引
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(double[] array, double[] arrayToFind, int startIndex) {
        return arrayLastIndexOf(array, arrayToFind, startIndex, 0);
    }

    /**
     * 在数组中从末尾开始查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则返回<code>-1</code>,超出数组长度的起始索引则从数组末尾开始找。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param startIndex  起始索引
     * @param tolerance   误差
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(double[] array, double[] arrayToFind, int startIndex, double tolerance) {
        if (array == null || arrayToFind == null) {
            return -1;
        }

        int sourceLength = array.length;
        int targetLength = arrayToFind.length;

        int rightIndex = sourceLength - targetLength;

        if (startIndex < 0) {
            return -1;
        }

        if (startIndex > rightIndex) {
            startIndex = rightIndex;
        }

        if (targetLength == 0) {
            return startIndex;
        }

        int lastIndex = targetLength - 1;
        double lastMin = arrayToFind[lastIndex] - tolerance;
        double lastMax = arrayToFind[lastIndex] + tolerance;
        int min = targetLength - 1;
        int i = min + startIndex;

        startSearchForLast:
        while (true) {
            while (i >= min && (array[i] < lastMin || array[i] > lastMax)) {
                i--;
            }

            if (i < min) {
                return -1;
            }

            int j = i - 1;
            int start = j - (targetLength - 1);
            int k = lastIndex - 1;

            while (j > start) {
                if (Math.abs(array[j--] - arrayToFind[k--]) > tolerance) {
                    i--;
                    continue startSearchForLast;
                }
            }

            return start + 1;
        }
    }

    /**
     * 判断指定对象是否存在于指定数组中。
     * <p>
     * 如果数组为<code>null</code>则返回<code>false</code>。
     * </p>
     *
     * @param array        要扫描的数组
     * @param doubleToFind 要查找的元素
     * @return 如果找到则返回<code>true</code>
     */
    public static boolean arrayContains(double[] array, double doubleToFind) {
        return arrayIndexOf(array, doubleToFind) != -1;
    }

    /**
     * 判断指定对象是否存在于指定数组中。
     * <p>
     * 如果数组为<code>null</code>则返回<code>false</code>。
     * </p>
     *
     * @param array        要扫描的数组
     * @param doubleToFind 要查找的元素
     * @param tolerance    误差
     * @return 如果找到则返回<code>true</code>
     */
    public static boolean arrayContains(double[] array, double doubleToFind, double tolerance) {
        return arrayIndexOf(array, doubleToFind, tolerance) != -1;
    }

    /**
     * 判断指定元素序列是否存在于指定数组中。
     * <p>
     * 如果数组为<code>null</code>则返回<code>false</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 如果找到则返回<code>true</code>
     */
    public static boolean arrayContains(double[] array, double[] arrayToFind) {
        return arrayIndexOf(array, arrayToFind) != -1;
    }

    /**
     * 判断指定元素序列是否存在于指定数组中。
     * <p>
     * 如果数组为<code>null</code>则返回<code>false</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param tolerance   误差
     * @return 如果找到则返回<code>true</code>
     */
    public static boolean arrayContains(double[] array, double[] arrayToFind, double tolerance) {
        return arrayIndexOf(array, arrayToFind, tolerance) != -1;
    }

    // ==========================================================================
    // 在数组中查找一个元素或一个元素序列。
    //
    // 类型:float[]
    // ==========================================================================

    /**
     * 在数组中查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param floatToFind 要查找的元素
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(float[] array, float floatToFind) {
        return arrayIndexOf(array, floatToFind, 0, 0);
    }

    /**
     * 在数组中查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param floatToFind 要查找的元素
     * @param tolerance   误差
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(float[] array, float floatToFind, float tolerance) {
        return arrayIndexOf(array, floatToFind, 0, tolerance);
    }

    /**
     * 在数组中查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(float[] array, float[] arrayToFind) {
        return arrayIndexOf(array, arrayToFind, 0, 0);
    }

    /**
     * 在数组中查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param tolerance   误差
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(float[] array, float[] arrayToFind, float tolerance) {
        return arrayIndexOf(array, arrayToFind, 0, tolerance);
    }

    /**
     * 在数组中查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则看作<code>0</code>,超出数组长度的起始索引则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param floatToFind 要查找的元素
     * @param startIndex  起始索引
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(float[] array, float floatToFind, int startIndex) {
        return arrayIndexOf(array, floatToFind, startIndex, 0);
    }

    /**
     * 在数组中查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则看作<code>0</code>,超出数组长度的起始索引则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param floatToFind 要查找的元素
     * @param startIndex  起始索引
     * @param tolerance   误差
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(float[] array, float floatToFind, int startIndex, float tolerance) {
        if (array == null) {
            return -1;
        }

        if (startIndex < 0) {
            startIndex = 0;
        }

        float min = floatToFind - tolerance;
        float max = floatToFind + tolerance;

        for (int i = startIndex; i < array.length; i++) {
            if (array[i] >= min && array[i] <= max) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 在数组中查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则看作<code>0</code>,超出数组长度的起始索引则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param startIndex  起始索引
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(float[] array, float[] arrayToFind, int startIndex) {
        return arrayIndexOf(array, arrayToFind, startIndex, 0);
    }

    /**
     * 在数组中查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则看作<code>0</code>,超出数组长度的起始索引则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param startIndex  起始索引
     * @param tolerance   误差
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(float[] array, float[] arrayToFind, int startIndex, float tolerance) {
        if (array == null || arrayToFind == null) {
            return -1;
        }

        int sourceLength = array.length;
        int targetLength = arrayToFind.length;

        if (startIndex >= sourceLength) {
            return targetLength == 0 ? sourceLength : -1;
        }

        if (startIndex < 0) {
            startIndex = 0;
        }

        if (targetLength == 0) {
            return startIndex;
        }

        float firstMin = arrayToFind[0] - tolerance;
        float firstMax = arrayToFind[0] + tolerance;
        int i = startIndex;
        int max = sourceLength - targetLength;

        startSearchForFirst:
        while (true) {
            // 查找第一个元素
            while (i <= max && (array[i] < firstMin || array[i] > firstMax)) {
                i++;
            }

            if (i > max) {
                return -1;
            }

            // 已经找到第一个元素,接着找
            int j = i + 1;
            int end = j + targetLength - 1;
            int k = 1;

            while (j < end) {
                if (Math.abs(array[j++] - arrayToFind[k++]) > tolerance) {
                    i++;

                    // 重新查找第一个元素
                    continue startSearchForFirst;
                }
            }

            // 找到了
            return i;
        }
    }

    /**
     * 在数组中从末尾开始查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param floatToFind 要查找的元素
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(float[] array, float floatToFind) {
        return arrayLastIndexOf(array, floatToFind, Integer.MAX_VALUE, 0);
    }

    /**
     * 在数组中从末尾开始查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param floatToFind 要查找的元素
     * @param tolerance   误差
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(float[] array, float floatToFind, float tolerance) {
        return arrayLastIndexOf(array, floatToFind, Integer.MAX_VALUE, tolerance);
    }

    /**
     * 在数组中从末尾开始查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(float[] array, float[] arrayToFind) {
        return arrayLastIndexOf(array, arrayToFind, Integer.MAX_VALUE, 0);
    }

    /**
     * 在数组中从末尾开始查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param tolerance   误差
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(float[] array, float[] arrayToFind, float tolerance) {
        return arrayLastIndexOf(array, arrayToFind, Integer.MAX_VALUE, tolerance);
    }

    /**
     * 在数组中从末尾开始查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则返回<code>-1</code>,超出数组长度的起始索引则从数组末尾开始找。
     * </p>
     *
     * @param array       要扫描的数组
     * @param floatToFind 要查找的元素
     * @param startIndex  起始索引
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(float[] array, float floatToFind, int startIndex) {
        return arrayLastIndexOf(array, floatToFind, startIndex, 0);
    }

    /**
     * 在数组中从末尾开始查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则返回<code>-1</code>,超出数组长度的起始索引则从数组末尾开始找。
     * </p>
     *
     * @param array       要扫描的数组
     * @param floatToFind 要查找的元素
     * @param startIndex  起始索引
     * @param tolerance   误差
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(float[] array, float floatToFind, int startIndex, float tolerance) {
        if (array == null) {
            return -1;
        }

        if (startIndex < 0) {
            return -1;
        } else if (startIndex >= array.length) {
            startIndex = array.length - 1;
        }

        float min = floatToFind - tolerance;
        float max = floatToFind + tolerance;

        for (int i = startIndex; i >= 0; i--) {
            if (array[i] >= min && array[i] <= max) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 在数组中从末尾开始查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则返回<code>-1</code>,超出数组长度的起始索引则从数组末尾开始找。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param startIndex  起始索引
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(float[] array, float[] arrayToFind, int startIndex) {
        return arrayLastIndexOf(array, arrayToFind, startIndex, 0);
    }

    /**
     * 在数组中从末尾开始查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则返回<code>-1</code>,超出数组长度的起始索引则从数组末尾开始找。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param startIndex  起始索引
     * @param tolerance   误差
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(float[] array, float[] arrayToFind, int startIndex, float tolerance) {
        if (array == null || arrayToFind == null) {
            return -1;
        }

        int sourceLength = array.length;
        int targetLength = arrayToFind.length;

        int rightIndex = sourceLength - targetLength;

        if (startIndex < 0) {
            return -1;
        }

        if (startIndex > rightIndex) {
            startIndex = rightIndex;
        }

        if (targetLength == 0) {
            return startIndex;
        }

        int lastIndex = targetLength - 1;
        float lastMin = arrayToFind[lastIndex] - tolerance;
        float lastMax = arrayToFind[lastIndex] + tolerance;
        int min = targetLength - 1;
        int i = min + startIndex;

        startSearchForLast:
        while (true) {
            while (i >= min && (array[i] < lastMin || array[i] > lastMax)) {
                i--;
            }

            if (i < min) {
                return -1;
            }

            int j = i - 1;
            int start = j - (targetLength - 1);
            int k = lastIndex - 1;

            while (j > start) {
                if (Math.abs(array[j--] - arrayToFind[k--]) > tolerance) {
                    i--;
                    continue startSearchForLast;
                }
            }

            return start + 1;
        }
    }

    /**
     * 判断指定对象是否存在于指定数组中。
     * <p>
     * 如果数组为<code>null</code>则返回<code>false</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param floatToFind 要查找的元素
     * @return 如果找到则返回<code>true</code>
     */
    public static boolean arrayContains(float[] array, float floatToFind) {
        return arrayIndexOf(array, floatToFind) != -1;
    }

    /**
     * 判断指定对象是否存在于指定数组中。
     * <p>
     * 如果数组为<code>null</code>则返回<code>false</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param floatToFind 要查找的元素
     * @param tolerance   误差
     * @return 如果找到则返回<code>true</code>
     */
    public static boolean arrayContains(float[] array, float floatToFind, float tolerance) {
        return arrayIndexOf(array, floatToFind, tolerance) != -1;
    }

    /**
     * 判断指定元素序列是否存在于指定数组中。
     * <p>
     * 如果数组为<code>null</code>则返回<code>false</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 如果找到则返回<code>true</code>
     */
    public static boolean arrayContains(float[] array, float[] arrayToFind) {
        return arrayIndexOf(array, arrayToFind) != -1;
    }

    /**
     * 判断指定元素序列是否存在于指定数组中。
     * <p>
     * 如果数组为<code>null</code>则返回<code>false</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param tolerance   误差
     * @return 如果找到则返回<code>true</code>
     */
    public static boolean arrayContains(float[] array, float[] arrayToFind, float tolerance) {
        return arrayIndexOf(array, arrayToFind, tolerance) != -1;
    }

    // ==========================================================================
    // 在数组中查找一个元素或一个元素序列。
    //
    // 类型:boolean[]
    // ==========================================================================

    /**
     * 在数组中查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array         要扫描的数组
     * @param booleanToFind 要查找的元素
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(boolean[] array, boolean booleanToFind) {
        return arrayIndexOf(array, booleanToFind, 0);
    }

    /**
     * 在数组中查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(boolean[] array, boolean[] arrayToFind) {
        return arrayIndexOf(array, arrayToFind, 0);
    }

    /**
     * 在数组中查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则看作<code>0</code>,超出数组长度的起始索引则返回<code>-1</code>。
     * </p>
     *
     * @param array         要扫描的数组
     * @param booleanToFind 要查找的元素
     * @param startIndex    起始索引
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(boolean[] array, boolean booleanToFind, int startIndex) {
        if (array == null) {
            return -1;
        }

        if (startIndex < 0) {
            startIndex = 0;
        }

        for (int i = startIndex; i < array.length; i++) {
            if (booleanToFind == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 在数组中查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则看作<code>0</code>,超出数组长度的起始索引则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param startIndex  起始索引
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(boolean[] array, boolean[] arrayToFind, int startIndex) {
        if (array == null || arrayToFind == null) {
            return -1;
        }

        int sourceLength = array.length;
        int targetLength = arrayToFind.length;

        if (startIndex >= sourceLength) {
            return targetLength == 0 ? sourceLength : -1;
        }

        if (startIndex < 0) {
            startIndex = 0;
        }

        if (targetLength == 0) {
            return startIndex;
        }

        boolean first = arrayToFind[0];
        int i = startIndex;
        int max = sourceLength - targetLength;

        startSearchForFirst:
        while (true) {
            // 查找第一个元素
            while (i <= max && array[i] != first) {
                i++;
            }

            if (i > max) {
                return -1;
            }

            // 已经找到第一个元素,接着找
            int j = i + 1;
            int end = j + targetLength - 1;
            int k = 1;

            while (j < end) {
                if (array[j++] != arrayToFind[k++]) {
                    i++;

                    // 重新查找第一个元素
                    continue startSearchForFirst;
                }
            }

            // 找到了
            return i;
        }
    }

    /**
     * 在数组中从末尾开始查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array         要扫描的数组
     * @param booleanToFind 要查找的元素
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(boolean[] array, boolean booleanToFind) {
        return arrayLastIndexOf(array, booleanToFind, Integer.MAX_VALUE);
    }

    /**
     * 在数组中从末尾开始查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(boolean[] array, boolean[] arrayToFind) {
        return arrayLastIndexOf(array, arrayToFind, Integer.MAX_VALUE);
    }

    /**
     * 在数组中从末尾开始查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则返回<code>-1</code>,超出数组长度的起始索引则从数组末尾开始找。
     * </p>
     *
     * @param array         要扫描的数组
     * @param booleanToFind 要查找的元素
     * @param startIndex    起始索引
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(boolean[] array, boolean booleanToFind, int startIndex) {
        if (array == null) {
            return -1;
        }

        if (startIndex < 0) {
            return -1;
        } else if (startIndex >= array.length) {
            startIndex = array.length - 1;
        }

        for (int i = startIndex; i >= 0; i--) {
            if (booleanToFind == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 在数组中从末尾开始查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则返回<code>-1</code>,超出数组长度的起始索引则从数组末尾开始找。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param startIndex  起始索引
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(boolean[] array, boolean[] arrayToFind, int startIndex) {
        if (array == null || arrayToFind == null) {
            return -1;
        }

        int sourceLength = array.length;
        int targetLength = arrayToFind.length;

        int rightIndex = sourceLength - targetLength;

        if (startIndex < 0) {
            return -1;
        }

        if (startIndex > rightIndex) {
            startIndex = rightIndex;
        }

        if (targetLength == 0) {
            return startIndex;
        }

        int lastIndex = targetLength - 1;
        boolean last = arrayToFind[lastIndex];
        int min = targetLength - 1;
        int i = min + startIndex;

        startSearchForLast:
        while (true) {
            while (i >= min && array[i] != last) {
                i--;
            }

            if (i < min) {
                return -1;
            }

            int j = i - 1;
            int start = j - (targetLength - 1);
            int k = lastIndex - 1;

            while (j > start) {
                if (array[j--] != arrayToFind[k--]) {
                    i--;
                    continue startSearchForLast;
                }
            }

            return start + 1;
        }
    }

    /**
     * 判断指定对象是否存在于指定数组中。
     * <p>
     * 如果数组为<code>null</code>则返回<code>false</code>。
     * </p>
     *
     * @param array         要扫描的数组
     * @param booleanToFind 要查找的元素
     * @return 如果找到则返回<code>true</code>
     */
    public static boolean arrayContains(boolean[] array, boolean booleanToFind) {
        return arrayIndexOf(array, booleanToFind) != -1;
    }

    /**
     * 判断指定元素序列是否存在于指定数组中。
     * <p>
     * 如果数组为<code>null</code>则返回<code>false</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 如果找到则返回<code>true</code>
     */
    public static boolean arrayContains(boolean[] array, boolean[] arrayToFind) {
        return arrayIndexOf(array, arrayToFind) != -1;
    }

    // ==========================================================================
    // 在数组中查找一个元素或一个元素序列。
    //
    // 类型:char[]
    // ==========================================================================

    /**
     * 在数组中查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array      要扫描的数组
     * @param charToFind 要查找的元素
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(char[] array, char charToFind) {
        return arrayIndexOf(array, charToFind, 0);
    }

    /**
     * 在数组中查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(char[] array, char[] arrayToFind) {
        return arrayIndexOf(array, arrayToFind, 0);
    }

    /**
     * 在数组中查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则看作<code>0</code>,超出数组长度的起始索引则返回<code>-1</code>。
     * </p>
     *
     * @param array      要扫描的数组
     * @param charToFind 要查找的元素
     * @param startIndex 起始索引
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(char[] array, char charToFind, int startIndex) {
        if (array == null) {
            return -1;
        }

        if (startIndex < 0) {
            startIndex = 0;
        }

        for (int i = startIndex; i < array.length; i++) {
            if (charToFind == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 在数组中查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则看作<code>0</code>,超出数组长度的起始索引则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param startIndex  起始索引
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayIndexOf(char[] array, char[] arrayToFind, int startIndex) {
        if (array == null || arrayToFind == null) {
            return -1;
        }

        int sourceLength = array.length;
        int targetLength = arrayToFind.length;

        if (startIndex >= sourceLength) {
            return targetLength == 0 ? sourceLength : -1;
        }

        if (startIndex < 0) {
            startIndex = 0;
        }

        if (targetLength == 0) {
            return startIndex;
        }

        char first = arrayToFind[0];
        int i = startIndex;
        int max = sourceLength - targetLength;

        startSearchForFirst:
        while (true) {
            // 查找第一个元素
            while (i <= max && array[i] != first) {
                i++;
            }

            if (i > max) {
                return -1;
            }

            // 已经找到第一个元素,接着找
            int j = i + 1;
            int end = j + targetLength - 1;
            int k = 1;

            while (j < end) {
                if (array[j++] != arrayToFind[k++]) {
                    i++;

                    // 重新查找第一个元素
                    continue startSearchForFirst;
                }
            }

            // 找到了
            return i;
        }
    }

    /**
     * 在数组中从末尾开始查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array      要扫描的数组
     * @param charToFind 要查找的元素
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(char[] array, char charToFind) {
        return arrayLastIndexOf(array, charToFind, Integer.MAX_VALUE);
    }

    /**
     * 在数组中从末尾开始查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(char[] array, char[] arrayToFind) {
        return arrayLastIndexOf(array, arrayToFind, Integer.MAX_VALUE);
    }

    /**
     * 在数组中从末尾开始查找一个元素。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则返回<code>-1</code>,超出数组长度的起始索引则从数组末尾开始找。
     * </p>
     *
     * @param array      要扫描的数组
     * @param charToFind 要查找的元素
     * @param startIndex 起始索引
     * @return 该元素在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(char[] array, char charToFind, int startIndex) {
        if (array == null) {
            return -1;
        }

        if (startIndex < 0) {
            return -1;
        } else if (startIndex >= array.length) {
            startIndex = array.length - 1;
        }

        for (int i = startIndex; i >= 0; i--) {
            if (charToFind == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 在数组中从末尾开始查找一个元素序列。
     * <p>
     * 如果未找到或数组为<code>null</code>则返回<code>-1</code>。
     * </p>
     * <p>
     * 起始索引小于<code>0</code>则返回<code>-1</code>,超出数组长度的起始索引则从数组末尾开始找。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @param startIndex  起始索引
     * @return 该元素序列在数组中的序号,如果数组为<code>null</code>或未找到,则返回<code>-1</code>。
     */
    public static int arrayLastIndexOf(char[] array, char[] arrayToFind, int startIndex) {
        if (array == null || arrayToFind == null) {
            return -1;
        }

        int sourceLength = array.length;
        int targetLength = arrayToFind.length;

        int rightIndex = sourceLength - targetLength;

        if (startIndex < 0) {
            return -1;
        }

        if (startIndex > rightIndex) {
            startIndex = rightIndex;
        }

        if (targetLength == 0) {
            return startIndex;
        }

        int lastIndex = targetLength - 1;
        char last = arrayToFind[lastIndex];
        int min = targetLength - 1;
        int i = min + startIndex;

        startSearchForLast:
        while (true) {
            while (i >= min && array[i] != last) {
                i--;
            }

            if (i < min) {
                return -1;
            }

            int j = i - 1;
            int start = j - (targetLength - 1);
            int k = lastIndex - 1;

            while (j > start) {
                if (array[j--] != arrayToFind[k--]) {
                    i--;
                    continue startSearchForLast;
                }
            }

            return start + 1;
        }
    }

    /**
     * 判断指定对象是否存在于指定数组中。
     * <p>
     * 如果数组为<code>null</code>则返回<code>false</code>。
     * </p>
     *
     * @param array      要扫描的数组
     * @param charToFind 要查找的元素
     * @return 如果找到则返回<code>true</code>
     */
    public static boolean arrayContains(char[] array, char charToFind) {
        return arrayIndexOf(array, charToFind) != -1;
    }

    /**
     * 判断指定元素序列是否存在于指定数组中。
     * <p>
     * 如果数组为<code>null</code>则返回<code>false</code>。
     * </p>
     *
     * @param array       要扫描的数组
     * @param arrayToFind 要查找的元素序列
     * @return 如果找到则返回<code>true</code>
     */
    public static boolean arrayContains(char[] array, char[] arrayToFind) {
        return arrayIndexOf(array, arrayToFind) != -1;
    }
}

 

分享到:
评论

相关推荐

    js 数组工具类 ArrayUtil

    ArrayUtil是一个实用的JavaScript工具类,它提供了一系列方便的方法,以帮助开发者更高效地处理数组操作。这个工具类通常包含各种自定义的数组函数,以弥补JavaScript内置数组方法的不足。接下来,我们将深入探讨...

    ArrayUtil+DateUtil+FileUtil+ReguUtil+StringUtil

    这里提到的"ArrayUtil+DateUtil+FileUtil+ReguUtil+StringUtil"是五个这样的工具包,它们分别针对数组操作、日期处理、文件操作、正则表达式匹配和字符串操作提供了一系列便利的方法。 1. **ArrayUtil**: - **...

    go-arrayutil:Go 数组的实用函数集合,灵感来自 Ruby 的 Array 函数

    阵列工具-- 导入“github.com/atedja/go-arrayutil”用法功能紧凑 func Compact ( arr [] interface {}) [] interface {} 从数组中删除 nil 值。 例子: var arr = []interface{}{1, 2, 3, 4, nil, 5}result := ...

    ArrayUtil.java

    输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分, 所有偶数位于数组的后半部分。要求时间复杂度为O(n)

    计算机后端-Java-Java核心基础-第15章 面向对象07 11. 自定义ArrayUtil工具类的优化.avi

    计算机后端-Java-Java核心基础-第15章 面向对象07 11. 自定义ArrayUtil工具类的优化.avi

    StringUtil

    Java字符串工具类。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

    Java常用ArrayUtile工具类

    ### Java常用ArrayUtil工具类知识点解析 #### 一、判断数组是否为空(null或长度为0) **功能:** 此方法用于检查一个对象数组是否为空。如果数组为`null`或者数组的长度为0,则认为该数组为空。 **代码实现:** ...

    JDK7源码 包含rt.jar包下的 sun包源码 sun.security包等源码

    在Java开发领域,JDK(Java Development Kit)是不可或缺的基础工具,它包含了Java运行环境、编译器以及各种工具。JDK7版本是Java历史上的一个重要里程碑,引入了许多新特性和改进。本压缩包提供了JDK7的源码,特别...

    机试题.docx

    b) ArrayUtil 类(30 分): 在 com.xc 包下,考生需要创建 ArrayUtil 类,该类中包含三个方法: 1. arrayTest 方法(10 分):在该方法中,考生需要定义一个一维数组 int[] array = {22,13,19,12,11,46,15,26},...

    flex学习笔记,技巧学习

    这里假设`bookdata`已经定义为某种类型的数据结构(例如数据集或对象),通过`ArrayUtil.toArray()`将其转换为数组形式,以便于后续处理。 #### 使用ArrayCollection管理数据 - **`ArrayCollection`**: Flex中非常...

    给程序员用的基于Java语言的工具集canoe-util-master.zip

    1. ArrayUtil:提供数组的扩展操作,如查找、复制、合并等,同时支持多维数组操作。 2. CollectionUtil:集合相关的辅助工具,包括集合的创建、遍历、比较以及集合元素的转换等。 3. StringUtil:提供字符串的高级...

    Java软件开发实战 Java基础与案例开发详解 4-2 数组应用 共16页.pdf

    ArrayUtil.printArray(myArray); } } ``` #### 七、总结 通过对《Java软件开发实战》第四章第二节的学习,我们深入了解了数组的基本概念及其在求解平均值、最大值、最小值等问题中的应用。同时,还介绍了数组排序...

    Flash与Flex3结合学习心得体会

    - Adobe提供了一系列的Utils包,如ArrayUtil、StringUtil、DateUtil、NumberFormatter和DictionaryUtil等,这些工具类包含了各种实用方法,例如字符串处理、数组操作、日期比较和格式化数字等。 - 例如,ArrayUtil...

    Java语言基础入门教程 Java实训教程 5.类属性及类方法定义 共40页.pptx

    int total = ArrayUtil.sum(1, 2, 3, 4, 5); // 调用变参方法 ``` 综上所述,Java中的类属性和类方法是面向对象编程的基本组成部分,它们共同构成了类的概念,使得开发者能够更好地组织代码,实现模块化编程。通过...

    java数组函数(摘自JAVA编程思想)

    Java 8引入了方法引用的概念,我们可以直接用ArrayUtil的函数名来调用其方法,如`Arrays::sort`进行排序,简化代码: ```java Arrays.sort(numbers); ``` 7. **安全的数组操作** 在`com.bruceeckel.util`包中...

    Access Objects from Velocity

    - `arrayUtil`:提供数组操作的工具类。 - `browserSniffer`:用于浏览器检测。 - `dateFormats`、`dateTool`、`dateUtiles`:提供日期格式化和工具类。 - `escapeTool`:提供HTML和JavaScript的转义工具。 - `...

    javaSE基础强化,自写自用

    数组工具类`ArrayUtil`可以包含静态方法来处理数组,如转换数组为字符串表示,校验数组是否为空等。 总之,JavaSE基础强化主要涉及强类型语言的理解、权限修饰符的应用、面向对象的特性,特别是静态关键字的使用,...

    as3corelib-.92.11.rar_as 3 corelib_as3_as3corelib_as3corelib API

    2. 数组运算:AS3CoreLib提供了一些增强的数组操作方法,例如`ArrayUtil`类,它包括了排序、查找、去重等实用功能。这些工具可以简化对数组的操作,提高代码的可读性和效率。 3. 网络连接:库中的`Net`类提供了一套...

Global site tag (gtag.js) - Google Analytics