package com.laytonsmith.PureUtilities.Common;
import java.lang.reflect.Array;
import java.util.List;
/**
*
*
*/
public class ArrayUtils {
/**
* Instantiating a new 0 length array is *usually* inefficient, unless you
* are doing reference comparisons later. If you are generating it simply to use
* as a "default" value for an array, consider using this instead to increase performance.
*/
public static final char[] EMPTY_CHAR_ARRAY = new char[0];
/**
* Instantiating a new 0 length array is *usually* inefficient, unless you
* are doing reference comparisons later. If you are generating it simply to use
* as a "default" value for an array, consider using this instead to increase performance.
*/
public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
/**
* Instantiating a new 0 length array is *usually* inefficient, unless you
* are doing reference comparisons later. If you are generating it simply to use
* as a "default" value for an array, consider using this instead to increase performance.
*/
public static final short[] EMPTY_SHORT_ARRAY = new short[0];
/**
* Instantiating a new 0 length array is *usually* inefficient, unless you
* are doing reference comparisons later. If you are generating it simply to use
* as a "default" value for an array, consider using this instead to increase performance.
*/
public static final int[] EMPTY_INT_ARRAY = new int[0];
/**
* Instantiating a new 0 length array is *usually* inefficient, unless you
* are doing reference comparisons later. If you are generating it simply to use
* as a "default" value for an array, consider using this instead to increase performance.
*/
public static final long[] EMPTY_LONG_ARRAY = new long[0];
/**
* Instantiating a new 0 length array is *usually* inefficient, unless you
* are doing reference comparisons later. If you are generating it simply to use
* as a "default" value for an array, consider using this instead to increase performance.
*/
public static final float[] EMPTY_FLOAT_ARRAY = new float[0];
/**
* Instantiating a new 0 length array is *usually* inefficient, unless you
* are doing reference comparisons later. If you are generating it simply to use
* as a "default" value for an array, consider using this instead to increase performance.
*/
public static final double[] EMPTY_DOUBLE_ARRAY = new double[0];
/**
* Instantiating a new 0 length array is *usually* inefficient, unless you
* are doing reference comparisons later. If you are generating it simply to use
* as a "default" value for an array, consider using this instead to increase performance.
*/
public static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0];
/**
* Instantiating a new 0 length array is *usually* inefficient, unless you
* are doing reference comparisons later. If you are generating it simply to use
* as a "default" value for an array, consider using this instead to increase performance.
*/
public static final Character[] EMPTY_CHAR_OBJ_ARRAY = new Character[0];
/**
* Instantiating a new 0 length array is *usually* inefficient, unless you
* are doing reference comparisons later. If you are generating it simply to use
* as a "default" value for an array, consider using this instead to increase performance.
*/
public static final Byte[] EMPTY_BYTE_OBJ_ARRAY = new Byte[0];
/**
* Instantiating a new 0 length array is *usually* inefficient, unless you
* are doing reference comparisons later. If you are generating it simply to use
* as a "default" value for an array, consider using this instead to increase performance.
*/
public static final Short[] EMPTY_SHORT_OBJ_ARRAY = new Short[0];
/**
* Instantiating a new 0 length array is *usually* inefficient, unless you
* are doing reference comparisons later. If you are generating it simply to use
* as a "default" value for an array, consider using this instead to increase performance.
*/
public static final Integer[] EMPTY_INT_OBJ_ARRAY = new Integer[0];
/**
* Instantiating a new 0 length array is *usually* inefficient, unless you
* are doing reference comparisons later. If you are generating it simply to use
* as a "default" value for an array, consider using this instead to increase performance.
*/
public static final Long[] EMPTY_LONG_OBJ_ARRAY = new Long[0];
/**
* Instantiating a new 0 length array is *usually* inefficient, unless you
* are doing reference comparisons later. If you are generating it simply to use
* as a "default" value for an array, consider using this instead to increase performance.
*/
public static final Float[] EMPTY_FLOAT_OBJ_ARRAY = new Float[0];
/**
* Instantiating a new 0 length array is *usually* inefficient, unless you
* are doing reference comparisons later. If you are generating it simply to use
* as a "default" value for an array, consider using this instead to increase performance.
*/
public static final Double[] EMPTY_DOUBLE_OBJ_ARRAY = new Double[0];
/**
* Instantiating a new 0 length array is *usually* inefficient, unless you
* are doing reference comparisons later. If you are generating it simply to use
* as a "default" value for an array, consider using this instead to increase performance.
*/
public static final Boolean[] EMPTY_BOOLEAN_OBJ_ARRAY = new Boolean[0];
/***************************************************************************
* Slices
***************************************************************************/
/**
* Slices an array, where the array [0, 1, 2] sliced from 0 to 2 would return the whole array.
* That is, start and finish are inclusive. Finish may be less than start, in which case the slice will also
* be backwards, so slicing from 1 to 0 would return [1, 0]. If start and finish are equal, an array with one
* result is returned.
* @param <T> The array type
* @param array The array to be sliced. Note that the original array remains unchanged.
* @param start The starting node.
* @param finish The ending node (inclusive).
* @return
*/
public static <T> T [] slice(T[] array, int start, int finish){
int size = Math.abs(start - finish) + 1;
Object [] newArray = new Object[size];
if(start <= finish){
int counter = 0;
for(int i = start; i <= finish; i++){
newArray[counter++] = array[i];
}
} else {
int counter = 0;
for(int i = start; i >= finish; i--){
newArray[counter++] = array[i];
}
}
return (T[])newArray;
}
/**
* Slices an array, where the array [0, 1, 2] sliced from 0 to 2 would return the whole array.
* That is, start and finish are inclusive. Finish may be less than start, in which case the slice will also
* be backwards, so slicing from 1 to 0 would return [1, 0]. If start and finish are equal, an array with one
* result is returned.
* @param array The array to be sliced. Note that the original array remains unchanged.
* @param start The starting node.
* @param finish The ending node (inclusive).
* @return
*/
public static char [] slice(char[] array, int start, int finish){
int size = Math.abs(start - finish) + 1;
char [] newArray = new char[size];
if(start <= finish){
int counter = 0;
for(int i = start; i <= finish; i++){
newArray[counter++] = array[i];
}
} else {
int counter = 0;
for(int i = start; i >= finish; i--){
newArray[counter++] = array[i];
}
}
return newArray;
}
/**
* Slices an array, where the array [0, 1, 2] sliced from 0 to 2 would return the whole array.
* That is, start and finish are inclusive. Finish may be less than start, in which case the slice will also
* be backwards, so slicing from 1 to 0 would return [1, 0]. If start and finish are equal, an array with one
* result is returned.
* @param array The array to be sliced. Note that the original array remains unchanged.
* @param start The starting node.
* @param finish The ending node (inclusive).
* @return
*/
public static byte [] slice(byte[] array, int start, int finish){
int size = Math.abs(start - finish) + 1;
byte [] newArray = new byte[size];
if(start <= finish){
int counter = 0;
for(int i = start; i <= finish; i++){
newArray[counter++] = array[i];
}
} else {
int counter = 0;
for(int i = start; i >= finish; i--){
newArray[counter++] = array[i];
}
}
return newArray;
}
/**
* Slices an array, where the array [0, 1, 2] sliced from 0 to 2 would return the whole array.
* That is, start and finish are inclusive. Finish may be less than start, in which case the slice will also
* be backwards, so slicing from 1 to 0 would return [1, 0]. If start and finish are equal, an array with one
* result is returned.
* @param array The array to be sliced. Note that the original array remains unchanged.
* @param start The starting node.
* @param finish The ending node (inclusive).
* @return
*/
public static short [] slice(short[] array, int start, int finish){
int size = Math.abs(start - finish) + 1;
short [] newArray = new short[size];
if(start <= finish){
int counter = 0;
for(int i = start; i <= finish; i++){
newArray[counter++] = array[i];
}
} else {
int counter = 0;
for(int i = start; i >= finish; i--){
newArray[counter++] = array[i];
}
}
return newArray;
}
/**
* Slices an array, where the array [0, 1, 2] sliced from 0 to 2 would return the whole array.
* That is, start and finish are inclusive. Finish may be less than start, in which case the slice will also
* be backwards, so slicing from 1 to 0 would return [1, 0]. If start and finish are equal, an array with one
* result is returned.
* @param array The array to be sliced. Note that the original array remains unchanged.
* @param start The starting node.
* @param finish The ending node (inclusive).
* @return
*/
public static int [] slice(int[] array, int start, int finish){
int size = Math.abs(start - finish) + 1;
int [] newArray = new int[size];
if(start <= finish){
int counter = 0;
for(int i = start; i <= finish; i++){
newArray[counter++] = array[i];
}
} else {
int counter = 0;
for(int i = start; i >= finish; i--){
newArray[counter++] = array[i];
}
}
return newArray;
}
/**
* Slices an array, where the array [0, 1, 2] sliced from 0 to 2 would return the whole array.
* That is, start and finish are inclusive. Finish may be less than start, in which case the slice will also
* be backwards, so slicing from 1 to 0 would return [1, 0]. If start and finish are equal, an array with one
* result is returned.
* @param array The array to be sliced. Note that the original array remains unchanged.
* @param start The starting node.
* @param finish The ending node (inclusive).
* @return
*/
public static long [] slice(long[] array, int start, int finish){
int size = Math.abs(start - finish) + 1;
long [] newArray = new long[size];
if(start <= finish){
int counter = 0;
for(int i = start; i <= finish; i++){
newArray[counter++] = array[i];
}
} else {
int counter = 0;
for(int i = start; i >= finish; i--){
newArray[counter++] = array[i];
}
}
return newArray;
}
/**
* Slices an array, where the array [0, 1, 2] sliced from 0 to 2 would return the whole array.
* That is, start and finish are inclusive. Finish may be less than start, in which case the slice will also
* be backwards, so slicing from 1 to 0 would return [1, 0]. If start and finish are equal, an array with one
* result is returned.
* @param array The array to be sliced. Note that the original array remains unchanged.
* @param start The starting node.
* @param finish The ending node (inclusive).
* @return
*/
public static float [] slice(float[] array, int start, int finish){
int size = Math.abs(start - finish) + 1;
float [] newArray = new float[size];
if(start <= finish){
int counter = 0;
for(int i = start; i <= finish; i++){
newArray[counter++] = array[i];
}
} else {
int counter = 0;
for(int i = start; i >= finish; i--){
newArray[counter++] = array[i];
}
}
return newArray;
}
/**
* Slices an array, where the array [0, 1, 2] sliced from 0 to 2 would return the whole array.
* That is, start and finish are inclusive. Finish may be less than start, in which case the slice will also
* be backwards, so slicing from 1 to 0 would return [1, 0]. If start and finish are equal, an array with one
* result is returned.
* @param array The array to be sliced. Note that the original array remains unchanged.
* @param start The starting node.
* @param finish The ending node (inclusive).
* @return
*/
public static double [] slice(double[] array, int start, int finish){
int size = Math.abs(start - finish) + 1;
double [] newArray = new double[size];
if(start <= finish){
int counter = 0;
for(int i = start; i <= finish; i++){
newArray[counter++] = array[i];
}
} else {
int counter = 0;
for(int i = start; i >= finish; i--){
newArray[counter++] = array[i];
}
}
return newArray;
}
/**
* Slices an array, where the array [0, 1, 2] sliced from 0 to 2 would return the whole array.
* That is, start and finish are inclusive. Finish may be less than start, in which case the slice will also
* be backwards, so slicing from 1 to 0 would return [1, 0]. If start and finish are equal, an array with one
* result is returned.
* @param array The array to be sliced. Note that the original array remains unchanged.
* @param start The starting node.
* @param finish The ending node (inclusive).
* @return
*/
public static boolean [] slice(boolean[] array, int start, int finish){
int size = Math.abs(start - finish) + 1;
boolean [] newArray = new boolean[size];
if(start <= finish){
int counter = 0;
for(int i = start; i <= finish; i++){
newArray[counter++] = array[i];
}
} else {
int counter = 0;
for(int i = start; i >= finish; i--){
newArray[counter++] = array[i];
}
}
return newArray;
}
/***************************************************************************
* Unboxes
***************************************************************************/
/**
* "Unboxes" an array, that is, unboxes all the primitives in this
* array, and returns a primitive array.
* @param array The "boxed" array
* @return The "unboxed" array
*/
public static char[] unbox(Character[] array){
if(array == null){
return null;
} else if(array.length == 0){
return EMPTY_CHAR_ARRAY;
}
final char [] newArray = new char[array.length];
for(int i = 0; i < array.length; i++){
newArray[i] = array[i].charValue();
}
return newArray;
}
/**
* "Unboxes" an array, that is, unboxes all the primitives in this
* array, and returns a primitive array.
* @param array The "boxed" array
* @return The "unboxed" array
*/
public static byte[] unbox(Byte[] array){
if(array == null){
return null;
} else if(array.length == 0){
return EMPTY_BYTE_ARRAY;
}
final byte [] newArray = new byte[array.length];
for(int i = 0; i < array.length; i++){
newArray[i] = array[i].byteValue();
}
return newArray;
}
/**
* "Unboxes" an array, that is, unboxes all the primitives in this
* array, and returns a primitive array.
* @param array The "boxed" array
* @return The "unboxed" array
*/
public static short[] unbox(Short[] array){
if(array == null){
return null;
} else if(array.length == 0){
return EMPTY_SHORT_ARRAY;
}
final short [] newArray = new short[array.length];
for(int i = 0; i < array.length; i++){
newArray[i] = array[i].shortValue();
}
return newArray;
}
/**
* "Unboxes" an array, that is, unboxes all the primitives in this
* array, and returns a primitive array.
* @param array The "boxed" array
* @return The "unboxed" array
*/
public static int[] unbox(Integer[] array){
if(array == null){
return null;
} else if(array.length == 0){
return EMPTY_INT_ARRAY;
}
final int [] newArray = new int[array.length];
for(int i = 0; i < array.length; i++){
newArray[i] = array[i].intValue();
}
return newArray;
}
/**
* "Unboxes" an array, that is, unboxes all the primitives in this
* array, and returns a primitive array.
* @param array The "boxed" array
* @return The "unboxed" array
*/
public static long[] unbox(Long[] array){
if(array == null){
return null;
} else if(array.length == 0){
return EMPTY_LONG_ARRAY;
}
final long [] newArray = new long[array.length];
for(int i = 0; i < array.length; i++){
newArray[i] = array[i].longValue();
}
return newArray;
}
/**
* "Unboxes" an array, that is, unboxes all the primitives in this
* array, and returns a primitive array.
* @param array The "boxed" array
* @return The "unboxed" array
*/
public static float[] unbox(Float[] array){
if(array == null){
return null;
} else if(array.length == 0){
return EMPTY_FLOAT_ARRAY;
}
final float [] newArray = new float[array.length];
for(int i = 0; i < array.length; i++){
newArray[i] = array[i].floatValue();
}
return newArray;
}
/**
* "Unboxes" an array, that is, unboxes all the primitives in this
* array, and returns a primitive array.
* @param array The "boxed" array
* @return The "unboxed" array
*/
public static double[] unbox(Double[] array){
if(array == null){
return null;
} else if(array.length == 0){
return EMPTY_DOUBLE_ARRAY;
}
final double [] newArray = new double[array.length];
for(int i = 0; i < array.length; i++){
newArray[i] = array[i].doubleValue();
}
return newArray;
}
/**
* "Unboxes" an array, that is, unboxes all the primitives in this
* array, and returns a primitive array.
* @param array The "boxed" array
* @return The "unboxed" array
*/
public static boolean[] unbox(Boolean[] array){
if(array == null){
return null;
} else if(array.length == 0){
return EMPTY_BOOLEAN_ARRAY;
}
final boolean [] newArray = new boolean[array.length];
for(int i = 0; i < array.length; i++){
newArray[i] = array[i].booleanValue();
}
return newArray;
}
/***************************************************************************
* Boxes
***************************************************************************/
/**
* "Boxes" an array, that is, boxes all the primitives in the given array,
* and returns a new "boxed" array.
* @param array The primitive array
* @return The "boxed" array
*/
public static Character[] box(char[] array){
if(array == null){
return null;
} else if(array.length == 0){
return EMPTY_CHAR_OBJ_ARRAY;
}
final Character[] newArray = new Character[array.length];
for(int i = 0; i < array.length; i++){
newArray[i] = array[i];
}
return newArray;
}
/**
* "Boxes" an array, that is, boxes all the primitives in the given array,
* and returns a new "boxed" array.
* @param array The primitive array
* @return The "boxed" array
*/
public static Byte[] box(byte[] array){
if(array == null){
return null;
} else if(array.length == 0){
return EMPTY_BYTE_OBJ_ARRAY;
}
final Byte[] newArray = new Byte[array.length];
for(int i = 0; i < array.length; i++){
newArray[i] = array[i];
}
return newArray;
}
/**
* "Boxes" an array, that is, boxes all the primitives in the given array,
* and returns a new "boxed" array.
* @param array The primitive array
* @return The "boxed" array
*/
public static Short[] box(short[] array){
if(array == null){
return null;
} else if(array.length == 0){
return EMPTY_SHORT_OBJ_ARRAY;
}
final Short[] newArray = new Short[array.length];
for(int i = 0; i < array.length; i++){
newArray[i] = array[i];
}
return newArray;
}
/**
* "Boxes" an array, that is, boxes all the primitives in the given array,
* and returns a new "boxed" array.
* @param array The primitive array
* @return The "boxed" array
*/
public static Integer[] box(int[] array){
if(array == null){
return null;
} else if(array.length == 0){
return EMPTY_INT_OBJ_ARRAY;
}
final Integer[] newArray = new Integer[array.length];
for(int i = 0; i < array.length; i++){
newArray[i] = array[i];
}
return newArray;
}
/**
* "Boxes" an array, that is, boxes all the primitives in the given array,
* and returns a new "boxed" array.
* @param array The primitive array
* @return The "boxed" array
*/
public static Long[] box(long[] array){
if(array == null){
return null;
} else if(array.length == 0){
return EMPTY_LONG_OBJ_ARRAY;
}
final Long[] newArray = new Long[array.length];
for(int i = 0; i < array.length; i++){
newArray[i] = array[i];
}
return newArray;
}
/**
* "Boxes" an array, that is, boxes all the primitives in the given array,
* and returns a new "boxed" array.
* @param array The primitive array
* @return The "boxed" array
*/
public static Float[] box(float[] array){
if(array == null){
return null;
} else if(array.length == 0){
return EMPTY_FLOAT_OBJ_ARRAY;
}
final Float[] newArray = new Float[array.length];
for(int i = 0; i < array.length; i++){
newArray[i] = array[i];
}
return newArray;
}
/**
* "Boxes" an array, that is, boxes all the primitives in the given array,
* and returns a new "boxed" array.
* @param array The primitive array
* @return The "boxed" array
*/
public static Double[] box(double[] array){
if(array == null){
return null;
} else if(array.length == 0){
return EMPTY_DOUBLE_OBJ_ARRAY;
}
final Double[] newArray = new Double[array.length];
for(int i = 0; i < array.length; i++){
newArray[i] = array[i];
}
return newArray;
}
/**
* "Boxes" an array, that is, boxes all the primitives in the given array,
* and returns a new "boxed" array.
* @param array The primitive array
* @return The "boxed" array
*/
public static Boolean[] box(boolean[] array){
if(array == null){
return null;
} else if(array.length == 0){
return EMPTY_BOOLEAN_OBJ_ARRAY;
}
final Boolean[] newArray = new Boolean[array.length];
for(int i = 0; i < array.length; i++){
newArray[i] = array[i];
}
return newArray;
}
/***************************************************************************
* Misc
***************************************************************************/
/**
* Returns a new array, based on the runtime type of the list.
* @param <T>
* @param list
* @return
*/
public static <T> T[] asArray(Class<T> clazz, List list){
T[] obj = (T[]) Array.newInstance(clazz, list.size());
for(int i = 0; i < list.size(); i++){
obj[i] = (T)list.get(i);
}
return obj;
}
/**
* Returns a new array, where each item has been cast to the
* specified class, and the returned array is an array type
* based on that class.
* @param <T>
* @param array Despite being an Object, instead of an Object[], this will throw a ClassCastException
* if it is not an array type.
* @param toClass
* @return
*/
public static <T> T cast(Object array, Class<T> toArrayClass){
if(!array.getClass().isArray()){
throw new ClassCastException();
}
Object obj;
Class toClass = toArrayClass.getComponentType();
obj = toArrayClass.cast(Array.newInstance(toClass, Array.getLength(array)));
for(int i = 0; i < Array.getLength(array); i++){
doSet(obj, i, Array.get(array, i));
}
return (T)obj;
}
private static void doSet(Object array, int index, Object o){
Class componentType = array.getClass().getComponentType();
if(componentType.isPrimitive()){
if(componentType == char.class){
Array.setChar(array, index, ((Character)o).charValue());
} else if(componentType == byte.class){
Array.setByte(array, index, ((Number)o).byteValue());
} else if(componentType == short.class){
Array.setShort(array, index, ((Number)o).shortValue());
} else if(componentType == int.class){
Array.setInt(array, index, ((Number)o).intValue());
} else if(componentType == long.class){
Array.setLong(array, index, ((Number)o).longValue());
} else if(componentType == float.class){
Array.setFloat(array, index, ((Number)o).floatValue());
} else if(componentType == double.class){
Array.setDouble(array, index, ((Number)o).doubleValue());
} else if(componentType == boolean.class){
Array.setBoolean(array, index, ((Boolean)o).booleanValue());
}
} else {
Array.set(array, index, o);
}
}
}