All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.moon.core.lang.ArrayUtil Maven / Gradle / Ivy

package com.moon.core.lang;

import com.moon.core.util.CollectUtil;
import com.moon.core.util.ListUtil;
import com.moon.core.util.function.BiIntConsumer;
import com.moon.core.util.function.BiIntFunction;
import com.moon.core.util.function.TableIntConsumer;
import com.moon.core.util.function.TableIntFunction;

import java.lang.reflect.Array;
import java.util.*;
import java.util.function.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.moon.core.lang.ThrowUtil.noInstanceError;

/**
 * @author moonsky
 */
public final class ArrayUtil {

    private ArrayUtil() { noInstanceError(); }

    private static  T ifNonNull(T value, Consumer consumer) {
        if (value != null) { consumer.accept(value); }
        return value;
    }

    public static String stringify(Object arr) {
        if (arr == null) { return null; }
        if (arr instanceof Object[]) {return Arrays.deepToString((Object[]) arr);}
        if (arr instanceof int[]) {return Arrays.toString((int[]) arr);}
        if (arr instanceof long[]) {return Arrays.toString((long[]) arr);}
        if (arr instanceof double[]) {return Arrays.toString((double[]) arr);}
        if (arr instanceof byte[]) {return Arrays.toString((byte[]) arr);}
        if (arr instanceof char[]) {return Arrays.toString((char[]) arr);}
        if (arr instanceof short[]) {return Arrays.toString((short[]) arr);}
        if (arr instanceof boolean[]) {return Arrays.toString((boolean[]) arr);}
        return arr.toString();
    }

    /*
     * ----------------------------------------------------------------
     * with
     * ----------------------------------------------------------------
     */

    @SafeVarargs
    public static  T[] toArray(T... values) { return values; }

    public static char[] toArray(char... values) { return values; }

    public static byte[] toArray(byte... values) { return values; }

    public static short[] toArray(short... values) { return values; }

    public static int[] toArray(int... values) { return values; }

    public static long[] toArray(long... values) { return values; }

    public static float[] toArray(float... values) { return values; }

    public static double[] toArray(double... values) { return values; }

    public static boolean[] toArray(boolean... values) { return values; }

    /*
     * ----------------------------------------------------------------
     * sort
     * ----------------------------------------------------------------
     */

    @SafeVarargs
    public static  T[] sort(T... values) { return ifNonNull(values, Arrays::sort); }

    public static char[] sort(char... values) { return ifNonNull(values, Arrays::sort); }

    public static byte[] sort(byte... values) { return ifNonNull(values, Arrays::sort); }

    public static short[] sort(short... values) { return ifNonNull(values, Arrays::sort); }

    public static int[] sort(int... values) { return ifNonNull(values, Arrays::sort); }

    public static long[] sort(long... values) { return ifNonNull(values, Arrays::sort); }

    public static float[] sort(float... values) { return ifNonNull(values, Arrays::sort); }

    public static double[] sort(double... values) { return ifNonNull(values, Arrays::sort); }

    /*
     * ----------------------------------------------------------------
     * sort
     * ----------------------------------------------------------------
     */

    @SafeVarargs
    public static  T[] sort(Comparator comparator, T... values) {
        if (values != null) { Arrays.sort(values, comparator); }
        return values;
    }

    /*
     * ----------------------------------------------------------------
     * reverse
     * ----------------------------------------------------------------
     */

    @SuppressWarnings("all")
    public static  T[] reverse(T... values) {
        if (values == null) {
            return null;
        }
        T[] items = values;
        T cache;
        for (int i = 0, two = 2, len = items.length, half = len-- / two; i < half; i++) {
            cache = items[len - i];
            items[len - i] = items[i];
            items[i] = cache;
        }
        return items;
    }

    @SuppressWarnings("all")
    public static char[] reverse(char... values) {
        if (values == null) {
            return null;
        }
        char[] items = values;
        char cache;
        for (int i = 0, two = 2, len = items.length, half = len-- / two; i < half; i++) {
            cache = items[len - i];
            items[len - i] = items[i];
            items[i] = cache;
        }
        return items;
    }

    @SuppressWarnings("all")
    public static byte[] reverse(byte... values) {
        if (values == null) {
            return null;
        }
        byte[] items = values;
        byte cache;
        for (int i = 0, two = 2, len = items.length, half = len-- / two; i < half; i++) {
            cache = items[len - i];
            items[len - i] = items[i];
            items[i] = cache;
        }
        return items;
    }

