ソースを参照

fix: IteratorUtils - accept NULLs
new: IteratorUtils#filter(ListIterator)

tests (96)

Ranides Atterwim 10 年 前
コミット
9d41b716d4

+ 236 - 123
assira/src/main/java/net/ranides/assira/collection/iterators/IteratorUtils.java

@@ -1,123 +1,236 @@
-/*
- * @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.NoSuchElementException;
-import java.util.function.Predicate;
-
-/**
- *
- * @author Ranides Atterwim <ranides@gmail.com>
- */
-public final class IteratorUtils {
-    
-    private IteratorUtils() {
-        /* utility class */
-    }
-    
-    public static <T> T first(Iterator<T> iterator) {
-        return iterator.hasNext() ? iterator.next() : null;
-    }
-    
-    public static <T> T first(Iterator<T> iterator, Predicate<T> predicate) {
-        while(iterator.hasNext()) {
-            T v = iterator.next();
-            if( predicate.test(v)) {
-                return v;
-            }
-        }
-        return null;
-    }
-    
-    public static <T> T last(Iterator<T> iterator) {
-        T result = null;
-        while(iterator.hasNext()) { 
-            result = iterator.next(); 
-        }
-        return result;
-    }
-    
-    public static <T> T last(Iterator<T> iterator, Predicate<T> predicate) {
-        T result = null;
-        while(iterator.hasNext()) { 
-            T v = iterator.next(); 
-            if(predicate.test(v)) {
-                result = v;
-            }
-        }
-        return result;
-    }
-    
-    public static int size(Iterator<?> iterator) {
-        int c = 0;
-        while(iterator.hasNext()) {
-            c++;
-            iterator.next();
-        }
-        return c;
-    }
-           
-    public static <T> Iterator<T> filter(Iterator<T> iterator, Predicate<T> predicate) {
-        return new FilterIterator<T>(iterator) {
-            @Override
-            public boolean accept(T source) {
-                return predicate.test(source);
-            }
-        };
-    }
-    
-    private static abstract class FilterIterator<T> implements Iterator<T> {
-
-        private final Iterator<? extends T> iterator;
-        private T next;
-        private boolean hasNext;
-
-        public abstract boolean accept(T value);
-
-        public FilterIterator(Iterator<? extends T> iterator) {
-            this.iterator = iterator;
-            nextMatch();
-        }
-
-        @Override
-        public boolean hasNext() {
-            return hasNext;
-        }
-
-        @Override
-        public T next() {
-            if (!hasNext) {
-                throw new NoSuchElementException();
-            }
-            return nextMatch();
-        }
-
-        private T nextMatch() {
-            T last = next;
-
-            while (iterator.hasNext()) {
-                T value = iterator.next();
-                if (accept(value)) {
-                    hasNext = true;
-                    next = value;
-                    return last;
-                }
-            }
-
-            hasNext = false;
-            return last;
-        }
-
-        @Override
-        public void remove() {
-            iterator.remove();
-        }
-
-    }
-    
-}
+/*
+ * @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.NoSuchElementException;
+import java.util.function.Predicate;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public final class IteratorUtils {
+    
+    private IteratorUtils() {
+        /* utility class */
+    }
+    
+    public static <T> T first(Iterator<T> iterator) {
+		if(iterator==null) {
+			return null;
+		}
+        return iterator.hasNext() ? iterator.next() : null;
+    }
+    
+    public static <T> T first(Iterator<T> iterator, Predicate<T> predicate) {
+		if(iterator==null) {
+			return null;
+		}
+        while(iterator.hasNext()) {
+            T v = iterator.next();
+            if( predicate.test(v)) {
+                return v;
+            }
+        }
+        return null;
+    }
+    
+    public static <T> T last(Iterator<T> iterator) {
+		if(iterator==null) {
+			return null;
+		}
+        T result = null;
+        while(iterator.hasNext()) { 
+            result = iterator.next(); 
+        }
+        return result;
+    }
+    
+    public static <T> T last(Iterator<T> iterator, Predicate<T> predicate) {
+		if(iterator==null) {
+			return null;
+		}
+        T result = null;
+        while(iterator.hasNext()) { 
+            T v = iterator.next(); 
+            if(predicate.test(v)) {
+                result = v;
+            }
+        }
+        return result;
+    }
+    
+    public static int size(Iterator<?> iterator) {
+		if(iterator==null) {
+			return 0;
+		}
+        int c = 0;
+        while(iterator.hasNext()) {
+            c++;
+            iterator.next();
+        }
+        return c;
+    }
+           
+    public static <T> Iterator<T> filter(Iterator<T> iterator, Predicate<T> predicate) {
+        return new FilterIterator<T>(iterator, predicate);
+    }
+	
+	public static <T> ListIterator<T> filter(ListIterator<T> iterator, Predicate<T> predicate) {
+        return new FilterListIterator<T>(iterator, predicate);
+    }
+    
+    private static class FilterIterator<T> implements Iterator<T> {
+
+        private final Iterator<T> iterator;
+        private final Predicate<T> predicate;
+        private T next;
+        private boolean hasNext;
+
+        public FilterIterator(Iterator<T> iterator, Predicate<T> predicate) {
+            this.iterator = iterator;
+			this.predicate = predicate;
+            nextMatch();
+        }
+
+        @Override
+        public boolean hasNext() {
+            return hasNext;
+        }
+
+        @Override
+        public T next() {
+            if (!hasNext) {
+                throw new NoSuchElementException();
+            }
+            return nextMatch();
+        }
+
+        private T nextMatch() {
+            T last = next;
+
+            while (iterator.hasNext()) {
+                T value = iterator.next();
+                if (predicate.test(value)) {
+                    hasNext = true;
+                    next = value;
+                    return last;
+                }
+            }
+
+            hasNext = false;
+            return last;
+        }
+
+        @Override
+        public void remove() {
+            iterator.remove();
+        }
+
+    }
+	
+	private static class FilterListIterator<T> implements ListIterator<T> {
+
+        private final ListIterator<T> iterator;
+        private final Predicate<T> predicate;
+		int index;
+		private T next;
+        private boolean hasNext;
+
+        public FilterListIterator(ListIterator<T> iterator, Predicate<T> predicate) {
+            this.iterator = iterator;
+			this.predicate = predicate;
+            nextMatch();
+        }
+		
+        @Override
+        public boolean hasNext() {
+            return hasNext;
+        }
+		
+		@Override
+        public boolean hasPrevious() {
+            return index>0;
+        }
+
+        @Override
+        public T next() {
+            if (!hasNext) {
+                throw new NoSuchElementException();
+            }
+			index++;
+            return nextMatch();
+        }
+		
+		@Override
+        public T previous() {
+            if (index<=0) {
+                throw new NoSuchElementException();
+            }
+			index--;
+            return prevMatch();
+        }
+
+        private T nextMatch() {
+            T ilast = next;
+			
+            while (iterator.hasNext()) {
+                T value = iterator.next();
+                if (predicate.test(value)) {
+                    hasNext = true;
+                    next = value;
+                    return ilast;
+                }
+            }
+
+            hasNext = false;
+            return ilast;
+        }
+		
+		private T prevMatch() {
+            while (iterator.hasPrevious()) {
+                T value = iterator.previous();
+                if (predicate.test(value)) {
+                    hasNext = true;
+                    next = value;
+                    return next;
+                }
+            }
+            throw new AssertionError("unreachable code");
+        }
+
+		
+		@Override
+		public int nextIndex() {
+			return index;
+		}
+		
+		@Override
+		public int previousIndex() {
+			return index-1;
+		}
+
+		@Override
+		public void remove() {
+			iterator.remove();
+		}
+
+		@Override
+		public void set(T e) {
+			iterator.set(e);
+		}
+
+		@Override
+		public void add(T e) {
+			iterator.add(e);
+		}
+
+    }
+    
+}

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

