|
|
@@ -1,424 +1,424 @@
|
|
|
-/*
|
|
|
- * @author Ranides Atterwim <ranides@gmail.com>
|
|
|
- * @copyright Ranides Atterwim
|
|
|
- * @license WTFPL
|
|
|
- * @url http://ranides.net/projects/assira
|
|
|
- */
|
|
|
-package net.ranides.assira.collection.arrays;
|
|
|
-
|
|
|
-import java.lang.reflect.Array;
|
|
|
-import java.util.AbstractList;
|
|
|
-import java.util.Arrays;
|
|
|
-import java.util.Comparator;
|
|
|
-import java.util.Iterator;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Random;
|
|
|
-import net.ranides.assira.collection.Swapper;
|
|
|
-
|
|
|
-@SuppressWarnings({
|
|
|
- "PMD.AvoidReassigningParameters"
|
|
|
-})
|
|
|
-public final class ArrayUtils {
|
|
|
-
|
|
|
- private ArrayUtils() {
|
|
|
- // utility class
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Unwraps an iterator into an array starting at a given offset for a given
|
|
|
- * number of elements.
|
|
|
- *
|
|
|
- * <P>This method iterates over the given type-specific iterator and stores
|
|
|
- * the elements returned, up to a maximum of
|
|
|
- * <code>length</code>, in the given array starting at
|
|
|
- * <code>offset</code>. The number of actually unwrapped elements is
|
|
|
- * returned (it may be less than
|
|
|
- * <code>max</code> if the iterator emits less than
|
|
|
- * <code>max</code> elements).
|
|
|
- *
|
|
|
- * @param iterator a type-specific iterator.
|
|
|
- * @param target an array to contain the output of the iterator.
|
|
|
- * @param offset the first element of the array to be returned.
|
|
|
- * @param max the maximum number of elements to collect.
|
|
|
- * @return the number of elements unwrapped.
|
|
|
- */
|
|
|
- public static <K> int collect(Iterator<? extends K> iterator, K target[], int offset, int max) {
|
|
|
- if (max < 0) {
|
|
|
- throw new IllegalArgumentException("The maximum number of elements (" + max + ") is negative");
|
|
|
- }
|
|
|
- if (offset < 0 || offset + max > target.length) {
|
|
|
- throw new IllegalArgumentException();
|
|
|
- }
|
|
|
- int j = max;
|
|
|
- while (j-- != 0 && iterator.hasNext()) {
|
|
|
- target[ offset++] = iterator.next();
|
|
|
- }
|
|
|
- return max - j - 1;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Unwraps an iterator into an array.
|
|
|
- *
|
|
|
- * <P>This method iterates over the given type-specific iterator and stores
|
|
|
- * the elements returned in the given array. The iteration will stop when
|
|
|
- * the iterator has no more elements or when the end of the array has been
|
|
|
- * reached.
|
|
|
- *
|
|
|
- * @param iterator a type-specific iterator.
|
|
|
- * @param target an array to contain the output of the iterator.
|
|
|
- * @return the number of elements unwrapped.
|
|
|
- */
|
|
|
- public static <K> int collect(Iterator<? extends K> iterator, K target[]) {
|
|
|
- return ArrayUtils.collect(iterator, target, 0, target.length);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Fills the given array with the given value.
|
|
|
- *
|
|
|
- * <P>This method uses a backward loop. It is significantly faster than the
|
|
|
- * corresponding method in {@link java.util.Arrays}.
|
|
|
- *
|
|
|
- * @param array an array.
|
|
|
- * @param value the new value for all elements of the array.
|
|
|
- */
|
|
|
- public static <K> void fill(K[] array, K value) {
|
|
|
- for(int i=0; i<array.length; i++) {
|
|
|
- array[i] = value;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Fills a portion of the given array with the given value.
|
|
|
- *
|
|
|
- * <P>If possible (i.e.,
|
|
|
- * <code>from</code> is 0) this method uses a backward loop. In this case,
|
|
|
- * it is significantly faster than the corresponding method in
|
|
|
- * {@link java.util.Arrays}.
|
|
|
- *
|
|
|
- * @param array an array.
|
|
|
- * @param from the starting index of the portion to fill (inclusive).
|
|
|
- * @param to the end index of the portion to fill (exclusive).
|
|
|
- * @param value the new value for all elements of the specified portion of
|
|
|
- * the array.
|
|
|
- */
|
|
|
- public static <K> void fill(K[] array, int from, int to, K value) {
|
|
|
- ArrayAllocator.ensureFromTo(array, from, to);
|
|
|
- for (int i = from; i < to; i++) {
|
|
|
- array[i] = value;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Fills the given array with the given value.
|
|
|
- *
|
|
|
- * <P>This method uses a backward loop. It is significantly faster than the
|
|
|
- * corresponding method in {@link java.util.Arrays}.
|
|
|
- *
|
|
|
- * @param array an array.
|
|
|
- * @param value the new value for all elements of the array.
|
|
|
- */
|
|
|
- public static void fill(boolean[] array, boolean value) {
|
|
|
- for (int i=0; i<array.length; i++) {
|
|
|
- array[i] = value;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Reverses the order of the elements in the specified array.
|
|
|
- *
|
|
|
- * @param array the array to be reversed.
|
|
|
- * @return <code>a</code>.
|
|
|
- */
|
|
|
- public static <K> K[] reverse(K[] array) {
|
|
|
- int length = array.length;
|
|
|
- for (int i = length / 2; i-- != 0;) {
|
|
|
- K temp = array[ length - i - 1];
|
|
|
- array[ length - i - 1] = array[ i];
|
|
|
- array[ i] = temp;
|
|
|
- }
|
|
|
- return array;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Returns true if the two arrays are elementwise equal.
|
|
|
- *
|
|
|
- * @param array1 an array.
|
|
|
- * @param array2 another array.
|
|
|
- * @return true if the two arrays are of the same length, and their elements
|
|
|
- * are equal.
|
|
|
- */
|
|
|
- public static <K> boolean equals(K[] array1, K array2[]) {
|
|
|
- // This method uses a backward loop.
|
|
|
- // It is significantly faster than the java.util.Arrays
|
|
|
- int i = array1.length;
|
|
|
- if (i != array2.length) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- while (i-- != 0) {
|
|
|
- if (!((array1[ i]) == null ? (array2[ i]) == null : (array1[ i]).equals(array2[ i]))) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- public static <K> K[] head(K[] values, K value, Comparator<K> cmp) {
|
|
|
- return islice(values, 0, ifind(values, value, 0, cmp));
|
|
|
- }
|
|
|
-
|
|
|
- public static <K> K[] tail(K[] values, K value, Comparator<K> cmp) {
|
|
|
- return islice(values, ifind(values, value, 0, cmp), values.length);
|
|
|
- }
|
|
|
-
|
|
|
- public static <K> K[] slice(K[] values, K begin, K end, Comparator<K> cmp) {
|
|
|
- int bi = ifind(values, begin, 0, cmp);
|
|
|
- int ei = ifind(values, end, bi, cmp);
|
|
|
- return islice(values, bi, ei);
|
|
|
- }
|
|
|
-
|
|
|
- private static <K> int ifind(K[] values, K value, int begin, Comparator<K> cmp) {
|
|
|
- int i = begin;
|
|
|
- while(i<values.length && cmp.compare(values[i], value) < 0) {
|
|
|
- i++;
|
|
|
- }
|
|
|
- return i;
|
|
|
- }
|
|
|
-
|
|
|
- private static <K> K[] islice(K[] values, int begin, int end) {
|
|
|
- int size = end - begin;
|
|
|
- K[] result = ArrayAllocator.forPrototype(values, size);
|
|
|
- System.arraycopy(values, begin, result, 0, size);
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- public static void shuffle(int size, Random random, Swapper swapper) {
|
|
|
- for(int i=0; i<size; i++) {
|
|
|
- swapper.swap(random.nextInt(size), random.nextInt(size));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public static <T> void shuffle(T[] array, Random random) {
|
|
|
- shuffle(array.length, random, Swapper.swapper(array));
|
|
|
- }
|
|
|
-
|
|
|
- public static <K> int size(K[] array) {
|
|
|
- return null == array ? 0 : array.length;
|
|
|
- }
|
|
|
-
|
|
|
- public static int size(Object array) {
|
|
|
- return null == array ? 0 : Array.getLength(array);
|
|
|
- }
|
|
|
-
|
|
|
- @SuppressWarnings("PMD.NPathComplexity")
|
|
|
- public static List<?> wrap(Object array) {
|
|
|
- Class<?> c = array.getClass().getComponentType();
|
|
|
- if(byte.class.equals(c)) {
|
|
|
- return new ByteList(array);
|
|
|
- }
|
|
|
- if(short.class.equals(c)) {
|
|
|
- return new ShortList(array);
|
|
|
- }
|
|
|
- if(int.class.equals(c)) {
|
|
|
- return new IntegerList(array);
|
|
|
- }
|
|
|
- if(long.class.equals(c)) {
|
|
|
- return new LongList(array);
|
|
|
- }
|
|
|
- if(float.class.equals(c)) {
|
|
|
- return new FloatList(array);
|
|
|
- }
|
|
|
- if(double.class.equals(c)) {
|
|
|
- return new DoubleList(array);
|
|
|
- }
|
|
|
- if(char.class.equals(c)) {
|
|
|
- return new CharacterList(array);
|
|
|
- }
|
|
|
- if(boolean.class.equals(c)) {
|
|
|
- return new BooleanList(array);
|
|
|
- }
|
|
|
- return Arrays.asList((Object[])array);
|
|
|
- }
|
|
|
-
|
|
|
- @SuppressWarnings("unchecked")
|
|
|
- public static <T> List<T> $wrap(Object array) {
|
|
|
- return (List<T>)wrap(array);
|
|
|
- }
|
|
|
-
|
|
|
- private static abstract class ArrayWrapper<T> extends AbstractList<T> {
|
|
|
-
|
|
|
- protected final Object array;
|
|
|
-
|
|
|
- protected ArrayWrapper(Object array) {
|
|
|
- this.array = array;
|
|
|
- }
|
|
|
-
|
|
|
- protected abstract void at(int index, T element);
|
|
|
-
|
|
|
- protected abstract T at(int index);
|
|
|
-
|
|
|
-
|
|
|
- @Override
|
|
|
- public final T set(int index, T element) {
|
|
|
- T prev = at(index);
|
|
|
- at(index, element);
|
|
|
- return prev;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public T get(int index) {
|
|
|
- return at(index);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public int size() {
|
|
|
- return Array.getLength(array);
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- private static final class ByteList extends ArrayWrapper<Byte> {
|
|
|
-
|
|
|
- public ByteList(Object array) {
|
|
|
- super(array);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void at(int index, Byte element) {
|
|
|
- Array.setByte(array, index, element);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Byte at(int index) {
|
|
|
- return Array.getByte(array, index);
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- private static final class ShortList extends ArrayWrapper<Short> {
|
|
|
-
|
|
|
- public ShortList(Object array) {
|
|
|
- super(array);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void at(int index, Short element) {
|
|
|
- Array.setShort(array, index, element);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Short at(int index) {
|
|
|
- return Array.getShort(array, index);
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- private static final class IntegerList extends ArrayWrapper<Integer> {
|
|
|
-
|
|
|
- public IntegerList(Object array) {
|
|
|
- super(array);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void at(int index, Integer element) {
|
|
|
- Array.setInt(array, index, element);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Integer at(int index) {
|
|
|
- return Array.getInt(array, index);
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- private static final class LongList extends ArrayWrapper<Long> {
|
|
|
-
|
|
|
- public LongList(Object array) {
|
|
|
- super(array);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void at(int index, Long element) {
|
|
|
- Array.setLong(array, index, element);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Long at(int index) {
|
|
|
- return Array.getLong(array, index);
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- private static final class FloatList extends ArrayWrapper<Float> {
|
|
|
-
|
|
|
- public FloatList(Object array) {
|
|
|
- super(array);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void at(int index, Float element) {
|
|
|
- Array.setFloat(array, index, element);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Float at(int index) {
|
|
|
- return Array.getFloat(array, index);
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- private static final class DoubleList extends ArrayWrapper<Double> {
|
|
|
-
|
|
|
- public DoubleList(Object array) {
|
|
|
- super(array);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void at(int index, Double element) {
|
|
|
- Array.setDouble(array, index, element);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Double at(int index) {
|
|
|
- return Array.getDouble(array, index);
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- private static final class CharacterList extends ArrayWrapper<Character> {
|
|
|
-
|
|
|
- public CharacterList(Object array) {
|
|
|
- super(array);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void at(int index, Character element) {
|
|
|
- Array.setChar(array, index, element);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Character at(int index) {
|
|
|
- return Array.getChar(array, index);
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- private static final class BooleanList extends ArrayWrapper<Boolean> {
|
|
|
-
|
|
|
- public BooleanList(Object array) {
|
|
|
- super(array);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void at(int index, Boolean element) {
|
|
|
- Array.setBoolean(array, index, element);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Boolean at(int index) {
|
|
|
- return Array.getBoolean(array, index);
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-}
|
|
|
+/*
|
|
|
+ * @author Ranides Atterwim <ranides@gmail.com>
|
|
|
+ * @copyright Ranides Atterwim
|
|
|
+ * @license WTFPL
|
|
|
+ * @url http://ranides.net/projects/assira
|
|
|
+ */
|
|
|
+package net.ranides.assira.collection.arrays;
|
|
|
+
|
|
|
+import java.lang.reflect.Array;
|
|
|
+import java.util.AbstractList;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.Comparator;
|
|
|
+import java.util.Iterator;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Random;
|
|
|
+import net.ranides.assira.collection.Swapper;
|
|
|
+
|
|
|
+@SuppressWarnings({
|
|
|
+ "PMD.AvoidReassigningParameters"
|
|
|
+})
|
|
|
+public final class ArrayUtils {
|
|
|
+
|
|
|
+ private ArrayUtils() {
|
|
|
+ // utility class
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Unwraps an iterator into an array starting at a given offset for a given
|
|
|
+ * number of elements.
|
|
|
+ *
|
|
|
+ * <P>This method iterates over the given type-specific iterator and stores
|
|
|
+ * the elements returned, up to a maximum of
|
|
|
+ * <code>length</code>, in the given array starting at
|
|
|
+ * <code>offset</code>. The number of actually unwrapped elements is
|
|
|
+ * returned (it may be less than
|
|
|
+ * <code>max</code> if the iterator emits less than
|
|
|
+ * <code>max</code> elements).
|
|
|
+ *
|
|
|
+ * @param iterator a type-specific iterator.
|
|
|
+ * @param target an array to contain the output of the iterator.
|
|
|
+ * @param offset the first element of the array to be returned.
|
|
|
+ * @param max the maximum number of elements to collect.
|
|
|
+ * @return the number of elements unwrapped.
|
|
|
+ */
|
|
|
+ public static <K> int collect(Iterator<? extends K> iterator, K target[], int offset, int max) {
|
|
|
+ if (max < 0) {
|
|
|
+ throw new IllegalArgumentException("The maximum number of elements (" + max + ") is negative");
|
|
|
+ }
|
|
|
+ if (offset < 0 || offset + max > target.length) {
|
|
|
+ throw new IllegalArgumentException();
|
|
|
+ }
|
|
|
+ int j = max;
|
|
|
+ while (j-- != 0 && iterator.hasNext()) {
|
|
|
+ target[ offset++] = iterator.next();
|
|
|
+ }
|
|
|
+ return max - j - 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Unwraps an iterator into an array.
|
|
|
+ *
|
|
|
+ * <P>This method iterates over the given type-specific iterator and stores
|
|
|
+ * the elements returned in the given array. The iteration will stop when
|
|
|
+ * the iterator has no more elements or when the end of the array has been
|
|
|
+ * reached.
|
|
|
+ *
|
|
|
+ * @param iterator a type-specific iterator.
|
|
|
+ * @param target an array to contain the output of the iterator.
|
|
|
+ * @return the number of elements unwrapped.
|
|
|
+ */
|
|
|
+ public static <K> int collect(Iterator<? extends K> iterator, K target[]) {
|
|
|
+ return ArrayUtils.collect(iterator, target, 0, target.length);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Fills the given array with the given value.
|
|
|
+ *
|
|
|
+ * <P>This method uses a backward loop. It is significantly faster than the
|
|
|
+ * corresponding method in {@link java.util.Arrays}.
|
|
|
+ *
|
|
|
+ * @param array an array.
|
|
|
+ * @param value the new value for all elements of the array.
|
|
|
+ */
|
|
|
+ public static <K> void fill(K[] array, K value) {
|
|
|
+ for(int i=0; i<array.length; i++) {
|
|
|
+ array[i] = value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Fills a portion of the given array with the given value.
|
|
|
+ *
|
|
|
+ * <P>If possible (i.e.,
|
|
|
+ * <code>from</code> is 0) this method uses a backward loop. In this case,
|
|
|
+ * it is significantly faster than the corresponding method in
|
|
|
+ * {@link java.util.Arrays}.
|
|
|
+ *
|
|
|
+ * @param array an array.
|
|
|
+ * @param from the starting index of the portion to fill (inclusive).
|
|
|
+ * @param to the end index of the portion to fill (exclusive).
|
|
|
+ * @param value the new value for all elements of the specified portion of
|
|
|
+ * the array.
|
|
|
+ */
|
|
|
+ public static <K> void fill(K[] array, int from, int to, K value) {
|
|
|
+ ArrayAllocator.ensureFromTo(array, from, to);
|
|
|
+ for (int i = from; i < to; i++) {
|
|
|
+ array[i] = value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Fills the given array with the given value.
|
|
|
+ *
|
|
|
+ * <P>This method uses a backward loop. It is significantly faster than the
|
|
|
+ * corresponding method in {@link java.util.Arrays}.
|
|
|
+ *
|
|
|
+ * @param array an array.
|
|
|
+ * @param value the new value for all elements of the array.
|
|
|
+ */
|
|
|
+ public static void fill(boolean[] array, boolean value) {
|
|
|
+ for (int i=0; i<array.length; i++) {
|
|
|
+ array[i] = value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Reverses the order of the elements in the specified array.
|
|
|
+ *
|
|
|
+ * @param array the array to be reversed.
|
|
|
+ * @return <code>a</code>.
|
|
|
+ */
|
|
|
+ public static <K> K[] reverse(K[] array) {
|
|
|
+ int length = array.length;
|
|
|
+ for (int i = length / 2; i-- != 0;) {
|
|
|
+ K temp = array[ length - i - 1];
|
|
|
+ array[ length - i - 1] = array[ i];
|
|
|
+ array[ i] = temp;
|
|
|
+ }
|
|
|
+ return array; // NOPMD we return "input" array
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns true if the two arrays are elementwise equal.
|
|
|
+ *
|
|
|
+ * @param array1 an array.
|
|
|
+ * @param array2 another array.
|
|
|
+ * @return true if the two arrays are of the same length, and their elements
|
|
|
+ * are equal.
|
|
|
+ */
|
|
|
+ public static <K> boolean equals(K[] array1, K array2[]) {
|
|
|
+ // This method uses a backward loop.
|
|
|
+ // It is significantly faster than the java.util.Arrays
|
|
|
+ int i = array1.length;
|
|
|
+ if (i != array2.length) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ while (i-- != 0) {
|
|
|
+ if (!((array1[ i]) == null ? (array2[ i]) == null : (array1[ i]).equals(array2[ i]))) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static <K> K[] head(K[] values, K value, Comparator<K> cmp) {
|
|
|
+ return islice(values, 0, ifind(values, value, 0, cmp));
|
|
|
+ }
|
|
|
+
|
|
|
+ public static <K> K[] tail(K[] values, K value, Comparator<K> cmp) {
|
|
|
+ return islice(values, ifind(values, value, 0, cmp), values.length);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static <K> K[] slice(K[] values, K begin, K end, Comparator<K> cmp) {
|
|
|
+ int bi = ifind(values, begin, 0, cmp);
|
|
|
+ int ei = ifind(values, end, bi, cmp);
|
|
|
+ return islice(values, bi, ei);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static <K> int ifind(K[] values, K value, int begin, Comparator<K> cmp) {
|
|
|
+ int i = begin;
|
|
|
+ while(i<values.length && cmp.compare(values[i], value) < 0) {
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ return i;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static <K> K[] islice(K[] values, int begin, int end) {
|
|
|
+ int size = end - begin;
|
|
|
+ K[] result = ArrayAllocator.forPrototype(values, size);
|
|
|
+ System.arraycopy(values, begin, result, 0, size);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void shuffle(int size, Random random, Swapper swapper) {
|
|
|
+ for(int i=0; i<size; i++) {
|
|
|
+ swapper.swap(random.nextInt(size), random.nextInt(size));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static <T> void shuffle(T[] array, Random random) {
|
|
|
+ shuffle(array.length, random, Swapper.swapper(array));
|
|
|
+ }
|
|
|
+
|
|
|
+ public static <K> int size(K[] array) {
|
|
|
+ return null == array ? 0 : array.length;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static int size(Object array) {
|
|
|
+ return null == array ? 0 : Array.getLength(array);
|
|
|
+ }
|
|
|
+
|
|
|
+ @SuppressWarnings("PMD.NPathComplexity")
|
|
|
+ public static List<?> wrap(Object array) {
|
|
|
+ Class<?> c = array.getClass().getComponentType();
|
|
|
+ if(byte.class.equals(c)) {
|
|
|
+ return new ByteList(array);
|
|
|
+ }
|
|
|
+ if(short.class.equals(c)) {
|
|
|
+ return new ShortList(array);
|
|
|
+ }
|
|
|
+ if(int.class.equals(c)) {
|
|
|
+ return new IntegerList(array);
|
|
|
+ }
|
|
|
+ if(long.class.equals(c)) {
|
|
|
+ return new LongList(array);
|
|
|
+ }
|
|
|
+ if(float.class.equals(c)) {
|
|
|
+ return new FloatList(array);
|
|
|
+ }
|
|
|
+ if(double.class.equals(c)) {
|
|
|
+ return new DoubleList(array);
|
|
|
+ }
|
|
|
+ if(char.class.equals(c)) {
|
|
|
+ return new CharacterList(array);
|
|
|
+ }
|
|
|
+ if(boolean.class.equals(c)) {
|
|
|
+ return new BooleanList(array);
|
|
|
+ }
|
|
|
+ return Arrays.asList((Object[])array);
|
|
|
+ }
|
|
|
+
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ public static <T> List<T> $wrap(Object array) {
|
|
|
+ return (List<T>)wrap(array);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static abstract class ArrayWrapper<T> extends AbstractList<T> {
|
|
|
+
|
|
|
+ protected final Object array;
|
|
|
+
|
|
|
+ protected ArrayWrapper(Object array) {
|
|
|
+ this.array = array;
|
|
|
+ }
|
|
|
+
|
|
|
+ protected abstract void at(int index, T element);
|
|
|
+
|
|
|
+ protected abstract T at(int index);
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public final T set(int index, T element) {
|
|
|
+ T prev = at(index);
|
|
|
+ at(index, element);
|
|
|
+ return prev;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public T get(int index) {
|
|
|
+ return at(index);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int size() {
|
|
|
+ return Array.getLength(array);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private static final class ByteList extends ArrayWrapper<Byte> {
|
|
|
+
|
|
|
+ public ByteList(Object array) {
|
|
|
+ super(array);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void at(int index, Byte element) {
|
|
|
+ Array.setByte(array, index, element);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Byte at(int index) {
|
|
|
+ return Array.getByte(array, index);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private static final class ShortList extends ArrayWrapper<Short> {
|
|
|
+
|
|
|
+ public ShortList(Object array) {
|
|
|
+ super(array);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void at(int index, Short element) {
|
|
|
+ Array.setShort(array, index, element);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Short at(int index) {
|
|
|
+ return Array.getShort(array, index);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private static final class IntegerList extends ArrayWrapper<Integer> {
|
|
|
+
|
|
|
+ public IntegerList(Object array) {
|
|
|
+ super(array);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void at(int index, Integer element) {
|
|
|
+ Array.setInt(array, index, element);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Integer at(int index) {
|
|
|
+ return Array.getInt(array, index);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private static final class LongList extends ArrayWrapper<Long> {
|
|
|
+
|
|
|
+ public LongList(Object array) {
|
|
|
+ super(array);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void at(int index, Long element) {
|
|
|
+ Array.setLong(array, index, element);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Long at(int index) {
|
|
|
+ return Array.getLong(array, index);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private static final class FloatList extends ArrayWrapper<Float> {
|
|
|
+
|
|
|
+ public FloatList(Object array) {
|
|
|
+ super(array);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void at(int index, Float element) {
|
|
|
+ Array.setFloat(array, index, element);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Float at(int index) {
|
|
|
+ return Array.getFloat(array, index);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private static final class DoubleList extends ArrayWrapper<Double> {
|
|
|
+
|
|
|
+ public DoubleList(Object array) {
|
|
|
+ super(array);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void at(int index, Double element) {
|
|
|
+ Array.setDouble(array, index, element);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Double at(int index) {
|
|
|
+ return Array.getDouble(array, index);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private static final class CharacterList extends ArrayWrapper<Character> {
|
|
|
+
|
|
|
+ public CharacterList(Object array) {
|
|
|
+ super(array);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void at(int index, Character element) {
|
|
|
+ Array.setChar(array, index, element);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Character at(int index) {
|
|
|
+ return Array.getChar(array, index);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private static final class BooleanList extends ArrayWrapper<Boolean> {
|
|
|
+
|
|
|
+ public BooleanList(Object array) {
|
|
|
+ super(array);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void at(int index, Boolean element) {
|
|
|
+ Array.setBoolean(array, index, element);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Boolean at(int index) {
|
|
|
+ return Array.getBoolean(array, index);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|