    @SuppressWarnings("all")
    public static int[] reverse(int... values) {
        if (values == null) {
            return null;
        }
        int[] items = values;
        int cache;
        for (int i = 0, two = 2, len = items.length, half = len-- / two; i < half; i++) {
            cache = items[len - i];
            items[len - i] = items[i];
            items[i] = cache;
        }
        return items;
    }

    @SuppressWarnings("all")
    public static long[] reverse(long... values) {
        if (values == null) {
            return null;
        }
        long[] items = values;
        long cache;
        for (int i = 0, two = 2, len = items.length, half = len-- / two; i < half; i++) {
            cache = items[len - i];
            items[len - i] = items[i];
            items[i] = cache;
        }
        return items;
    }

    @SuppressWarnings("all")
    public static double[] reverse(double... values) {
        if (values == null) {
            return null;
        }
        double[] items = values;
        double cache;
        for (int i = 0, two = 2, len = items.length, half = len-- / two; i < half; i++) {
            cache = items[len - i];
            items[len - i] = items[i];
            items[i] = cache;
        }
        return items;
    }

    /*
     * ----------------------------------------------------------------
     * get array type
     * ----------------------------------------------------------------
     */

    public static Class getArrayType(Class componentType) {
        return Array.newInstance(componentType, 0).getClass();
    }

    /*
     * ----------------------------------------------------------------
     * length
     * ----------------------------------------------------------------
     */

    public static int length(Object[] arr) { return arr == null ? 0 : arr.length; }

    public static int length(boolean[] arr) { return arr == null ? 0 : arr.length; }

    public static int length(double[] arr) { return arr == null ? 0 : arr.length; }

    public static int length(float[] arr) { return arr == null ? 0 : arr.length; }

    public static int length(long[] arr) { return arr == null ? 0 : arr.length; }

    public static int length(int[] arr) { return arr == null ? 0 : arr.length; }

    public static int length(short[] arr) { return arr == null ? 0 : arr.length; }

    public static int length(byte[] arr) { return arr == null ? 0 : arr.length; }

    public static int length(char[] arr) { return arr == null ? 0 : arr.length; }

    @SafeVarargs
    public static  boolean isEmpty(T... arr) { return length(arr) == 0; }

    public static boolean isEmpty(double... arr) { return length(arr) == 0; }

    public static boolean isEmpty(long... arr) { return length(arr) == 0; }

    public static boolean isEmpty(int... arr) { return length(arr) == 0; }

    public static boolean isEmpty(byte... arr) { return length(arr) == 0; }

    public static boolean isEmpty(char... arr) { return length(arr) == 0; }

    public static boolean isEmpty(float... arr) { return length(arr) == 0; }

    public static boolean isEmpty(short... arr) { return length(arr) == 0; }

    public static boolean isEmpty(boolean... arr) { return length(arr) == 0; }

    @SafeVarargs
    public static  boolean isNotEmpty(T... arr) { return length(arr) > 0; }

    public static boolean isNotEmpty(double... arr) { return length(arr) > 0; }

    public static boolean isNotEmpty(long... arr) { return length(arr) > 0; }

    public static boolean isNotEmpty(int... arr) { return length(arr) > 0; }

    public static boolean isNotEmpty(byte... arr) { return length(arr) > 0; }

    public static boolean isNotEmpty(char... arr) { return length(arr) > 0; }

    public static boolean isNotEmpty(float... arr) { return length(arr) > 0; }

    public static boolean isNotEmpty(short... arr) { return length(arr) > 0; }

    public static boolean isNotEmpty(boolean... arr) { return length(arr) > 0; }

    /*
     * ----------------------------------------------------------------
     * fill
     * ----------------------------------------------------------------
     */

    public static  T[] fill(T[] arr, T value) { return fillBegin(arr, 0, value); }

    public static boolean[] fill(boolean[] arr, boolean value) { return fillBegin(arr, 0, value); }

    public static double[] fill(double[] arr, double value) { return fillBegin(arr, 0, value); }

    public static float[] fill(float[] arr, float value) { return fillBegin(arr, 0, value); }

    public static long[] fill(long[] arr, long value) { return fillBegin(arr, 0, value); }

    public static int[] fill(int[] arr, int value) { return fillBegin(arr, 0, value); }

    public static short[] fill(short[] arr, short value) { return fillBegin(arr, 0, value); }

    public static byte[] fill(byte[] arr, byte value) { return fillBegin(arr, 0, value); }

    public static char[] fill(char[] arr, char value) { return fillBegin(arr, 0, value); }

    /*
     * ----------------------------------------------------------------
     * fill from
     * ----------------------------------------------------------------
     */

