package com.vip.vjtools.vjkit.collection; import java.lang.reflect.Array; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Random; import com.google.common.collect.ObjectArrays; import com.google.common.primitives.Doubles; import com.google.common.primitives.Ints; import com.google.common.primitives.Longs; import com.vip.vjtools.vjkit.base.annotation.Nullable; /** * 数组工具类. * * 1. 创建Array的函数 * * 2. 数组的乱序与contact相加 * * 3. 从Array转换到Guava的底层为原子类型的List * * JDK Arrays的其他函数,如sort(), toString() 请直接调用 * * Common Lang ArrayUtils的其他函数,如subarray(),reverse(),indexOf(), 请直接调用 */ public class ArrayUtil { /** * 传入类型与大小创建数组. * * Array.newInstance()的性能并不差 */ @SuppressWarnings("unchecked") public static <T> T[] newArray(Class<T> type, int length) { return (T[]) Array.newInstance(type, length); } /** * 从collection转为Array, 以 list.toArray(new String[0]); 最快 不需要创建list.size()的数组. * * 本函数等价于list.toArray(new String[0]); 用户也可以直接用后者. * * https://shipilev.net/blog/2016/arrays-wisdom-ancients/ */ @SuppressWarnings("unchecked") public static <T> T[] toArray(Collection<T> col, Class<T> type) { return col.toArray((T[]) Array.newInstance(type, 0)); } /** * Swaps the two specified elements in the specified array. */ private static void swap(Object[] arr, int i, int j) { Object tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } /** * 将传入的数组乱序 */ public static <T> T[] shuffle(T[] array) { if (array != null && array.length > 1) { Random rand = new Random(); return shuffle(array, rand); } else { return array; } } /** * 将传入的数组乱序 */ public static <T> T[] shuffle(T[] array, Random random) { if (array != null && array.length > 1 && random != null) { for (int i = array.length; i > 1; i--) { swap(array, i - 1, random.nextInt(i)); } } return array; } /** * 添加元素到数组头. */ public static <T> T[] concat(@Nullable T element, T[] array) { return ObjectArrays.concat(element, array); } /** * 添加元素到数组末尾. */ public static <T> T[] concat(T[] array, @Nullable T element) { return ObjectArrays.concat(array, element); } ////////////////// guava Array 转换为底层为原子类型的List /////////// /** * 原版将数组转换为List. * * 注意转换后的List不能写入, 否则抛出UnsupportedOperationException * * @see java.util.Arrays#asList(Object...) */ public static <T> List<T> asList(T... a) { return Arrays.asList(a); } /** * Arrays.asList()的加强版, 返回一个底层为原始类型int的List * * 与保存Integer相比节约空间,同时只在读取数据时AutoBoxing. * * @see java.util.Arrays#asList(Object...) * @see com.google.common.primitives.Ints#asList(int...) * */ public static List<Integer> intAsList(int... backingArray) { return Ints.asList(backingArray); } /** * Arrays.asList()的加强版, 返回一个底层为原始类型long的List * * 与保存Long相比节约空间,同时只在读取数据时AutoBoxing. * * @see java.util.Arrays#asList(Object...) * @see com.google.common.primitives.Longs#asList(long...) */ public static List<Long> longAsList(long... backingArray) { return Longs.asList(backingArray); } /** * Arrays.asList()的加强版, 返回一个底层为原始类型double的List * * 与保存Double相比节约空间,同时也避免了AutoBoxing. * * @see java.util.Arrays#asList(Object...) * @see com.google.common.primitives.Doubles#asList(double...) */ public static List<Double> doubleAsList(double... backingArray) { return Doubles.asList(backingArray); } }