218 lines
7.1 KiB
Java
218 lines
7.1 KiB
Java
package tc.oc.commons.core.util;
|
|
|
|
import java.lang.reflect.Array;
|
|
import java.lang.reflect.Method;
|
|
import java.util.AbstractList;
|
|
import java.util.Arrays;
|
|
import java.util.List;
|
|
import java.util.function.Function;
|
|
import java.util.function.Predicate;
|
|
import javax.annotation.Nullable;
|
|
|
|
import tc.oc.commons.core.reflect.Methods;
|
|
|
|
public class ArrayUtils {
|
|
private ArrayUtils() {}
|
|
|
|
public static final int NOT_FOUND_INDEX = -1;
|
|
|
|
public static <T> T fromEnd(T[] array, int index) {
|
|
return array[array.length - 1 - index];
|
|
}
|
|
|
|
public static <T> int indexOf(T[] array, T value) {
|
|
if(array == null) return NOT_FOUND_INDEX;
|
|
|
|
if(value == null) {
|
|
for(int i = 0; i < array.length; i++) {
|
|
if(array[i] == null) return i;
|
|
}
|
|
} else {
|
|
for(int i = 0; i < array.length; i++) {
|
|
if(value.equals(array[i])) return i;
|
|
}
|
|
}
|
|
|
|
return NOT_FOUND_INDEX;
|
|
}
|
|
|
|
public static <T> boolean contains(T[] array, T value) {
|
|
return indexOf(array, value) != NOT_FOUND_INDEX;
|
|
}
|
|
|
|
/**
|
|
* Create a new array of given size, with the same component type as the given array
|
|
*/
|
|
public static <T> T[] sameType(T[] array, int size) {
|
|
return (T[]) Array.newInstance(array.getClass().getComponentType(), size);
|
|
}
|
|
|
|
/**
|
|
* Similar to {@link Arrays#copyOfRange}, but from can be negative,
|
|
* which will copy to an offset in the destination array.
|
|
*/
|
|
public static <T> T[] copyOfRange(T[] src, int from, int to) {
|
|
final T[] dest = sameType(src, to - from);
|
|
System.arraycopy(src, Math.max(0, from),
|
|
dest, Math.max(0, -from),
|
|
Math.min(to, src.length));
|
|
return dest;
|
|
}
|
|
|
|
public static <T> T[] append(T[] a, T...b) {
|
|
if(b.length == 0) return a;
|
|
if(a.length == 0) return b;
|
|
|
|
T[] result = Arrays.copyOf(a, a.length + b.length);
|
|
System.arraycopy(b, 0, result, a.length, b.length);
|
|
return result;
|
|
}
|
|
|
|
public static <T> T[] prepend(T element, T[] array) {
|
|
final T[] result = copyOfRange(array, -1, array.length);
|
|
result[0] = element;
|
|
return result;
|
|
}
|
|
|
|
public static <T> void copy(Iterable<? extends T> src, T[] dest, int destPos) {
|
|
for(T t : src) {
|
|
if(destPos >= dest.length) break;
|
|
dest[destPos++] = t;
|
|
}
|
|
}
|
|
|
|
public static <T> T first(T[] array, Predicate<T> test, T def) {
|
|
for(T t : array) {
|
|
if(test.test(t)) return t;
|
|
}
|
|
return def;
|
|
}
|
|
|
|
public static @Nullable <T> T first(T[] array, Predicate<T> test) {
|
|
return first(array, test, null);
|
|
}
|
|
|
|
private static final Method APPLY_METHOD = Methods.method(Function.class, "apply", Object.class);
|
|
|
|
public static <T, U> U[] transform(T[] input, Class<U> outputType, Function<T, U> function) {
|
|
return transform(input, (U[]) Array.newInstance(outputType, input.length), function);
|
|
}
|
|
|
|
public static <T, U> U[] transform(T[] input, U[] output, Function<T, U> function) {
|
|
for(int i = 0; i < input.length; i++) {
|
|
output[i] = function.apply(input[i]);
|
|
}
|
|
return output;
|
|
}
|
|
|
|
private static final Object[] EMPTY_OBJECT_ARRAY = new Object[]{};
|
|
public static Object[] zeroObjects() { return EMPTY_OBJECT_ARRAY; }
|
|
|
|
public static List<Boolean> asList(boolean[] array) {
|
|
return new AbstractList<Boolean>() {
|
|
@Override public int size() { return array.length; }
|
|
@Override public Boolean get(int index) { return array[index]; }
|
|
};
|
|
}
|
|
|
|
public static List<Character> asList(char[] array) {
|
|
return new AbstractList<Character>() {
|
|
@Override public int size() { return array.length; }
|
|
@Override public Character get(int index) { return array[index]; }
|
|
};
|
|
}
|
|
|
|
public static List<Byte> asList(byte[] array) {
|
|
return new AbstractList<Byte>() {
|
|
@Override public int size() { return array.length; }
|
|
@Override public Byte get(int index) { return array[index]; }
|
|
};
|
|
}
|
|
|
|
public static List<Short> asList(short[] array) {
|
|
return new AbstractList<Short>() {
|
|
@Override public int size() { return array.length; }
|
|
@Override public Short get(int index) { return array[index]; }
|
|
};
|
|
}
|
|
|
|
public static List<Integer> asList(int[] array) {
|
|
return new AbstractList<Integer>() {
|
|
@Override public int size() { return array.length; }
|
|
@Override public Integer get(int index) { return array[index]; }
|
|
};
|
|
}
|
|
|
|
public static List<Long> asList(long[] array) {
|
|
return new AbstractList<Long>() {
|
|
@Override public int size() { return array.length; }
|
|
@Override public Long get(int index) { return array[index]; }
|
|
};
|
|
}
|
|
|
|
public static List<Float> asList(float[] array) {
|
|
return new AbstractList<Float>() {
|
|
@Override public int size() { return array.length; }
|
|
@Override public Float get(int index) { return array[index]; }
|
|
};
|
|
}
|
|
|
|
public static List<Double> asList(double[] array) {
|
|
return new AbstractList<Double>() {
|
|
@Override public int size() { return array.length; }
|
|
@Override public Double get(int index) { return array[index]; }
|
|
};
|
|
}
|
|
|
|
public static List<?> asList(Object array) {
|
|
if(!array.getClass().isArray()) {
|
|
throw new IllegalArgumentException("Not an array");
|
|
}
|
|
|
|
final Class<?> type = array.getClass().getComponentType();
|
|
if(!type.isPrimitive()) {
|
|
return Arrays.asList((Object[]) array);
|
|
} else if(boolean.class.equals(type)) {
|
|
return asList((boolean[]) array);
|
|
} else if(char.class.equals(type)) {
|
|
return asList((char[]) array);
|
|
} else if(byte.class.equals(type)) {
|
|
return asList((byte[]) array);
|
|
} else if(short.class.equals(type)) {
|
|
return asList((short[]) array);
|
|
} else if(int.class.equals(type)) {
|
|
return asList((int[]) array);
|
|
} else if(long.class.equals(type)) {
|
|
return asList((long[]) array);
|
|
} else if(float.class.equals(type)) {
|
|
return asList((float[]) array);
|
|
} else if(double.class.equals(type)) {
|
|
return asList((double[]) array);
|
|
}
|
|
|
|
throw new IllegalArgumentException("Weird array type: " + type);
|
|
}
|
|
|
|
public static <T> List<T> asSubList(int start, int end, T... array) {
|
|
return new AbstractList() {
|
|
@Override
|
|
public int size() {
|
|
return end - start;
|
|
}
|
|
|
|
@Override
|
|
public Object get(int index) {
|
|
return array[start + index];
|
|
}
|
|
};
|
|
}
|
|
|
|
public static <T> List<T> asSubListFrom(int start, T... array) {
|
|
return asSubList(start, array.length, array);
|
|
}
|
|
|
|
public static <T> List<T> asSubListTo(int end, T... array) {
|
|
return asSubList(0, end, array);
|
|
}
|
|
}
|