@@ -9,7 +9,6 @@ package net.ranides.assira.collection.iterators;
 import java.util.Arrays;
 import java.util.Iterator;
 import java.util.ListIterator;
-import net.ranides.assira.collection.lists.IntArrayList;
 import net.ranides.assira.collection.lists.NativeArray;
 import net.ranides.assira.collection.suite.IteratorTester;
 import org.junit.Test;

+ 106 - 0
assira/src/test/java/net/ranides/assira/collection/iterators/IteratorUtilsTest.java

@@ -0,0 +1,106 @@
+/*
+ * @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.List;
+import java.util.ListIterator;
+import net.ranides.assira.collection.suite.IteratorTester;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author msieron
+ */
+
+
+public class IteratorUtilsTest {
+	
+	@Test
+	public void testFirst() {
+		assertEquals((Integer)1, IteratorUtils.first(Arrays.asList(1,2,3,4).iterator()));
+		assertEquals((Integer)1, IteratorUtils.first(Arrays.asList(1,2).iterator()));
+		assertEquals((Integer)1, IteratorUtils.first(Arrays.asList(1).iterator()));
+		
+		assertNull(IteratorUtils.first(Arrays.asList().iterator()));
+		assertNull(IteratorUtils.first(null));
+	}
+	
+	@Test
+	public void testLast() {
+		assertEquals((Integer)4, IteratorUtils.last(Arrays.asList(1,2,3,4).iterator()));
+		assertEquals((Integer)4, IteratorUtils.last(Arrays.asList(3,4).iterator()));
+		assertEquals((Integer)4, IteratorUtils.last(Arrays.asList(4).iterator()));
+		
+		assertNull(IteratorUtils.last(Arrays.asList().iterator()));
+		assertNull(IteratorUtils.last(null));
+	}
+	
+	
+	@Test
+	public void testFirst_Filter() {
+		assertEquals((Integer)7, IteratorUtils.first(Arrays.asList(1,2,7,0,8,0,3).iterator(), (a)->a>5));
+		
+		assertNull(IteratorUtils.first(Arrays.asList(1,2,3).iterator(), (a)->a>5));
+		assertNull(IteratorUtils.first(Arrays.<Integer>asList().iterator(), (a)->a>5));
+		assertNull(IteratorUtils.first(null, (Integer a)->a>5));
+	}
+	
+	@Test
+	public void testLast_Filter() {
+		assertEquals((Integer)8, IteratorUtils.last(Arrays.asList(1,2,7,0,8,0,3).iterator(), (a)->a>5));
+		assertEquals((Integer)8, IteratorUtils.last(Arrays.asList(1,2,7,0,8).iterator(), (a)->a>5));
+		assertEquals((Integer)8, IteratorUtils.last(Arrays.asList(1,8).iterator(), (a)->a>5));
+		assertEquals((Integer)8, IteratorUtils.last(Arrays.asList(8,1).iterator(), (a)->a>5));
+		
+		assertNull(IteratorUtils.last(Arrays.asList(1,2,3).iterator(), (a)->a>5));
+		assertNull(IteratorUtils.last(Arrays.<Integer>asList().iterator(), (a)->a>5));
+		assertNull(IteratorUtils.last(null, (Integer a)->a>5));
+	}
+	
+	@Test
+	public void testSize() {
+		assertEquals(4, IteratorUtils.size(Arrays.asList(1,2,7,8).iterator()));
+		assertEquals(2, IteratorUtils.size(Arrays.asList(1,2).iterator()));
+		assertEquals(1, IteratorUtils.size(Arrays.asList(1).iterator()));
+		assertEquals(0, IteratorUtils.size(Arrays.asList().iterator()));
+		assertEquals(0, IteratorUtils.size(null));
+	}
+	
+	@Test
+	public void testFilterIterator() {
+		List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9);
+
+		IteratorTester.basicIterator(IteratorUtils.filter(list.iterator(), (v)->v%2==0), 0, new Integer[]{2,4,6,8});
+		IteratorTester.basicIterator(IteratorUtils.filter(list.iterator(), (v)->v%2==1), 0, new Integer[]{1,3,5,7,9});
+		IteratorTester.basicIterator(IteratorUtils.filter(list.iterator(), (v)->v>5), 0, new Integer[]{6,7,8,9});
+	}
+	
+	@Test
+	public void testFilterListIterator() {
+		List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9);
+
+		IteratorTester.listIterator(IteratorUtils.filter(list.listIterator(), (v)->v%2==0), 0, new Integer[]{2,4,6,8});
+		IteratorTester.listIterator(IteratorUtils.filter(list.listIterator(), (v)->v%2==1), 0, new Integer[]{1,3,5,7,9});
+		IteratorTester.listIterator(IteratorUtils.filter(list.listIterator(), (v)->v>5), 0, new Integer[]{6,7,8,9});
+		
+		
+		IteratorTester.listIterator(IteratorUtils.filter(forward(list.listIterator(),2), (v)->v%2==0), 0, new Integer[]{4,6,8});
+		IteratorTester.listIterator(IteratorUtils.filter(forward(list.listIterator(),2), (v)->v%2==1), 0, new Integer[]{3,5,7,9});
+		IteratorTester.listIterator(IteratorUtils.filter(forward(list.listIterator(),6), (v)->v>5), 0, new Integer[]{7,8,9});
+	}
+	
+	private <T> ListIterator<T> forward(ListIterator<T> iterator, int count) {
+		for(int i=0; i<count; i++) {
+			iterator.next();
+		}
+		return iterator;
+	}
+	
+}