package org.basex.util;
import java.util.*;
import org.basex.util.list.*;
/**
* Convenience functions for handling arrays; serves as an extension to Java's {@link Arrays} class.
*
* @author BaseX Team 2005-17, BSD License
* @author Christian Gruen
*/
public final class Array {
/** Initial default size for new arrays. */
public static final int CAPACITY = 1 << 3;
/** Default factor for resizing dynamic arrays. */
public static final double RESIZE = 1.5;
/** Private constructor. */
private Array() { }
/**
* Copies the specified array.
* @param array array to be copied
* @param size new array size
* @return new array
*/
public static byte[][] copyOf(final byte[][] array, final int size) {
final byte[][] tmp = new byte[size][];
System.arraycopy(array, 0, tmp, 0, Math.min(size, array.length));
return tmp;
}
/**
* Copies the specified array.
* @param array array to be copied
* @param size new array size
* @return new array
*/
public static int[][] copyOf(final int[][] array, final int size) {
final int[][] tmp = new int[size][];
System.arraycopy(array, 0, tmp, 0, Math.min(size, array.length));
return tmp;
}
/**
* Copies the specified array.
* @param array array to be copied
* @param size new array size
* @return new array
*/
public static String[] copyOf(final String[] array, final int size) {
final String[] tmp = new String[size];
System.arraycopy(array, 0, tmp, 0, Math.min(size, array.length));
return tmp;
}
/**
* Adds an entry to the end of an array and returns the new array.
* @param array array to be resized
* @param entry entry to be added
* @param <T> array type
* @return array
*/
public static <T> T[] add(final T[] array, final T entry) {
final int s = array.length;
final T[] t = Arrays.copyOf(array, s + 1);
t[s] = entry;
return t;
}
/**
* Adds an entry to the end of an array and returns the new array.
* @param array array to be resized
* @param entry entry to be added
* @return array
*/
public static int[] add(final int[] array, final int entry) {
final int s = array.length;
final int[] t = Arrays.copyOf(array, s + 1);
t[s] = entry;
return t;
}
/**
* Moves entries inside an array.
* @param array array
* @param pos position
* @param off move offset
* @param size number of entries to move
*/
public static void move(final Object array, final int pos, final int off, final int size) {
System.arraycopy(array, pos, array, pos + off, size);
}
/**
* Copies entries from one array to another.
* @param <T> object type
* @param source source array
* @param target target array
* @return object
*/
public static <T> T[] copy(final T[] source, final T[] target) {
System.arraycopy(source, 0, target, 0, source.length);
return target;
}
/**
* Removes an array entry at the specified position.
* @param array array to be resized
* @param pos position
* @param <T> array type
* @return new array
*/
public static <T> T[] delete(final T[] array, final int pos) {
final int s = array.length - 1;
final T[] tmp = Arrays.copyOf(array, s);
System.arraycopy(array, pos + 1, tmp, pos, s - pos);
return tmp;
}
/**
* Sorts the specified tokens and returns an array with offsets to the sorted array.
* @param values values to sort by (will be sorted as well)
* @param numeric numeric sort
* @param ascending ascending
* @return array containing the order
*/
public static int[] createOrder(final byte[][] values, final boolean numeric,
final boolean ascending) {
final IntList il = number(values.length);
il.sort(values, numeric, ascending);
return il.finish();
}
/**
* Sorts the specified double values and returns an array with offsets to the sorted array.
* @param values values to sort by (will be sorted as well)
* @param ascending ascending
* @return array containing the order
*/
public static int[] createOrder(final double[] values, final boolean ascending) {
final IntList il = number(values.length);
il.sort(values, ascending);
return il.finish();
}
/**
* Sorts the specified int values and returns an array with offsets to the sorted array.
* @param values values to sort by (will be sorted as well)
* @param ascending ascending
* @return array containing the order
*/
public static int[] createOrder(final int[] values, final boolean ascending) {
final IntList il = number(values.length);
il.sort(values, ascending);
return il.finish();
}
/**
* Sorts the specified long values and returns an array with offsets to the sorted array.
* @param values values to sort by (will be sorted as well)
* @param ascending ascending
* @return array containing the order
*/
public static int[] createOrder(final long[] values, final boolean ascending) {
final IntList il = number(values.length);
il.sort(values, ascending);
return il.finish();
}
/**
* Returns an enumerated integer list.
* @param size array size
* @return number list
*/
public static IntList number(final int size) {
final int[] tmp = new int[size];
for(int i = 0; i < size; ++i) tmp[i] = i;
return new IntList(tmp);
}
/**
* Reverses the order of the elements in the given array.
* @param array array
*/
public static void reverse(final byte[] array) {
reverse(array, 0, array.length);
}
/**
* Reverses the order of all elements in the given interval.
* @param array array
* @param pos position of first element of the interval
* @param len length of the interval
*/
private static void reverse(final byte[] array, final int pos, final int len) {
for(int l = pos, r = pos + len - 1; l < r; l++, r--) {
final byte tmp = array[l];
array[l] = array[r];
array[r] = tmp;
}
}
/**
* Reverses the order of all elements in the given interval.
* @param array array
* @param pos position of first element of the interval
* @param len length of the interval
*/
public static void reverse(final Object[] array, final int pos, final int len) {
for(int l = pos, r = pos + len - 1; l < r; l++, r--) {
final Object tmp = array[l];
array[l] = array[r];
array[r] = tmp;
}
}
/**
* Returns a value for a new array size, which will always be larger than the specified value.
* @param old old size
* @return resulting size
*/
public static int newSize(final int old) {
return newSize(old, RESIZE);
}
/**
* Returns a value for a new array size, which will always be larger than the specified value.
* @param old old size
* @param factor resize factor; must be larger than or equal to 1
* @return resulting size
*/
public static int newSize(final int old, final double factor) {
return (int) (old * factor) + 1;
}
}