    public static  T[] fillBegin(T[] arr, int fromIndex, T value) {
        return fill(arr, fromIndex, length(arr), value);
    }

    public static boolean[] fillBegin(boolean[] arr, int fromIndex, boolean value) {
        return fill(arr, fromIndex, length(arr), value);
    }

    public static double[] fillBegin(double[] arr, int fromIndex, double value) {
        return fill(arr, fromIndex, length(arr), value);
    }

    public static float[] fillBegin(float[] arr, int fromIndex, float value) {
        return fill(arr, fromIndex, length(arr), value);
    }

    public static long[] fillBegin(long[] arr, int fromIndex, long value) {
        return fill(arr, fromIndex, length(arr), value);
    }

    public static int[] fillBegin(int[] arr, int fromIndex, int value) {
        return fill(arr, fromIndex, length(arr), value);
    }

    public static short[] fillBegin(short[] arr, int fromIndex, short value) {
        return fill(arr, fromIndex, length(arr), value);
    }

    public static byte[] fillBegin(byte[] arr, int fromIndex, byte value) {
        return fill(arr, fromIndex, length(arr), value);
    }

    public static char[] fillBegin(char[] arr, int fromIndex, char value) {
        return fill(arr, fromIndex, length(arr), value);
    }

    /*
     * ----------------------------------------------------------------
     * fill to; 纯粹为了一个返回值
     * ----------------------------------------------------------------
     */

    public static  T[] fill(T[] arr, int fromIndex, int toIndex, T value) {
        Arrays.fill(arr, fromIndex, toIndex, value);
        return arr;
    }

    public static boolean[] fill(boolean[] arr, int fromIndex, int toIndex, boolean value) {
        Arrays.fill(arr, fromIndex, toIndex, value);
        return arr;
    }

    public static double[] fill(double[] arr, int fromIndex, int toIndex, double value) {
        Arrays.fill(arr, fromIndex, toIndex, value);
        return arr;
    }

    public static float[] fill(float[] arr, int fromIndex, int toIndex, float value) {
        Arrays.fill(arr, fromIndex, toIndex, value);
        return arr;
    }

    public static long[] fill(long[] arr, int fromIndex, int toIndex, long value) {
        Arrays.fill(arr, fromIndex, toIndex, value);
        return arr;
    }

    public static int[] fill(int[] arr, int fromIndex, int toIndex, int value) {
        Arrays.fill(arr, fromIndex, toIndex, value);
        return arr;
    }

    public static short[] fill(short[] arr, int fromIndex, int toIndex, short value) {
        Arrays.fill(arr, fromIndex, toIndex, value);
        return arr;
    }

    public static byte[] fill(byte[] arr, int fromIndex, int toIndex, byte value) {
        Arrays.fill(arr, fromIndex, toIndex, value);
        return arr;
    }

    public static char[] fill(char[] arr, int fromIndex, int toIndex, char value) {
        Arrays.fill(arr, fromIndex, toIndex, value);
        return arr;
    }

    /*
     * ----------------------------------------------------------------
     * remove index, 删除指定位置数据,后面的数据前移一位; 返回原数组
     * ----------------------------------------------------------------
     */

    public static  T[] remove(T[] arr, int index) {
        arr[clearIdxAndGetLastIdx(arr, arr.length, index)] = null;
        return arr;
    }

    public static boolean[] remove(boolean[] arr, int index) {
        arr[clearIdxAndGetLastIdx(arr, arr.length, index)] = false;
        return arr;
    }

    public static double[] remove(double[] arr, int index) {
        arr[clearIdxAndGetLastIdx(arr, arr.length, index)] = 0;
        return arr;
    }

    public static float[] remove(float[] arr, int index) {
        arr[clearIdxAndGetLastIdx(arr, arr.length, index)] = 0;
        return arr;
    }

    public static long[] remove(long[] arr, int index) {
        arr[clearIdxAndGetLastIdx(arr, arr.length, index)] = 0;
        return arr;
    }

    public static int[] remove(int[] arr, int index) {
        arr[clearIdxAndGetLastIdx(arr, arr.length, index)] = 0;
        return arr;
    }

    public static short[] remove(short[] arr, int index) {
        arr[clearIdxAndGetLastIdx(arr, arr.length, index)] = 0;
        return arr;
    }

    public static byte[] remove(byte[] arr, int index) {
        arr[clearIdxAndGetLastIdx(arr, arr.length, index)] = 0;
        return arr;
    }

