Forráskód Böngészése

tests (96)

fix: ArrayUtils#wrap
fix: HashUtils#hashIterable (for primitive arrays)

fix: IntIterator,IntListIterator - default methods
fix: IteratorAdapters - method signature
Ranides Atterwim 10 éve
szülő
commit
e3613f0e2f

+ 507 - 424
assira/src/main/java/net/ranides/assira/collection/arrays/ArrayUtils.java

@@ -1,424 +1,507 @@
-/*
- *  @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);
-        }
-    
-    }
-
-    
-}
+/*
+ *  @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 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);
+        }
+
+    }
+    
+    private static final class ByteList extends ArrayWrapper<Byte> {
+		
+		private final byte[] array;
+
+        public ByteList(Object array) {
+            this.array = (byte[])array;
+        }
+
+        @Override
+        public void at(int index, Byte element) {
+			array[index] = element;
+        }
+
+        @Override
+        public Byte at(int index) {
+			return array[index];
+        }
+
+		@Override
+		public int size() {
+			return array.length;
+		}
+
+		@Override
+		public int hashCode() { //NOPMD
+			return Arrays.hashCode(array);
+		}
+		
+    }
+    
+    private static final class ShortList extends ArrayWrapper<Short> {
+
+        private final short[] array;
+
+        public ShortList(Object array) {
+            this.array = (short[])array;
+        }
+
+        @Override
+        public void at(int index, Short element) {
+            array[index] = element;
+        }
+
+        @Override
+        public Short at(int index) {
+            return array[index];
+        }
+		
+		@Override
+		public int size() {
+			return array.length;
+		}
+
+		@Override
+		public int hashCode() { //NOPMD
+			return Arrays.hashCode(array);
+		}
+    
+    }
+    
+    private static final class IntegerList extends ArrayWrapper<Integer> {
+
+        private final int[] array;
+
+        public IntegerList(Object array) {
+            this.array = (int[])array;
+        }
+
+        @Override
+        public void at(int index, Integer element) {
+            array[index] = element;
+        }
+
+        @Override
+        public Integer at(int index) {
+            return array[index];
+        }
+		
+		@Override
+		public int size() {
+			return array.length;
+		}
+
+		@Override
+		public int hashCode() { //NOPMD
+			return Arrays.hashCode(array);
+		}
+    
+    }
+    
+    private static final class LongList extends ArrayWrapper<Long> {
+
+        private final long[] array;
+
+        public LongList(Object array) {
+            this.array = (long[])array;
+        }
+
+        @Override
+        public void at(int index, Long element) {
+            array[index] = element;
+        }
+
+        @Override
+        public Long at(int index) {
+            return array[index];
+        }
+		
+		@Override
+		public int size() {
+			return array.length;
+		}
+
+		@Override
+		public int hashCode() { //NOPMD
+			return Arrays.hashCode(array);
+		}
+    
+    }
+    
+    private static final class FloatList extends ArrayWrapper<Float> {
+
+        private final float[] array;
+
+        public FloatList(Object array) {
+            this.array = (float[])array;
+        }
+
+        @Override
+        public void at(int index, Float element) {
+            array[index] = element;
+        }
+
+        @Override
+        public Float at(int index) {
+            return array[index];
+        }
+		
+		@Override
+		public int size() {
+			return array.length;
+		}
+
+		@Override
+		public int hashCode() { //NOPMD
+			return Arrays.hashCode(array);
+		}
+    
+    }
+    
+    private static final class DoubleList extends ArrayWrapper<Double> {
+
+        private final double[] array;
+
+        public DoubleList(Object array) {
+            this.array = (double[])array;
+        }
+
+        @Override
+        public void at(int index, Double element) {
+            array[index] = element;
+        }
+
+        @Override
+        public Double at(int index) {
+            return array[index];
+        }
+		
+		@Override
+		public int size() {
+			return array.length;
+		}
+
+		@Override
+		public int hashCode() { //NOPMD
+			return Arrays.hashCode(array);
+		}
+    
+    }
+    
+    private static final class CharacterList extends ArrayWrapper<Character> {
+
+        private final char[] array;
+
+        public CharacterList(Object array) {
+            this.array = (char[])array;
+        }
+
+        @Override
+        public void at(int index, Character element) {
+            array[index] = element;
+        }
+
+        @Override
+        public Character at(int index) {
+            return array[index];
+        }
+		
+		@Override
+		public int size() {
+			return array.length;
+		}
+
+		@Override
+		public int hashCode() { //NOPMD
+			return Arrays.hashCode(array);
+		}
+    
+    }
+    
+    private static final class BooleanList extends ArrayWrapper<Boolean> {
+
+        private final boolean[] array;
+
+        public BooleanList(Object array) {
+            this.array = (boolean[])array;
+        }
+
+        @Override
+        public void at(int index, Boolean element) {
+            array[index] = element;
+        }
+
+        @Override
+        public Boolean at(int index) {
+            return array[index];
+        }
+		
+		@Override
+		public int size() {
+			return array.length;
+		}
+
+		@Override
+		public int hashCode() { //NOPMD
+			return Arrays.hashCode(array);
+		}
+    
+    }
+    
+}

+ 1 - 18
assira/src/main/java/net/ranides/assira/collection/iterators/IntIterator.java

@@ -10,9 +10,7 @@ import java.util.Iterator;
 
 public interface IntIterator extends Iterator<Integer> {
 
-    default int nextInt() {
-        return next();
-    }
+    int nextInt();
 
     @Override
     default Integer next() {
@@ -63,19 +61,4 @@ public interface IntIterator extends Iterator<Integer> {
         };
     }
     
-    static String toString(IntIterator iterator) {
-        if ( !iterator.hasNext() ) {
-            return "[]";
-        }
-        StringBuilder builder = new StringBuilder();
-        builder.append('[');
-        for (;;) {
-            builder.append(iterator.nextInt());
-            if ( !iterator.hasNext() ) {
-                return builder.append(']').toString();
-            }
-            builder.append(", ");
-        }
-    }
-
 }

+ 1 - 3
assira/src/main/java/net/ranides/assira/collection/iterators/IntListIterator.java

@@ -38,9 +38,7 @@ public interface IntListIterator extends IntIterator, ListIterator<Integer> {
         add(value.intValue());
     }
 
-    default int previousInt() {
-        return previous();
-    }
+    int previousInt();
 
     @Override
     default Integer previous() {

+ 211 - 211
assira/src/main/java/net/ranides/assira/collection/iterators/IteratorAdapters.java

@@ -1,211 +1,211 @@
-/*
- * @author Ranides Atterwim <ranides@gmail.com>
- * @copyright Ranides Atterwim
- * @license WTFPL
- * @url http://ranides.net/projects/assira
- */
-package net.ranides.assira.collection.iterators;
-
-import java.util.Iterator;
-import java.util.ListIterator;
-import java.util.function.Function;
-import java.util.function.IntUnaryOperator;
-
-/**
- *
- * @author Ranides Atterwim <ranides@gmail.com>
- */
-public final class IteratorAdapters {
-    
-    private IteratorAdapters() { }
-    
-    public static <S,T> Iterator<T> apply(Iterator<S> iterator, Function<S,T> function) {
-        return new Adapter<>(iterator, function);
-    }
-    
-    public static <S,T> IntIterator apply(IntIterator iterator, IntUnaryOperator function) {
-        return new IntAdapter(iterator, function);
-    }
-    
-    public static <S,T> ListIterator<T> apply(ListIterator<S> iterator, Function<S,T> function) {
-        return new ListAdapter<>(iterator, function);
-    }
-    
-    public static <S,T> IntIterator apply(IntListIterator iterator, IntUnaryOperator function) {
-        return new IntListAdapter(iterator, function);
-    }
-
-    private static final class Adapter<S, T> implements Iterator<T> {
-    
-        protected final Iterator<S> delegate;
-        
-        protected final Function<S,T> function;
-
-        protected <E> Adapter(Iterator<S> delegate, Function<S,T> function) {
-            this.delegate = delegate;
-            this.function = function;
-        }
-
-        @Override
-        public boolean hasNext() {
-            return delegate.hasNext();
-        }
-
-        @Override
-        public T next() {
-            return function.apply(delegate.next());
-        }
-
-        @Override
-        public void remove() {
-            delegate.remove();
-        }
-        
-    }    
-    
-    private static final class IntAdapter implements IntIterator {
-    
-        protected final IntIterator delegate;
-        
-        protected final IntUnaryOperator function;
-
-        protected IntAdapter(IntIterator delegate, IntUnaryOperator function) {
-            this.delegate = delegate;
-            this.function = function;
-        }
-
-        @Override
-        public boolean hasNext() {
-            return delegate.hasNext();
-        }
-
-        @Override
-        public int nextInt() {
-            return function.applyAsInt(delegate.nextInt());
-        }
-        
-        @Override
-        public void remove() {
-            delegate.remove();
-        }
-    } 
-    
-    private static final class ListAdapter<S, T> implements ListIterator<T> {
-    
-        protected final ListIterator<S> delegate;
-        
-        protected final Function<S,T> function;
-
-        protected <E> ListAdapter(ListIterator<S> delegate, Function<S,T> function) {
-            this.delegate = delegate;
-            this.function = function;
-        }
-        
-        @Override
-        public T next() {
-            return function.apply(delegate.next());
-        }
-        
-        @Override
-        public T previous() {
-            return function.apply(delegate.previous());
-        }
-
-        @Override
-        public boolean hasNext() {
-            return delegate.hasNext();
-        }
-
-        @Override
-        public boolean hasPrevious() {
-            return delegate.hasPrevious();
-        }
-
-        @Override
-        public int nextIndex() {
-            return delegate.nextIndex();
-        }
-
-        @Override
-        public int previousIndex() {
-            return delegate.previousIndex();
-        }
-
-        @Override
-        public void remove() {
-            delegate.remove();
-        }
-
-        @Override
-        public void set(T value) {
-            throw new UnsupportedOperationException("");
-        }
-
-        @Override
-        public void add(T value) {
-            throw new UnsupportedOperationException("");
-        }
-        
-    }
-    
-    private static final class IntListAdapter implements IntListIterator {
-
-        protected final IntListIterator delegate;
-        
-        protected final IntUnaryOperator function;
-
-        protected <E> IntListAdapter(IntListIterator delegate, IntUnaryOperator function) {
-            this.delegate = delegate;
-            this.function = function;
-        }
-        
-        @Override
-        public int nextInt() {
-            return function.applyAsInt(delegate.nextInt());
-        }
-
-
-        @Override
-        public int previousInt() {
-            return function.applyAsInt(delegate.previousInt());
-        }
-
-        @Override
-        public boolean hasNext() {
-            return delegate.hasNext();
-        }
-        
-        @Override
-        public boolean hasPrevious() {
-            return delegate.hasPrevious();
-        }
-
-        @Override
-        public int nextIndex() {
-            return delegate.nextIndex();
-        }
-
-        @Override
-        public int previousIndex() {
-            return delegate.previousIndex();
-        }
-
-        @Override
-        public void remove() {
-            delegate.remove();
-        }
-        
-        @Override
-        public void add(int value) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void set(int value) {
-            throw new UnsupportedOperationException();
-        }
-        
-    }
-    
-    
-}
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.collection.iterators;
+
+import java.util.Iterator;
+import java.util.ListIterator;
+import java.util.function.Function;
+import java.util.function.IntUnaryOperator;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public final class IteratorAdapters {
+    
+    private IteratorAdapters() { }
+    
+    public static <S,T> Iterator<T> apply(Iterator<S> iterator, Function<S,T> function) {
+        return new Adapter<>(iterator, function);
+    }
+    
+    public static <S,T> IntIterator apply(IntIterator iterator, IntUnaryOperator function) {
+        return new IntAdapter(iterator, function);
+    }
+    
+    public static <S,T> ListIterator<T> apply(ListIterator<S> iterator, Function<S,T> function) {
+        return new ListAdapter<>(iterator, function);
+    }
+    
+    public static <S,T> IntListIterator apply(IntListIterator iterator, IntUnaryOperator function) {
+        return new IntListAdapter(iterator, function);
+    }
+
+    private static final class Adapter<S, T> implements Iterator<T> {
+    
+        protected final Iterator<S> delegate;
+        
+        protected final Function<S,T> function;
+
+        protected <E> Adapter(Iterator<S> delegate, Function<S,T> function) {
+            this.delegate = delegate;
+            this.function = function;
+        }
+
+        @Override
+        public boolean hasNext() {
+            return delegate.hasNext();
+        }
+
+        @Override
+        public T next() {
+            return function.apply(delegate.next());
+        }
+
+        @Override
+        public void remove() {
+            delegate.remove();
+        }
+        
+    }    
+    
+    private static final class IntAdapter implements IntIterator {
+    
+        protected final IntIterator delegate;
+        
+        protected final IntUnaryOperator function;
+
+        protected IntAdapter(IntIterator delegate, IntUnaryOperator function) {
+            this.delegate = delegate;
+            this.function = function;
+        }
+
+        @Override
+        public boolean hasNext() {
+            return delegate.hasNext();
+        }
+
+        @Override
+        public int nextInt() {
+            return function.applyAsInt(delegate.nextInt());
+        }
+        
+        @Override
+        public void remove() {
+            delegate.remove();
+        }
+    } 
+    
+    private static final class ListAdapter<S, T> implements ListIterator<T> {
+    
+        protected final ListIterator<S> delegate;
+        
+        protected final Function<S,T> function;
+
+        protected <E> ListAdapter(ListIterator<S> delegate, Function<S,T> function) {
+            this.delegate = delegate;
+            this.function = function;
+        }
+        
+        @Override
+        public T next() {
+            return function.apply(delegate.next());
+        }
+        
+        @Override
+        public T previous() {
+            return function.apply(delegate.previous());
+        }
+
+        @Override
+        public boolean hasNext() {
+            return delegate.hasNext();
+        }
+
+        @Override
+        public boolean hasPrevious() {
+            return delegate.hasPrevious();
+        }
+
+        @Override
+        public int nextIndex() {
+            return delegate.nextIndex();
+        }
+
+        @Override
+        public int previousIndex() {
+            return delegate.previousIndex();
+        }
+
+        @Override
+        public void remove() {
+            delegate.remove();
+        }
+
+        @Override
+        public void set(T value) {
+            throw new UnsupportedOperationException("");
+        }
+
+        @Override
+        public void add(T value) {
+            throw new UnsupportedOperationException("");
+        }
+        
+    }
+    
+    private static final class IntListAdapter implements IntListIterator {
+
+        protected final IntListIterator delegate;
+        
+        protected final IntUnaryOperator function;
+
+        protected <E> IntListAdapter(IntListIterator delegate, IntUnaryOperator function) {
+            this.delegate = delegate;
+            this.function = function;
+        }
+        
+        @Override
+        public int nextInt() {
+            return function.applyAsInt(delegate.nextInt());
+        }
+
+
+        @Override
+        public int previousInt() {
+            return function.applyAsInt(delegate.previousInt());
+        }
+
+        @Override
+        public boolean hasNext() {
+            return delegate.hasNext();
+        }
+        
+        @Override
+        public boolean hasPrevious() {
+            return delegate.hasPrevious();
+        }
+
+        @Override
+        public int nextIndex() {
+            return delegate.nextIndex();
+        }
+
+        @Override
+        public int previousIndex() {
+            return delegate.previousIndex();
+        }
+
+        @Override
+        public void remove() {
+            delegate.remove();
+        }
+        
+        @Override
+        public void add(int value) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void set(int value) {
+            throw new UnsupportedOperationException();
+        }
+        
+    }
+    
+    
+}

