Ranides Atterwim 13 éve
szülő
commit
e460d61b5b

+ 12 - 12
src/main/java/net/ranides/assira/collection/list/RTList.java

@@ -12,21 +12,21 @@ import java.util.Collection;
 /**
  * <p>
  * Specjalna wersja listy, oszczędzająca pamięć w maksymalnym możliwym stopniu.
- * Dokonuje realokacji po dowolnej modyfikacji, odpowiednio zwiększając lub 
+ * Dokonuje realokacji po dowolnej modyfikacji, odpowiednio zwiększając lub
  * zmniejszając zużycie pamięci w czasie rzeczywistym. W szczególności pusta
  * lista wprowadza minimalny narzut pamięciowy, tzn nie alokuje żadnej pamięci na bufor.
  * </p><p>
- * Klasa wzorowana na {@link javax.swing.event.EventListenerList}, szczególnie 
+ * Klasa wzorowana na {@link javax.swing.event.EventListenerList}, szczególnie
  * przydatna do obsługi kolekcji, które przez większość czasu nie są modyfikowane,
  * posiadają mało elementów, lub w ogóle pozostają puste.
  * </p>
  * całej zawartości
- * @param <T> 
+ * @param <T>
  * @author ranides
  */
 @SuppressWarnings("unchecked")
 public class RTList<T> extends AbstractList<T> {
-    
+
     private final static Object[] EMPTY = new Object[0];
     private Object[] content = EMPTY;
 
@@ -36,7 +36,7 @@ public class RTList<T> extends AbstractList<T> {
     public RTList() {
         // do nothing
     }
-    
+
     /**
      * Tworzy nową listę, zawierającą podane elementy.
      * @param values
@@ -44,7 +44,7 @@ public class RTList<T> extends AbstractList<T> {
     public RTList(Collection<? extends T> values) {
         content = values.toArray();
     }
-    
+
     @Override
     public T get(int index) {
         return (T)content[index];
@@ -54,12 +54,12 @@ public class RTList<T> extends AbstractList<T> {
     public int size() {
         return content.length;
     }
-    
+
     @Override
     public void clear() {
         content = EMPTY;
     }
-    
+
     @Override
     public T set(int index, T element) {
         T prev = (T)content[index];
@@ -70,8 +70,8 @@ public class RTList<T> extends AbstractList<T> {
     @Override
     public void add(int index, T element) {
         if(index > content.length) {
-                throw new IndexOutOfBoundsException(index + " out of bound " + content.length);
-            }
+            throw new IndexOutOfBoundsException(index + " out of bound " + content.length);
+        }
         if(content == EMPTY) {
             content = new Object[]{ element };
             return;
@@ -104,9 +104,9 @@ public class RTList<T> extends AbstractList<T> {
         if( content.length - index > 1) {
             System.arraycopy(content, index+1, buffer, index, content.length - index - 1);
         }
-        
+
         content = buffer;
         return prev;
     }
-    
+
 }

+ 251 - 126
src/test/java/net/ranides/assira/collection/ArrayUtilsTest.java

@@ -13,6 +13,8 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.ListIterator;
 import java.util.Set;
+import net.ranides.assira.generic.CoFunction;
+import net.ranides.assira.generic.Function;
 import net.ranides.assira.generic.ValueUtils;
 import net.ranides.assira.math.Randomizer;
 import net.ranides.assira.reflection.ClassInspector;
@@ -27,79 +29,79 @@ import static org.junit.Assert.*;
 @SuppressWarnings("PMD.AvoidDuplicateLiterals")
 @edu.umd.cs.findbugs.annotations.SuppressWarnings("DLS_DEAD_LOCAL_STORE")
 public class ArrayUtilsTest {
-    
+
     public ArrayUtilsTest() {
     }
-    
+
     @Test
     public void testWrap() {
         Integer[] boxArray = new Integer[]{1,2,3,4,5,6};
         List<Integer> boxList = ArrayUtils.wrap(boxArray);
-        
+
         boxArray[2] = 77;
         boxList.set(3, 78);
-        
+
         assertEquals(boxList, Arrays.asList(1,2,77,78,5,6));
         assertArrayEquals(boxArray, new Integer[]{1,2,77,78,5,6});
     }
-    
+
     @Test
     public void testWrapRaw() {
         int[] rawArray = new int[]{1,2,3,4,5,6};
         List<Integer> rawList = ArrayUtils.wrap(rawArray);
-        
+
         rawArray[2] = 77;
         rawList.set(3, 78);
-        
+
         assertEquals(rawList, Arrays.asList(1,2,77,78,5,6));
         assertArrayEquals(rawArray, new int[]{1,2,77,78,5,6});
     }
-    
+
     @Test
     public void testWrapCast() {
         short[] array = new short[]{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,0x88};
         List<Integer> list = ArrayUtils.wrap(int[].class, array);
-        
+
         array[2] = 0xE33;
         list.set(2, 0x1c2c3c4c);
-        
+
         assertArrayEquals(new short[]{0x11, 0x22, 0xe33, 0x44, 0x3c4c, 0x1c2c, 0x77, 0x88 }, array);
         assertEquals(Arrays.asList(0x220011, 0x440e33, 0x1c2c3c4c, 0x880077), list);
-        
+
         assertSame(list, ArrayUtils.wrap(int[].class, list));
         assertEquals(Collections.emptyList(), ArrayUtils.wrap(int[].class, null));
         assertEquals(Collections.emptyList(), ArrayUtils.wrap(int[].class, new float[0]));
     }
-    
+
     @Test
     public void testAsList() {
         Integer[] boxArray = new Integer[]{1,2,3,4,5,6};
         List<Integer> boxList = ArrayUtils.asList(boxArray);
-        
+
         boxArray[2] = 77;
         boxList.set(3, 78);
-        
+
         assertEquals(boxList, Arrays.asList(1,2,77,78,5,6));
         assertArrayEquals(boxArray, new Integer[]{1,2,77,78,5,6});
-        
+
     }
 
     @Test
     public void testShift() {
         Integer[] data1 = new Integer[]{1,2,3,4,5,6};
-       
+
         ArrayUtils.shift(data1);
         assertArrayEquals(new Integer[]{2, 3, 4, 5, 6, 6}, data1);
-        
+
         ArrayUtils.shift(data1);
         assertArrayEquals(new Integer[]{3, 4, 5, 6, 6, 6}, data1);
-        
-        
+
+
         Integer[] data2 = new Integer[]{1,2};
         ArrayUtils.shift(data2);
         assertArrayEquals(new Integer[]{2, 2}, data2);
-        
-        
+
+
         Integer[] data3 = new Integer[]{1};
         ArrayUtils.shift(data3);
         assertArrayEquals(new Integer[]{1}, data3);
@@ -110,18 +112,37 @@ public class ArrayUtilsTest {
         } catch(EmptyCollectionException cause) {
             assertTrue(true);
         }
+
+        try {
+            ArrayUtils.shift((Integer[])null);
+            fail("exception expected");
+        } catch(EmptyCollectionException cause) {
+            assertTrue(true);
+        }
+        try {
+            ArrayUtils.shift(new int[]{});
+            fail("exception expected");
+        } catch(EmptyCollectionException cause) {
+            assertTrue(true);
+        }
+        try {
+            ArrayUtils.shift((int[])null);
+            fail("exception expected");
+        } catch(EmptyCollectionException cause) {
+            assertTrue(true);
+        }
     }
-    
+
     @Test
     public void testShiftPrimitive() {
         // wiemy już, że shift(T[]) działa dobrze, resztę testujemy w oparciu
         // o porównanie, czy shift tablicy wrapowanej daje to samo co shift native
-        
+
 
         new ShiftTest<char[]>(2, char[].class) { @Override void run() {
             ArrayUtils.shift(array);
             ArrayUtils.shift(boxed);
-        }}; 
+        }};
         new ShiftTest<char[]>(20, char[].class) { @Override void run() {
             ArrayUtils.shift(array);
             ArrayUtils.shift(array);
@@ -133,11 +154,11 @@ public class ArrayUtilsTest {
             ArrayUtils.shift(boxed);
             ArrayUtils.unshift(boxed);
         }};
-        
+
         new ShiftTest<byte[]>(2, byte[].class) { @Override void run() {
             ArrayUtils.shift(array);
             ArrayUtils.shift(boxed);
-        }}; 
+        }};
         new ShiftTest<byte[]>(20, byte[].class) { @Override void run() {
             ArrayUtils.shift(array);
             ArrayUtils.shift(array);
@@ -149,11 +170,11 @@ public class ArrayUtilsTest {
             ArrayUtils.shift(boxed);
             ArrayUtils.unshift(boxed);
         }};
-        
+
         new ShiftTest<short[]>(2, short[].class) { @Override void run() {
             ArrayUtils.shift(array);
             ArrayUtils.shift(boxed);
-        }}; 
+        }};
         new ShiftTest<short[]>(20, short[].class) { @Override void run() {
             ArrayUtils.shift(array);
             ArrayUtils.shift(array);
@@ -165,11 +186,11 @@ public class ArrayUtilsTest {
             ArrayUtils.shift(boxed);
             ArrayUtils.unshift(boxed);
         }};
-        
+
         new ShiftTest<int[]>(2, int[].class) { @Override void run() {
             ArrayUtils.shift(array);
             ArrayUtils.shift(boxed);
-        }}; 
+        }};
         new ShiftTest<int[]>(20, int[].class) { @Override void run() {
             ArrayUtils.shift(array);
             ArrayUtils.shift(array);
@@ -180,12 +201,12 @@ public class ArrayUtilsTest {
             ArrayUtils.shift(boxed);
             ArrayUtils.shift(boxed);
             ArrayUtils.unshift(boxed);
-        }}; 
-        
+        }};
+
         new ShiftTest<long[]>(2, long[].class) { @Override void run() {
             ArrayUtils.shift(array);
             ArrayUtils.shift(boxed);
-        }}; 
+        }};
         new ShiftTest<long[]>(20, long[].class) { @Override void run() {
             ArrayUtils.shift(array);
             ArrayUtils.shift(array);
@@ -197,11 +218,11 @@ public class ArrayUtilsTest {
             ArrayUtils.shift(boxed);
             ArrayUtils.unshift(boxed);
         }};
-        
+
         new ShiftTest<float[]>(2, float[].class) { @Override void run() {
             ArrayUtils.shift(array);
             ArrayUtils.shift(boxed);
-        }}; 
+        }};
         new ShiftTest<float[]>(20, float[].class) { @Override void run() {
             ArrayUtils.shift(array);
             ArrayUtils.shift(array);
@@ -213,11 +234,11 @@ public class ArrayUtilsTest {
             ArrayUtils.shift(boxed);
             ArrayUtils.unshift(boxed);
         }};
-        
+
         new ShiftTest<double[]>(2, double[].class) { @Override void run() {
             ArrayUtils.shift(array);
             ArrayUtils.shift(boxed);
-        }}; 
+        }};
         new ShiftTest<double[]>(20, double[].class) { @Override void run() {
             ArrayUtils.shift(array);
             ArrayUtils.shift(array);
@@ -229,11 +250,11 @@ public class ArrayUtilsTest {
             ArrayUtils.shift(boxed);
             ArrayUtils.unshift(boxed);
         }};
-        
+
         new ShiftTest<boolean[]>(2, boolean[].class) { @Override void run() {
             ArrayUtils.shift(array);
             ArrayUtils.shift(boxed);
-        }}; 
+        }};
         new ShiftTest<boolean[]>(20, boolean[].class) { @Override void run() {
             ArrayUtils.shift(array);
             ArrayUtils.shift(array);
@@ -247,24 +268,24 @@ public class ArrayUtilsTest {
         }};
         assertTrue(true);
     }
-    
+
     private static abstract class ShiftTest<P> {
-        
+
         final P array;
         final Object[] boxed;
-        
+
         abstract void run();
 
         @SuppressWarnings({"unchecked", "OverridableMethodCallInConstructor"})
         public ShiftTest(int size, Class<P> type) {
             List list = Randomizer.list(type.getComponentType(), size);
-            
+
             array = (P)ArrayUtils.toArray(type, list);
             boxed = (Object[])ArrayUtils.toArray(ClassInspector.box(type), list);
-            
+
             List plist = ArrayUtils.wrap(array);
             List blist = ArrayUtils.wrap(boxed);
-                        
+
             for(int cycle=0; cycle<5; cycle++) {
                 run();
                 for(int i=0; i<size; i++) {
@@ -277,35 +298,52 @@ public class ArrayUtilsTest {
             }
         }
     }
-    
+
     @Test
     public void testUnshift() {
         Integer[] data1 = new Integer[]{1,2,3,4,5,6};
-       
+
         ArrayUtils.unshift(data1);
         assertArrayEquals(new Integer[]{1, 1, 2, 3, 4, 5}, data1);
-        
+
         ArrayUtils.unshift(data1);
         assertArrayEquals(new Integer[]{1, 1, 1, 2, 3, 4}, data1);
-        
+
         Integer[] data2 = new Integer[]{1,2};
         ArrayUtils.unshift(data2);
         assertArrayEquals(new Integer[]{1, 1}, data2);
-        
-        
+
+
         Integer[] data3 = new Integer[]{1};
         ArrayUtils.unshift(data3);
         assertArrayEquals(new Integer[]{1}, data3);
 
-        Integer[] data4 = new Integer[]{};
         try {
-            ArrayUtils.unshift(data4);
+            ArrayUtils.unshift(new Integer[]{});
+            fail("exception expected");
+        } catch(EmptyCollectionException cause) {
+            assertTrue(true);
+        }
+        try {
+            ArrayUtils.unshift((Integer[])null);
+            fail("exception expected");
+        } catch(EmptyCollectionException cause) {
+            assertTrue(true);
+        }
+        try {
+            ArrayUtils.unshift(new int[]{});
+            fail("exception expected");
+        } catch(EmptyCollectionException cause) {
+            assertTrue(true);
+        }
+        try {
+            ArrayUtils.unshift((int[])null);
             fail("exception expected");
         } catch(EmptyCollectionException cause) {
             assertTrue(true);
         }
     }
-    
+
     @Test
     public void testGetDefault() {
         Integer numbers[] = new Integer[]{1,2,3,4,5,6};
@@ -357,7 +395,7 @@ public class ArrayUtilsTest {
 
         assertArrayEquals(new Long[]{10L, 20L, 30L, 40L, 50L}, objectArray);
         assertArrayEquals(new long[]{10L, 20L, 30L, 40L, 50L}, primtvArray);
-        
+
         try {
             String[] result = ArrayUtils.toArray(String[].class, longList);
             fail("cast exception expected");
@@ -382,31 +420,31 @@ public class ArrayUtilsTest {
         assertArrayEquals(new Integer[]{34, 79, 33, 31, 51, 32, 63, 38}, bValues);
         assertArrayEquals(new int[]    { 1,  3,  6, 19, 21, 33, 42, 44}, bIndex);
     }
-    
+
     @Test
     public void testConcat() {
         assertArrayEquals(
-            new String[]{"a","b","c","d","e"}, 
+            new String[]{"a","b","c","d","e"},
             ArrayUtils.concat(new String[]{"a","b"}, new String[]{"c","d","e"})
         );
         assertArrayEquals(
-            new String[]{"a","b","c"}, 
+            new String[]{"a","b","c"},
             ArrayUtils.concat(new String[]{"a","b"}, new String[]{"c"})
         );
         assertArrayEquals(
-            new String[]{"a","b","c"}, 
+            new String[]{"a","b","c"},
             ArrayUtils.concat(new String[]{"a"}, new String[]{"b", "c"})
         );
         assertArrayEquals(
-            new String[]{"b","c"}, 
+            new String[]{"b","c"},
             ArrayUtils.concat(new String[]{}, new String[]{"b", "c"})
         );
         assertArrayEquals(
-            new String[]{"b","c"}, 
+            new String[]{"b","c"},
             ArrayUtils.concat(new String[]{"b", "c"}, new String[]{})
         );
     }
-    
+
     @SuppressWarnings("PMD")
     @Test
     public void testConcatPrimitive() {
@@ -422,8 +460,8 @@ public class ArrayUtilsTest {
         new ConcatTest<byte[]>(30, 20, byte[].class){ @Override void run() {
             result = ArrayUtils.concat(first, second);
         }};
-        
-        
+
+
         new ConcatTest<short[]>(0, 10, short[].class){ @Override void run() {
             result = ArrayUtils.concat(first, second);
         }};
@@ -436,8 +474,8 @@ public class ArrayUtilsTest {
         new ConcatTest<short[]>(30, 20, short[].class){ @Override void run() {
             result = ArrayUtils.concat(first, second);
         }};
-        
-        
+
+
         new ConcatTest<int[]>(0, 10, int[].class){ @Override void run() {
             result = ArrayUtils.concat(first, second);
         }};
@@ -450,8 +488,8 @@ public class ArrayUtilsTest {
         new ConcatTest<int[]>(30, 20, int[].class){ @Override void run() {
             result = ArrayUtils.concat(first, second);
         }};
-        
-        
+
+
         new ConcatTest<long[]>(0, 10, long[].class){ @Override void run() {
             result = ArrayUtils.concat(first, second);
         }};
@@ -464,8 +502,8 @@ public class ArrayUtilsTest {
         new ConcatTest<long[]>(30, 20, long[].class){ @Override void run() {
             result = ArrayUtils.concat(first, second);
         }};
-        
-        
+
+
         new ConcatTest<float[]>(0, 10, float[].class){ @Override void run() {
             result = ArrayUtils.concat(first, second);
         }};
@@ -478,8 +516,8 @@ public class ArrayUtilsTest {
         new ConcatTest<float[]>(30, 20, float[].class){ @Override void run() {
             result = ArrayUtils.concat(first, second);
         }};
-        
-        
+
+
         new ConcatTest<double[]>(0, 10, double[].class){ @Override void run() {
             result = ArrayUtils.concat(first, second);
         }};
@@ -492,8 +530,8 @@ public class ArrayUtilsTest {
         new ConcatTest<double[]>(30, 20, double[].class){ @Override void run() {
             result = ArrayUtils.concat(first, second);
         }};
-        
-        
+
+
         new ConcatTest<char[]>(0, 10, char[].class){ @Override void run() {
             result = ArrayUtils.concat(first, second);
         }};
@@ -506,8 +544,8 @@ public class ArrayUtilsTest {
         new ConcatTest<char[]>(30, 20, char[].class){ @Override void run() {
             result = ArrayUtils.concat(first, second);
         }};
-        
-        
+
+
         new ConcatTest<boolean[]>(0, 10, boolean[].class){ @Override void run() {
             result = ArrayUtils.concat(first, second);
         }};
@@ -521,9 +559,9 @@ public class ArrayUtilsTest {
             result = ArrayUtils.concat(first, second);
         }};
     }
-    
+
     private static abstract class ConcatTest<P> {
-        
+
         final P first;
         final P second;
         P result;
@@ -534,22 +572,22 @@ public class ArrayUtilsTest {
         public ConcatTest(int ifirst, int isecond, Class<P> type) {
             List lfirst = Randomizer.list(type.getComponentType(), ifirst);
             List lsecond = Randomizer.list(type.getComponentType(), isecond);
-            
+
             first = (P)ArrayUtils.toArray(type, lfirst);
             second = (P)ArrayUtils.toArray(type, lsecond);
-            
+
             run();
             if(result == null) {
                 fail("unknown result of primivite test: "+type.getSimpleName());
             }
-            
+
             Object[] ofirst = (Object[])ArrayUtils.toArray(ClassInspector.box(type), lfirst);
             Object[] osecond = (Object[])ArrayUtils.toArray(ClassInspector.box(type), lsecond);
             Object[] oresult = ArrayUtils.concat(ofirst, osecond);
-            
+
             List<Object> expected = ArrayUtils.wrap(oresult);
-            List<Object> current = ArrayUtils.wrap(result);                  
-            
+            List<Object> current = ArrayUtils.wrap(result);
+
             if( expected.size() != current.size() ) {
                 LoggerUtils.dump("expected = %s\ncurrent  = %s\n", expected, current);
                 fail("primivite test: "+type.getSimpleName());
@@ -570,46 +608,112 @@ public class ArrayUtilsTest {
         assertNull( ArrayUtils.first(new Integer[]{}) );
         assertEquals( (Integer)7, ArrayUtils.first(new Integer[]{7}) );
         assertEquals( (Integer)7, ArrayUtils.first(new Integer[]{7,2,3}) );
-        
+
         assertNull( ArrayUtils.first(null, String.class) );
         assertNull( ArrayUtils.first(new Number[]{}, Float.class) );
         assertNull( ArrayUtils.first( new Number[]{7.0f}, Double.class) );
         assertEquals( 7.0, ArrayUtils.first( new Number[]{1, 2.0f, 7.0, 8.0f, 9.0 }, Double.class), 0.1 );
         assertEquals( 7.0, ArrayUtils.first( new Number[]{1, 2.0f, 7.0, 8.0f, 9.0 }, Double.class), 0.1 );
     }
-    
+
     @Test
     public void testLast() {
         assertNull( ArrayUtils.last(null) );
         assertNull( ArrayUtils.last(new Integer[]{}) );
         assertEquals( (Integer)7, ArrayUtils.last(new Integer[]{7}) );
         assertEquals( (Integer)3, ArrayUtils.last(new Integer[]{7,2,3}) );
-        
+
         assertNull( ArrayUtils.last(null, String.class) );
         assertNull( ArrayUtils.last(new Number[]{}, Float.class) );
         assertNull( ArrayUtils.last( new Number[]{7.0f}, Double.class) );
         assertEquals( 9.0, ArrayUtils.last( new Number[]{1, 2.0f, 7.0, 8.0f, 9.0 }, Double.class), 0.1 );
         assertEquals( 9.0, ArrayUtils.last( new Number[]{1, 2.0f, 7.0, 8.0f, 9.0 }, Double.class), 0.1 );
     }
-    
+
+    @Test
+    public void testIndexOf() {
+        Integer[] list = new Integer[]{1, 5, 2, 3, 4, 5, 6};
+
+        assertEquals(-1, ArrayUtils.indexOf(null, 77));
+        assertEquals(-1, ArrayUtils.indexOf(new Integer[]{}, 77));
+        assertEquals(-1, ArrayUtils.indexOf(null, null));
+        assertEquals(-1, ArrayUtils.indexOf(new Integer[]{}, null));
+
+        assertEquals(-1, ArrayUtils.indexOf(list, 77));
+        assertEquals(1, ArrayUtils.indexOf(list, 5));
+        assertEquals(6, ArrayUtils.indexOf(list, 6));
+
+        // jakim cudem to się kompiluje?
+        // bo do Number jest typ sprowadzany, a Integer porównując sprawdza instanceof Integer,
+        // więc w efekcie nie znajdzie naszej klasy Short
+        assertEquals(-1, ArrayUtils.indexOf(list, (short)6 ));
+    }
+
+    @Test
+    public void testContains() {
+        Integer[] list = new Integer[]{1, 5, 2, 3, 4, 5, 6};
+
+        assertFalse(ArrayUtils.contains(null, 77));
+        assertFalse(ArrayUtils.contains(new Integer[]{}, 77));
+        assertFalse(ArrayUtils.contains(null, null));
+        assertFalse(ArrayUtils.contains(new Integer[]{}, null));
+
+        assertFalse(ArrayUtils.contains(list, 77));
+        assertTrue(ArrayUtils.contains(list, 5));
+        assertTrue(ArrayUtils.contains(list, 6));
+
+        // jakim cudem to się kompiluje?
+        // bo do Number jest typ sprowadzany, a Integer porównując sprawdza instanceof Integer,
+        // więc w efekcie nie znajdzie naszej klasy Short
+        assertFalse(ArrayUtils.contains(list, (short)6 ));
+
+    }
+
+    @Test
+    public void testApply() {
+        Function<String, Integer> functor = new Function<String, Integer>(){
+            @Override
+            public String apply(Integer source) {
+                return source.toString();
+            }
+        };
+        CoFunction<Object, Integer> cofunctor = new CoFunction<Object, Integer>(){
+            @Override
+            public Integer inverse(Object source) {
+                return Integer.valueOf(source.toString());
+            }
+        };
+        Integer[] input1 = new Integer[]{1,2,3,4,5};
+        Object[] output1 = ArrayUtils.apply(input1, functor);
+        Object[] output2 = ArrayUtils.inverse(output1, cofunctor);
+
+        assertNull( ArrayUtils.apply(null, functor) );
+        assertNull( ArrayUtils.inverse(null, cofunctor) );
+
+        assertArrayEquals(new String[]{"1","2","3","4","5"}, output1);
+        assertArrayEquals(input1, output2);
+    }
+
     @Test
     public void testSize() {
-        assertEquals(0, ArrayUtils.size(null) );
+        assertEquals(0, ArrayUtils.size((int[])null) );
+        assertEquals(0, ArrayUtils.size((Object)null) );
+
         assertEquals(0, ArrayUtils.size(new int[0]) );
         assertEquals(0, ArrayUtils.size(new Integer[0]) );
-        
+
         assertEquals(4, ArrayUtils.size(new int[4]) );
         assertEquals(4, ArrayUtils.size(new Integer[4]) );
-        
+
         try {
             ArrayUtils.size("");
         } catch(IllegalArgumentException cause) {
             assertTrue( cause.getMessage().contains("type is not an array"));
         }
-        
-        
+
+
     }
-    
+
     @Test
     public void testIsEmpty() {
         assertTrue( ArrayUtils.isEmpty(null) );
@@ -617,81 +721,81 @@ public class ArrayUtilsTest {
         assertTrue( ArrayUtils.isEmpty(new Integer[0]) );
         assertFalse( ArrayUtils.isEmpty(new int[3]) );
         assertFalse( ArrayUtils.isEmpty(new Integer[3]) );
-        
+
         try {
             ArrayUtils.isEmpty("");
         } catch(IllegalArgumentException cause) {
             assertTrue( cause.getMessage().contains("type is not an array"));
         }
     }
-    
+
     @Test
     public void testClip() {
         int[] int0 = new int[]{};
         int[] int3 = new int[]{1, 2, 3};
         int[] int5 = new int[]{1, 2, 3, 4, 5};
-        
+
         Integer[] integer0 = new Integer[]{};
         Integer[] integer3 = new Integer[]{1, 2, 3};
         Integer[] integer5 = new Integer[]{1, 2, 3, 4, 5};
-        
+
         assertArrayEquals(int0, ArrayUtils.clip(int0, 0));
         assertArrayEquals(int0, ArrayUtils.clip(int3, 0));
         assertArrayEquals(int0, ArrayUtils.clip(int0, 2));
-        
+
         assertArrayEquals(int3, ArrayUtils.clip(int3, 3));
         assertArrayEquals(int3, ArrayUtils.clip(int3, 5));
         assertArrayEquals(int3, ArrayUtils.clip(int5, 3));
-        
+
         assertArrayEquals(integer0, ArrayUtils.clip(integer0, 0));
         assertArrayEquals(integer0, ArrayUtils.clip(integer3, 0));
         assertArrayEquals(integer0, ArrayUtils.clip(integer0, 2));
-        
+
         assertArrayEquals(integer3, ArrayUtils.clip(integer3, 3));
         assertArrayEquals(integer3, ArrayUtils.clip(integer3, 5));
         assertArrayEquals(integer3, ArrayUtils.clip(integer5, 3));
 
     }
-    
+
     @Test
     public void testMake() {
         int[] int4zeroA = ArrayUtils.make(int.class, 4);
         int[] int4fiveA = ArrayUtils.make(int.class, 4, 5);
         Integer[] int4A = ArrayUtils.make(Integer.class, 4, 9);
-        
+
         int[] int4zeroB = ArrayUtils.make(int[].class, 4);
         int[] int4fiveB = ArrayUtils.make(int[].class, 4, 5);
         Integer[] int4B = ArrayUtils.make(Integer[].class, 4, 9);
-        
+
         int[] int4seven = ArrayUtils.make(4, 7);
         String[] text5a = ArrayUtils.make(5, "a");
-        
+
         Number[] object1 = ArrayUtils.makeT(Integer.class, 4);
-        
+
         Integer[] object2 = ArrayUtils.makeT(Integer.class, 4, 0);
         Number[]  object3 = ArrayUtils.makeT(Float.class, 4, 0f);
-        
+
         Number[] object4 = ArrayUtils.makeT(4, 7L);
         Number[] object5 = ArrayUtils.makeT(4, 7f);
-        
+
         assertArrayEquals(new int[]{0,0,0,0}, int4zeroA);
         assertArrayEquals(new int[]{5,5,5,5}, int4fiveA);
         assertArrayEquals(new Integer[]{9,9,9,9}, int4A);
-        
+
         assertArrayEquals(new int[]{0,0,0,0}, int4zeroB);
         assertArrayEquals(new int[]{5,5,5,5}, int4fiveB);
         assertArrayEquals(new Integer[]{9,9,9,9}, int4B);
-        
+
         assertArrayEquals(new int[]{7,7,7,7}, int4seven);
-        
+
         assertArrayEquals(new String[]{"a","a","a","a","a"}, text5a);
-        
+
         assertArrayEquals(new Integer[]{null,null,null,null}, object1);
         assertArrayEquals(new Integer[]{0,0,0,0}, object2);
         assertArrayEquals(new Float[]{0f,0f,0f,0f}, object3);
         assertArrayEquals(new Long[]{7L,7L,7L,7L}, object4);
         assertArrayEquals(new Float[]{7f,7f,7f,7f}, object5);
-        
+
         try {
             int[] int4cast = ArrayUtils.make(int[].class, 4, (short)5);
             fail("exception expected");
@@ -715,19 +819,19 @@ public class ArrayUtilsTest {
         } catch(AssertionError cause) {
             assertTrue(true); // dla trybu z włączonymi asercjami
         } catch(NullPointerException cause) {
-            assertTrue(true); // dla trybu release 
+            assertTrue(true); // dla trybu release
         }
         try {
             Integer[] object1cast = ArrayUtils.makeT(int.class, 7);
         } catch(ClassCastException cause) {
             assertTrue(cause.getMessage().matches(".*\\[I.*Object.*"));
-        } 
+        }
     }
-    
+
     @Test
     public void testPair() {
         Set<ArrayUtils.Pair<String>> pairs = new HashSet<ArrayUtils.Pair<String>>();
-        ArrayUtils.Pair<String> 
+        ArrayUtils.Pair<String>
             p1  = new ArrayUtils.Pair<String>("33",17),
             p2  = new ArrayUtils.Pair<String>("44",17),
             p3  = new ArrayUtils.Pair<String>("55",17),
@@ -735,13 +839,13 @@ public class ArrayUtilsTest {
         pairs.add(p1);
         pairs.add(p2);
         pairs.add(p3);
-        
+
         assertTrue(pairs.contains(p1));
         assertTrue(pairs.contains(p2));
         assertTrue(pairs.contains(p1c));
-        
+
         Set<ArrayUtils.IntPair> ipairs = new HashSet<ArrayUtils.IntPair>();
-        ArrayUtils.IntPair 
+        ArrayUtils.IntPair
             ip1  = new ArrayUtils.IntPair(33, 17),
             ip2  = new ArrayUtils.IntPair(44, 17),
             ip3  = new ArrayUtils.IntPair(55, 17),
@@ -749,16 +853,16 @@ public class ArrayUtilsTest {
         ipairs.add(ip1);
         ipairs.add(ip2);
         ipairs.add(ip3);
-        
+
         assertTrue(ipairs.contains(ip1));
         assertTrue(ipairs.contains(ip2));
         assertTrue(ipairs.contains(ip1c));
     }
-    
+
     @Test
     public void testIterator() {
         Integer[] array = new Integer[]{1,2,3,4,5,6};
-        
+
         ListIterator<Integer> it1 = ArrayUtils.iterator(array);
         int sum1 = 0;
         while(it1.hasNext()) {
@@ -767,7 +871,7 @@ public class ArrayUtilsTest {
         }
         assertEquals(21, sum1);
         assertArrayEquals(new Integer[]{1,3,6,10,15,21}, array);
-        
+
         ListIterator<Integer> it2 = ArrayUtils.iterator(array, 3, 1);
         int sum2 = 0;
         while(it2.hasNext()) {
@@ -776,7 +880,7 @@ public class ArrayUtilsTest {
         }
         assertEquals(19, sum2);
         assertArrayEquals(new Integer[]{1,-3,-9,-19,15,21}, array);
-        
+
         try {
              ListIterator<Integer> it3 = ArrayUtils.iterator(array, 3, 1);
              it3.next();
@@ -785,7 +889,7 @@ public class ArrayUtilsTest {
         } catch(UnsupportedOperationException cause) {
             assertTrue( cause.getMessage().contains("array"));
         }
-        
+
         try {
              ListIterator<Integer> it3 = ArrayUtils.iterator(array, 3, 1);
              it3.next();
@@ -796,4 +900,25 @@ public class ArrayUtilsTest {
         }
     }
 
+    @Test
+    public void testArrayCopy() {
+        int[] input1 = new int[]{1,2,3,4,5};
+        Integer[] input2 = new Integer[]{1,2,3,4,5};
+
+        assertArrayEquals(input1, ArrayUtils.arraycopy(input1));
+        assertArrayEquals(input2, ArrayUtils.arraycopy(input2));
+
+        Integer[] target2a = new Integer[3];
+        Integer[] target2b = new Integer[5];
+        Integer[] output2a = ArrayUtils.arraycopy(target2a, input2);
+        Integer[] output2b = ArrayUtils.arraycopy(target2b, input2);
+
+        assertNotSame(target2a, output2a);
+        assertArrayEquals(input2, output2a);
+
+        assertSame(target2b, output2b);
+        assertArrayEquals(input2, output2b);
+
+    }
+
 }