    public static char[] remove(char[] arr, int index) {
        arr[clearIdxAndGetLastIdx(arr, arr.length, index)] = 0;
        return arr;
    }

    private static int clearIdxAndGetLastIdx(Object arr, int length, int index) {
        int lastIndex = length - 1;
        System.arraycopy(arr, index + 1, arr, index, lastIndex - index);
        return lastIndex;
    }

    /*
     * ----------------------------------------------------------------
     * splice : 总是返回一个新数组
     * ----------------------------------------------------------------
     */

    public static  T[] splice(T[] arr, int fromIndex, int count, T... elements) {
        return (T[]) spliceArray(arr,
            arr.length,
            elements,
            elements.length,
            fromIndex,
            count,
            l -> Array.newInstance(arr.getClass().getComponentType(), l));
    }

    public static boolean[] splice(boolean[] arr, int fromIndex, int count, boolean... elements) {
        return (boolean[]) spliceArray(arr, arr.length, elements, elements.length, fromIndex, count, boolean[]::new);
    }

    public static char[] splice(char[] arr, int fromIndex, int count, char... elements) {
        return (char[]) spliceArray(arr, arr.length, elements, elements.length, fromIndex, count, char[]::new);
    }

    public static byte[] splice(byte[] arr, int fromIndex, int count, byte... elements) {
        return (byte[]) spliceArray(arr, arr.length, elements, elements.length, fromIndex, count, byte[]::new);
    }

    public static short[] splice(short[] arr, int fromIndex, int count, short... elements) {
        return (short[]) spliceArray(arr, arr.length, elements, elements.length, fromIndex, count, short[]::new);
    }

    public static int[] splice(int[] arr, int fromIndex, int count, int... elements) {
        return (int[]) spliceArray(arr, arr.length, elements, elements.length, fromIndex, count, int[]::new);
    }

    public static long[] splice(long[] arr, int fromIndex, int count, long... elements) {
        return (long[]) spliceArray(arr, arr.length, elements, elements.length, fromIndex, count, long[]::new);
    }

    public static float[] splice(float[] arr, int fromIndex, int count, float... elements) {
        return (float[]) spliceArray(arr, arr.length, elements, elements.length, fromIndex, count, float[]::new);
    }

    public static double[] splice(double[] arr, int fromIndex, int count, double... elements) {
        return (double[]) spliceArray(arr, arr.length, elements, elements.length, fromIndex, count, double[]::new);
    }

    private static Object spliceArray(
        Object arr, int arrLen, Object elements, int elementsLen, int fromIndex, int count, IntFunction creator
    ) {
        if (fromIndex < 0) {
            throw new ArrayIndexOutOfBoundsException("Invalid value of fromIndex: " + count);
        }
        if (count < 0) {
            throw new ArrayIndexOutOfBoundsException("Invalid value of count: " + count);
        }
        Object value = creator.apply(arrLen + elementsLen - count);
        System.arraycopy(arr, 0, value, 0, fromIndex);
        System.arraycopy(elements, 0, value, fromIndex, elementsLen);
        if ((count = fromIndex + count) < arrLen) {
            System.arraycopy(arr, count, value, fromIndex + elementsLen, arrLen - count);
        }
        return value;
    }

    /*
     * ----------------------------------------------------------------
     * to primitives
     * ----------------------------------------------------------------
     */

    public static boolean[] toPrimitives(Boolean[] value) { return transformArray(value, boolean[]::new); }

    public static char[] toPrimitives(Character[] value) { return transformArray(value, char[]::new); }

    public static byte[] toPrimitives(Byte[] value) { return transformArray(value, byte[]::new); }

    public static short[] toPrimitives(Short[] value) { return transformArray(value, short[]::new); }

    public static int[] toPrimitives(Integer[] value) { return transformArray(value, int[]::new); }

    public static long[] toPrimitives(Long[] value) { return transformArray(value, long[]::new); }

    public static float[] toPrimitives(Float[] value) { return transformArray(value, float[]::new); }

    public static double[] toPrimitives(Double[] value) { return transformArray(value, double[]::new); }

    /*
     * ----------------------------------------------------------------
     * to objects
     * ----------------------------------------------------------------
     */

    public static Boolean[] toObjects(boolean[] value) { return transformArray(value, Boolean[]::new); }

    public static Character[] toObjects(char[] value) { return transformArray(value, Character[]::new); }

    public static Byte[] toObjects(byte[] value) { return transformArray(value, Byte[]::new); }

    public static Short[] toObjects(short[] value) { return transformArray(value, Short[]::new); }