+ 2 - 2
assira/src/main/java/net/ranides/assira/collection/lists/IntRange.java

@@ -85,7 +85,7 @@ public class IntRange extends AIntList implements RandomAccess {
         }
 
         @Override
-        public Integer next() {
+        public int nextInt() {
 			if(hasNext()) {
 				return current++;
 			}
@@ -98,7 +98,7 @@ public class IntRange extends AIntList implements RandomAccess {
         }
 
         @Override
-        public Integer previous() {
+        public int previousInt() {
 			if(hasPrevious()) {
 				return --current;
 			}

+ 2 - 1
assira/src/main/java/net/ranides/assira/generic/HashUtils.java

@@ -10,6 +10,7 @@ import java.math.BigInteger;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.Arrays;
+import net.ranides.assira.collection.arrays.ArrayUtils;
 import net.ranides.assira.text.Charsets;
 
 @SuppressWarnings({
@@ -101,7 +102,7 @@ public final class HashUtils {
                 continue;
             }
             if( value.getClass().isArray() ) {
-                hash += Arrays.hashCode((Object[])value);
+                hash += ArrayUtils.wrap(value).hashCode();
             } else {
                 hash += value.hashCode();
             }

+ 60 - 0
assira/src/test/java/net/ranides/assira/collection/iterators/IteratorAdaptersTest.java

@@ -0,0 +1,60 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.collection.iterators;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.ListIterator;
+import net.ranides.assira.collection.arrays.ArrayUtils;
+import net.ranides.assira.collection.lists.IntArrayList;
+import net.ranides.assira.collection.suite.IteratorTester;
+import org.junit.Test;
+
+/**
+ *
+ * @author msieron
+ */
+
+
+public class IteratorAdaptersTest {
+	
+	public IteratorAdaptersTest() {
+	}
+
+	@Test
+	public void testIteratorApply() {
+		Iterator<String> s = Arrays.asList("a", "b", "c", "d").iterator();
+		Iterator<String> i = IteratorAdapters.apply(s, String::toUpperCase);
+		
+		IteratorTester.basicIterator(i, 0, new String[]{"A", "B", "C", "D"});
+	}
+	
+	@Test
+	public void testIntIteratorApply() {
+		IntIterator s = IntArrayList.wrap(new int[]{1,2,3,4,5}).iterator();
+		IntIterator i = IteratorAdapters.apply(s, (int v)->10*v);
+		
+		IteratorTester.basicIterator(i, 0, new Integer[]{10,20,30,40,50});
+	}
+	
+	@Test
+	public void testListIteratorApply() {
+		ListIterator<String> s = Arrays.asList("a", "b", "c", "d").listIterator();
+		ListIterator<String> i = IteratorAdapters.apply(s, String::toUpperCase);
+		
+		IteratorTester.listIterator(i, 0, new String[]{"A", "B", "C", "D"});
+	}
+	
+	@Test
+	public void testIntListIteratorApply() {
+		IntListIterator s = IntArrayList.wrap(new int[]{1,2,3,4,5}).iterator();
+		IntListIterator i = IteratorAdapters.apply(s, (int v)->10*v);
+		
+		IteratorTester.listIterator(i, 0, new Integer[]{10,20,30,40,50});
+	}
+	
+}

+ 119 - 0
assira/src/test/java/net/ranides/assira/generic/HashUtilsTest.java

@@ -0,0 +1,119 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.generic;
+
+import java.util.Arrays;
+import java.util.List;
+import org.junit.Test;
+import static net.ranides.assira.junit.NewAssert.*;
+
+/**
+ *
+ * @author msieron
+ */
+
+
+public class HashUtilsTest {
+	
+	public HashUtilsTest() {
+	}
+
+	@Test
+	public void testMurmurHash3() {
+		assertEquals(0x00000000, HashUtils.murmurHash3(0x0000000));
+		assertEquals(0xAA4AA778, HashUtils.murmurHash3(0x00000020));
+		assertEquals(0xB1A38591, HashUtils.murmurHash3(0x00003434));
+		assertEquals(0xA23BAE67, HashUtils.murmurHash3(0x0000FFFF));
+		assertEquals(0xF9CC0EA8, HashUtils.murmurHash3(0x7FFFFFFF));
+		assertEquals(0x81F16F39, HashUtils.murmurHash3(0xFFFFFFFF));
+		
+		assertEquals(0x0000000000000000L, HashUtils.murmurHash3(0x00000000L));
+		assertEquals(0xCC15890F1EEE9F7DL, HashUtils.murmurHash3(0x00000020L));
+		assertEquals(0xADF941FD9F597C3AL, HashUtils.murmurHash3(0x00003434L));
+		assertEquals(0x596F4BAF0B892560L, HashUtils.murmurHash3(0x0000FFFFL));
+		assertEquals(0x8A662C1A93A26B91L, HashUtils.murmurHash3(0x7FFFFFFFL));
+		assertEquals(0xCC71ECDA2AA8BCC6L, HashUtils.murmurHash3(0xFFFFFFFFL));
+	}
+	
+	
+	@Test
+	public void testHash() {
+		assertEquals("A".hashCode(), HashUtils.hash("A"));
+		assertEquals(0, HashUtils.hash(null));
+	}
+	
+	@Test
+	public void testHashPair() {
+		assertEquals(0 ^ 11, HashUtils.hashPair(0, 11));
+		assertEquals(0 ^ 11, HashUtils.hashPair(null, 11));
+		assertEquals(99 ^ 1037, HashUtils.hashPair(99, 1037));
+		assertEquals(99 ^ 0, HashUtils.hashPair(99, 0));
+		assertEquals(99 ^ 0, HashUtils.hashPair(99, null));
+	}
+	
+	
+	@Test
+	public void testHashIterable() {
+		List<Integer> list1 = Arrays.asList(3,4,5);
+		List<Integer> list2 = Arrays.asList(3,4,5,null);
+		List<Integer> list3 = Arrays.asList(3,4,null, 5);
+		
+		assertEquals(345,  HashUtils.hashIterable(0, 10, list1));
+		assertEquals(3450, HashUtils.hashIterable(0, 10, list2));
+		assertEquals(3405, HashUtils.hashIterable(0, 10, list3));
+	}
+	
+	@Test
+	public void testHashIterable_Array() {
+		Integer[] v1 = new Integer[]{1};
+		Integer[] v2 = new Integer[]{2};
+		Integer[] v3 = new Integer[]{3};
+		List<Integer[]> list1 = Arrays.asList(v1,v2,v3);
+		List<Integer[]> list2 = Arrays.asList(v1,v2,v3,null);
+		List<Integer[]> list3 = Arrays.asList(v1,v2,null, v3);
+		
+		int h1 = Arrays.hashCode(v1);
+		int h2 = Arrays.hashCode(v2);
+		int h3 = Arrays.hashCode(v3);
+	
+		assertEquals( (((h1*100)+h2)*100)+h3, HashUtils.hashIterable(0, 100, list1));
+		assertEquals( ((((h1*100)+h2)*100)+h3)*100, HashUtils.hashIterable(0, 100, list2));
+		assertEquals( ((((h1*100)+h2)*100)+0)*100+h3, HashUtils.hashIterable(0, 100, list3));
+	}
+	
+	@Test
+	public void testHashIterable_Array_primitive() {
+		int[] v1 = new int[]{1};
+		int[] v2 = new int[]{2};
+		int[] v3 = new int[]{3};
+		List<int[]> list1 = Arrays.asList(v1,v2,v3);
+		List<int[]> list2 = Arrays.asList(v1,v2,v3,null);
+		List<int[]> list3 = Arrays.asList(v1,v2,null, v3);
+		
+		int h1 = Arrays.hashCode(v1);
+		int h2 = Arrays.hashCode(v2);
+		int h3 = Arrays.hashCode(v3);
+	
+		assertEquals( (((h1*100)+h2)*100)+h3, HashUtils.hashIterable(0, 100, list1));
+		assertEquals( ((((h1*100)+h2)*100)+h3)*100, HashUtils.hashIterable(0, 100, list2));
+		assertEquals( ((((h1*100)+h2)*100)+0)*100+h3, HashUtils.hashIterable(0, 100, list3));
+	}
+	
+	@Test
+	public void testDigest() {
+		String h = "b7f783baed8297f0db917462184ff4f08e69c2d5e5f79a942600f9725f58ce1f29c18139bf80b06c0fff2bdd34738452ecf40c488c22a7e3d80cdf6f9c1c0d47";
+		assertEquals(h, HashUtils.digest("Hello world"));
+		
+		assertNull(HashUtils.digest(null));
+		assertNull(HashUtils.digest(""));
+		
+		assertThrows(UnsupportedOperationException.class, ()->{
+			HashUtils.digest("Hello world", "invalid-algorithm");
+		});
+	}
+	
+}

+ 60 - 0
assira/src/test/java/net/ranides/assira/trace/LoggerUtilsTest.java

@@ -0,0 +1,60 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.trace;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import net.ranides.assira.junit.NewAssert;
+import net.ranides.assira.system.RuntimeUtils;
+import net.ranides.assira.text.Charsets;
+import static org.junit.Assert.*;
+import org.junit.Test;
+import org.slf4j.Logger;
+
+/**
+ *
+ * @author msieron
+ */
+
+
+public class LoggerUtilsTest {
+	
+	private static final String EXPECTED = String.format(
+		"[main] ERROR net.ranides.assira.trace.LoggerUtilsTest - Hello world!%n"
+	);
+	
+	public LoggerUtilsTest() {
+	}
+
+	@Test
+	public void testTraceLogger() throws UnsupportedEncodingException {
+		PrintStream preverr = System.err;
+		ByteArrayOutputStream output = new ByteArrayOutputStream();
+		System.setErr(new PrintStream(output, true));
+		
+		try {
+			Logger logger = LoggerUtils.getTraceLogger();
+
+			if( !RuntimeUtils.invokedInsideSingleTest()) {
+				return;
+			}
+
+			logger.error("Hello world!");
+			assertEquals(EXPECTED, output.toString(Charsets.UTF8.name()));
+
+			NewAssert.assertThrows(AssertionError.class, ()->{
+				LoggerUtils.getTraceLogger();
+			});
+
+		} finally {
+			System.setErr(preverr);
+		}
+		
+	}
+	
+}