    public static Integer[] toObjects(int[] value) { return transformArray(value, Integer[]::new); }

    public static Long[] toObjects(long[] value) { return transformArray(value, Long[]::new); }

    public static Float[] toObjects(float[] value) { return transformArray(value, Float[]::new); }

    public static Double[] toObjects(double[] value) { return transformArray(value, Double[]::new); }

    private static  T transformArray(Object value, IntFunction creator) {
        if (value == null) { return null; }
        final int length = Array.getLength(value);
        T arr = creator.apply(length);
        System.arraycopy(value, 0, arr, 0, length);
        return arr;
    }

    public static Object[] toObjectArray(Object value) {
        if (value == null || value instanceof Object[]) {
            return (Object[]) value;
        }
        if (value.getClass().isArray()) {
            int length = Array.getLength(value);
            Object[] result = new Object[length];
            System.arraycopy(value, 0, result, 0, length);
            return result;
        }
        Collection collect = null;
        if (value instanceof Iterable) {
            if (value instanceof Collection) {
                collect = (Collection) value;
            } else {
                collect = ListUtil.newList((Iterable) value);
            }
        } else if (value instanceof Iterator) {
            collect = ListUtil.newList((Iterator) value);
        } else if (value instanceof Stream) {
            collect = (Collection) ((Stream) value).collect(Collectors.toList());
        }
        if (collect != null) {
            return CollectUtil.toArray(collect, Object[]::new);
        }
        Object[] objects = new Object[1];
        objects[0] = value;
        return objects;
    }

    @SafeVarargs
    public static  List mapBy(Function mapper, D... dataArr) {
        List result = new ArrayList<>();
        int length = length(dataArr);
        for (int i = 0; i < length; i++) {
            result.add(mapper.apply(dataArr[i]));
        }
        return result;
    }

    /*
     * 属性求和
     */

    public static  int sum(T[] arr, ToIntFunction getter) {
        int length = length(arr), total = 0;
        for (int i = 0; i < length; i++) {
            total += getter.applyAsInt(arr[i]);
        }
        return total;
    }

    public static  long sumAsLong(T[] arr, ToLongFunction getter) {
        int length = length(arr);
        long total = 0;
        for (int i = 0; i < length; i++) {
            total += getter.applyAsLong(arr[i]);
        }
        return total;
    }

    public static  double sumAsDouble(T[] arr, ToDoubleFunction getter) {
        int length = length(arr);
        double total = 0;
        for (int i = 0; i < length; i++) {
            total += getter.applyAsDouble(arr[i]);
        }
        return total;
    }

    /*
     reduce
     */

    /**
     * 聚合函数,参照 JavaScript 中 Array.reduce(..) 实现
     * 
     * 1. 接受一个数组作为源数据;
     * 2. 一个处理器,处理器接收两个参数(总值, 当前项);
     *       其中当前项也是索引,索引相对{@link #reduce(int, BiIntFunction, Object)}少一个参数
     * 3. 初始值,作为第一次传入处理器的参数,也是最后返回结果
     * 
* * @param count 迭代次数 * @param reducer 聚合函数 * @param totalValue 返回结果 * @param 返回值类型 * * @return 返回最后一项处理完后的结果 * * @see #reduce(Object[], TableIntFunction, Object) * @see CollectUtil#reduce(Iterable, TableIntFunction, Object) * @see CollectUtil#reduce(Iterator, TableIntFunction, Object) */ public static T reduce(int count, BiIntFunction reducer, T totalValue) { return IntUtil.reduce(count, reducer, totalValue); } /** * 聚合函数,参照 JavaScript 中 Array.reduce(..) 实现 *
     * 1. 接受一个数组作为源数据;
     * 2. 一个处理器,处理器接收三个参数(总值, 当前项, 索引),返回值作为下一次的总值,最终返回值是函数返回值;
     * 3. 初始值,作为第一次传入处理器的参数,也是最后返回结果
     * 
* * @param arr 入参数组 * @param reducer 聚合函数 * @param totalValue 返回结果 * @param 返回值类型 * @param 迭代器单项数据类型 * * @return 返回最后一项处理完后的结果 * * @see #reduce(int, BiIntFunction, Object) * @see CollectUtil#reduce(Iterable, TableIntFunction, Object) * @see CollectUtil#reduce(Iterator, TableIntFunction, Object) */ public static T reduce(E[] arr, TableIntFunction reducer, T totalValue) { if (arr != null) { for (int i = 0, len = arr.length; i < len; i++) { totalValue = reducer.apply(totalValue, arr[i], i); } } return totalValue; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy