|
@@ -19,6 +19,7 @@ import net.ranides.assira.generic.Wrapper;
|
|
|
import net.ranides.assira.trace.ExceptionUtils;
|
|
import net.ranides.assira.trace.ExceptionUtils;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
|
|
+ * Static methods working with Iterator interface.
|
|
|
*
|
|
*
|
|
|
* @author Ranides Atterwim {@literal <ranides@gmail.com>}
|
|
* @author Ranides Atterwim {@literal <ranides@gmail.com>}
|
|
|
*/
|
|
*/
|
|
@@ -27,14 +28,30 @@ public final class IteratorUtils {
|
|
|
private IteratorUtils() {
|
|
private IteratorUtils() {
|
|
|
/* utility class */
|
|
/* utility class */
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns first element for iterator, or none if iterator is empty.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return optional
|
|
|
|
|
+ */
|
|
|
public static <T> Optional<T> first(Iterator<? extends T> iterator) {
|
|
public static <T> Optional<T> first(Iterator<? extends T> iterator) {
|
|
|
if(iterator.hasNext()) {
|
|
if(iterator.hasNext()) {
|
|
|
return Optional.of(iterator.next());
|
|
return Optional.of(iterator.next());
|
|
|
}
|
|
}
|
|
|
return Optional.empty();
|
|
return Optional.empty();
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns first element for iterator which satisfies predicate.
|
|
|
|
|
+ * Returns none if iterator is empty or no element was accepted by predicate.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param predicate predicate
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return optional
|
|
|
|
|
+ */
|
|
|
public static <T> Optional<T> first(Iterator<? extends T> iterator, Predicate<? super T> predicate) {
|
|
public static <T> Optional<T> first(Iterator<? extends T> iterator, Predicate<? super T> predicate) {
|
|
|
while(iterator.hasNext()) {
|
|
while(iterator.hasNext()) {
|
|
|
T v = iterator.next();
|
|
T v = iterator.next();
|
|
@@ -44,7 +61,16 @@ public final class IteratorUtils {
|
|
|
}
|
|
}
|
|
|
return Optional.empty();
|
|
return Optional.empty();
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns last element for iterator, or none if iterator is empty.
|
|
|
|
|
+ * It must traverse whole collection.
|
|
|
|
|
+ * If you can, lets try ListUtils.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return optional
|
|
|
|
|
+ */
|
|
|
public static <T> Optional<T> last(Iterator<? extends T> iterator) {
|
|
public static <T> Optional<T> last(Iterator<? extends T> iterator) {
|
|
|
if(!iterator.hasNext()) {
|
|
if(!iterator.hasNext()) {
|
|
|
return Optional.empty();
|
|
return Optional.empty();
|
|
@@ -56,6 +82,16 @@ public final class IteratorUtils {
|
|
|
return Optional.of(result);
|
|
return Optional.of(result);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns element at specified position or none if iterator contains less elements.
|
|
|
|
|
+ * It must traverse through all previous elements.
|
|
|
|
|
+ * If you can, lets try ListUtils.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param index index
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return optional
|
|
|
|
|
+ */
|
|
|
public static <T> Optional<T> at(Iterator<? extends T> iterator, int index) {
|
|
public static <T> Optional<T> at(Iterator<? extends T> iterator, int index) {
|
|
|
for(int i=0; i<index; i++) {
|
|
for(int i=0; i<index; i++) {
|
|
|
if(!iterator.hasNext()) {
|
|
if(!iterator.hasNext()) {
|
|
@@ -65,12 +101,23 @@ public final class IteratorUtils {
|
|
|
}
|
|
}
|
|
|
return iterator.hasNext() ? Optional.of(iterator.next()) : Optional.empty();
|
|
return iterator.hasNext() ? Optional.of(iterator.next()) : Optional.empty();
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns last element for iterator which satisfies predicate.
|
|
|
|
|
+ * Returns none if iterator is empty or no element was accepted by predicate.
|
|
|
|
|
+ * It must traverse whole collection.
|
|
|
|
|
+ * If you can, lets try ListUtils.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param predicate predicate
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return optional
|
|
|
|
|
+ */
|
|
|
public static <T> Optional<T> last(Iterator<? extends T> iterator, Predicate<? super T> predicate) {
|
|
public static <T> Optional<T> last(Iterator<? extends T> iterator, Predicate<? super T> predicate) {
|
|
|
boolean found = false;
|
|
boolean found = false;
|
|
|
T result = null;
|
|
T result = null;
|
|
|
- while(iterator.hasNext()) {
|
|
|
|
|
- T v = iterator.next();
|
|
|
|
|
|
|
+ while(iterator.hasNext()) {
|
|
|
|
|
+ T v = iterator.next();
|
|
|
if(predicate.test(v)) {
|
|
if(predicate.test(v)) {
|
|
|
result = v;
|
|
result = v;
|
|
|
found = true;
|
|
found = true;
|
|
@@ -81,7 +128,14 @@ public final class IteratorUtils {
|
|
|
}
|
|
}
|
|
|
return Optional.of(result);
|
|
return Optional.of(result);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Counts number of elements for specified iterator.
|
|
|
|
|
+ * It must iterate through all elements, if you can, check collection size directly.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @return int
|
|
|
|
|
+ */
|
|
|
public static int size(Iterator<?> iterator) {
|
|
public static int size(Iterator<?> iterator) {
|
|
|
if(iterator==null) {
|
|
if(iterator==null) {
|
|
|
return 0;
|
|
return 0;
|
|
@@ -94,112 +148,319 @@ public final class IteratorUtils {
|
|
|
return c;
|
|
return c;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns filtered view of provided IntIterator.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param predicate predicate
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return iterator view
|
|
|
|
|
+ */
|
|
|
public static <T> Iterator<T> filter(Iterator<? extends T> iterator, Predicate<? super T> predicate) {
|
|
public static <T> Iterator<T> filter(Iterator<? extends T> iterator, Predicate<? super T> predicate) {
|
|
|
return new FilterIterator<>(iterator, predicate, false);
|
|
return new FilterIterator<>(iterator, predicate, false);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- public static <T> ListIterator<T> filter(ListIterator<? extends T> iterator, Predicate<? super T> predicate) {
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns filtered read-only view of provided IntIterator.
|
|
|
|
|
+ * Returned iterator supports backward iteration, but it does not allow modifications.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param predicate predicate
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return iterator view
|
|
|
|
|
+ */
|
|
|
|
|
+ public static <T> ListIterator<T> filter(ListIterator<? extends T> iterator, Predicate<? super T> predicate) {
|
|
|
return new FilterListIterator<>(iterator, predicate, false);
|
|
return new FilterListIterator<>(iterator, predicate, false);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns filtered view of provided IntIterator.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param predicate predicate
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return iterator view
|
|
|
|
|
+ */
|
|
|
public static <T> Iterator<T> filterEach(Iterator<? extends T> iterator, EachPredicate<? super T> predicate) {
|
|
public static <T> Iterator<T> filterEach(Iterator<? extends T> iterator, EachPredicate<? super T> predicate) {
|
|
|
return new FilterIterator<>(iterator, predicate, false);
|
|
return new FilterIterator<>(iterator, predicate, false);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns filtered read-only view of provided IntIterator.
|
|
|
|
|
+ * Returned iterator supports backward iteration, but it does not allow modifications.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param predicate predicate
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return iterator view
|
|
|
|
|
+ */
|
|
|
public static <T> ListIterator<T> filterEach(ListIterator<? extends T> iterator, EachPredicate<? super T> predicate) {
|
|
public static <T> ListIterator<T> filterEach(ListIterator<? extends T> iterator, EachPredicate<? super T> predicate) {
|
|
|
return new FilterListIterator<>(iterator, predicate, false);
|
|
return new FilterListIterator<>(iterator, predicate, false);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns read-only view of provided Iterator.
|
|
|
|
|
+ * Limited iterator stops at first unmatched element.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param predicate predicate
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return iterator view
|
|
|
|
|
+ */
|
|
|
public static <T> Iterator<T> limit(Iterator<? extends T> iterator, Predicate<? super T> predicate) {
|
|
public static <T> Iterator<T> limit(Iterator<? extends T> iterator, Predicate<? super T> predicate) {
|
|
|
return new FilterIterator<>(iterator, predicate, true);
|
|
return new FilterIterator<>(iterator, predicate, true);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- public static <T> ListIterator<T> limit(ListIterator<? extends T> iterator, Predicate<? super T> predicate) {
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns read-only view of provided Iterator.
|
|
|
|
|
+ * Limited iterator stops at first unmatched element.
|
|
|
|
|
+ * Returned iterator supports backward iteration, but it does not allow modifications.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param predicate predicate
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return iterator view
|
|
|
|
|
+ */
|
|
|
|
|
+ public static <T> ListIterator<T> limit(ListIterator<? extends T> iterator, Predicate<? super T> predicate) {
|
|
|
return new FilterListIterator<>(iterator, predicate, true);
|
|
return new FilterListIterator<>(iterator, predicate, true);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns read-only view of provided Iterator.
|
|
|
|
|
+ * Limited iterator returns no more than "limit" elements.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param limit limit
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return iterator view
|
|
|
|
|
+ */
|
|
|
public static <T> Iterator<T> limit(Iterator<T> iterator, int limit) {
|
|
public static <T> Iterator<T> limit(Iterator<T> iterator, int limit) {
|
|
|
return new LimitIterator<>(iterator, limit);
|
|
return new LimitIterator<>(iterator, limit);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns read-only view of provided Iterator.
|
|
|
|
|
+ * Limited iterator returns no more than "limit" elements.
|
|
|
|
|
+ * Returned iterator supports backward iteration, but it does not allow modifications.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param limit limit
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return iterator view
|
|
|
|
|
+ */
|
|
|
public static <T> ListIterator<T> limit(ListIterator<T> iterator, int limit) {
|
|
public static <T> ListIterator<T> limit(ListIterator<T> iterator, int limit) {
|
|
|
return new LimitListIterator<>(iterator, limit);
|
|
return new LimitListIterator<>(iterator, limit);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns read-only view of provided Iterator.
|
|
|
|
|
+ * Limited iterator returns elements at most from specified range.
|
|
|
|
|
+ * It means: it skips first "begin" elements and then stops after reaching "end".
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param begin begin
|
|
|
|
|
+ * @param end end
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return iterator view
|
|
|
|
|
+ */
|
|
|
public static <T> Iterator<T> limit(Iterator<T> iterator, int begin, int end) {
|
|
public static <T> Iterator<T> limit(Iterator<T> iterator, int begin, int end) {
|
|
|
next(iterator, begin);
|
|
next(iterator, begin);
|
|
|
return new LimitIterator<>(iterator, end-begin);
|
|
return new LimitIterator<>(iterator, end-begin);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns read-only view of provided Iterator.
|
|
|
|
|
+ * Limited iterator returns elements at most from specified range.
|
|
|
|
|
+ * It means: it skips first "begin" elements and then stops after reaching "end".
|
|
|
|
|
+ * Returned iterator supports backward iteration, but it does not allow modifications.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param begin begin
|
|
|
|
|
+ * @param end end
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return iterator view
|
|
|
|
|
+ */
|
|
|
public static <T> ListIterator<T> limit(ListIterator<T> iterator, int begin, int end) {
|
|
public static <T> ListIterator<T> limit(ListIterator<T> iterator, int begin, int end) {
|
|
|
next(iterator, begin);
|
|
next(iterator, begin);
|
|
|
return new LimitListIterator<>(iterator, end-begin);
|
|
return new LimitListIterator<>(iterator, end-begin);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns read-only view of iterator which maps every element using provided function.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param function function
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @param <S> S
|
|
|
|
|
+ * @return iterator view
|
|
|
|
|
+ */
|
|
|
public static <S,T> Iterator<T> map(Iterator<? extends S> iterator, EachFunction<? super S,? extends T> function) {
|
|
public static <S,T> Iterator<T> map(Iterator<? extends S> iterator, EachFunction<? super S,? extends T> function) {
|
|
|
return new EachAdapter<>(iterator, function);
|
|
return new EachAdapter<>(iterator, function);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- public static <S,T> Iterator<T> map(Iterator<? extends S> iterator, Function<? super S,? extends T> function) {
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns read-only view of iterator which maps every element using provided function.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param function function
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @param <S> S
|
|
|
|
|
+ * @return iterator view
|
|
|
|
|
+ */
|
|
|
|
|
+ public static <S,T> Iterator<T> map(Iterator<? extends S> iterator, Function<? super S,? extends T> function) {
|
|
|
return new Adapter<>(iterator, function);
|
|
return new Adapter<>(iterator, function);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns read-only view of iterator which maps every element using provided function.
|
|
|
|
|
+ * Returned iterator supports backward iteration, but it does not allow modifications.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param function function
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @param <S> S
|
|
|
|
|
+ * @return iterator view
|
|
|
|
|
+ */
|
|
|
public static <S,T> ListIterator<T> map(ListIterator<? extends S> iterator, EachFunction<S,T> function) {
|
|
public static <S,T> ListIterator<T> map(ListIterator<? extends S> iterator, EachFunction<S,T> function) {
|
|
|
return new EachListAdapter<>(iterator, function);
|
|
return new EachListAdapter<>(iterator, function);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns read-only view of iterator which maps every element using provided function.
|
|
|
|
|
+ * Returned iterator supports backward iteration, but it does not allow modifications.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param function function
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @param <S> S
|
|
|
|
|
+ * @return iterator view
|
|
|
|
|
+ */
|
|
|
public static <S,T> ListIterator<T> map(ListIterator<? extends S> iterator, Function<? super S,? extends T> function) {
|
|
public static <S,T> ListIterator<T> map(ListIterator<? extends S> iterator, Function<? super S,? extends T> function) {
|
|
|
return new ListAdapter<>(iterator, function);
|
|
return new ListAdapter<>(iterator, function);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns view which lazily expands all nested Iterators and merges into one iterator.
|
|
|
|
|
+ * Flat iterators move forward only as much as necessary (which means one element at time).
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return iterator view
|
|
|
|
|
+ */
|
|
|
public static <T> Iterator<T> flat(Iterator<? extends Iterator<? extends T>> iterator) {
|
|
public static <T> Iterator<T> flat(Iterator<? extends Iterator<? extends T>> iterator) {
|
|
|
return new FlatIterator<>(iterator);
|
|
return new FlatIterator<>(iterator);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns view which lazily expands all provided Iterators and merges into one iterator.
|
|
|
|
|
+ * Flat iterators move forward only as much as necessary (which means one element at time).
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterators iterators
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return iterator
|
|
|
|
|
+ * @see #flat
|
|
|
|
|
+ */
|
|
|
@SafeVarargs
|
|
@SafeVarargs
|
|
|
public static <T> Iterator<T> concat(Iterator<? extends T>... iterators) {
|
|
public static <T> Iterator<T> concat(Iterator<? extends T>... iterators) {
|
|
|
return flat(Arrays.asList(iterators).iterator());
|
|
return flat(Arrays.asList(iterators).iterator());
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- public static <T> Stream<T> stream(Iterator<? extends T> iterator) {
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Creates new sequential Stream from provided iterator.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return stream
|
|
|
|
|
+ */
|
|
|
|
|
+ public static <T> Stream<T> stream(Iterator<? extends T> iterator) {
|
|
|
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false);
|
|
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Inserts all elements returned by iterator into provided collection.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param target target
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @param <C> C
|
|
|
|
|
+ * @return target
|
|
|
|
|
+ */
|
|
|
public static <T, C extends Collection<? super T>> C collect(Iterator<? extends T> iterator, C target) {
|
|
public static <T, C extends Collection<? super T>> C collect(Iterator<? extends T> iterator, C target) {
|
|
|
while(iterator.hasNext()) {
|
|
while(iterator.hasNext()) {
|
|
|
target.add(iterator.next());
|
|
target.add(iterator.next());
|
|
|
}
|
|
}
|
|
|
return target;
|
|
return target;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
- * Nie da się stworzyć odwróconego ListIterator ponieważ indeksowanie się położy, operacja
|
|
|
|
|
- * #add będzie wstawiać na nieprawidłowej pozycji. Operacja #set w zasadzie ma szanse działać.
|
|
|
|
|
- * Ale to za mało, żeby zwracać interfejs, którego kontraktu w 90% nie dotrzymujemy.
|
|
|
|
|
|
|
+ * Creates mutable iterator which runs in reversed order.
|
|
|
|
|
+ * It supports removing elements.
|
|
|
|
|
+ *
|
|
|
|
|
+ * Please note, that input iterator must be correctly rewinded before use.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
* @param <T>
|
|
* @param <T>
|
|
|
- * @param iterator
|
|
|
|
|
- * @return
|
|
|
|
|
|
|
+ * @return iterator view
|
|
|
*/
|
|
*/
|
|
|
public static <T> Iterator<T> reverse(ListIterator<? extends T> iterator) {
|
|
public static <T> Iterator<T> reverse(ListIterator<? extends T> iterator) {
|
|
|
return new ReverseIterator<>(iterator);
|
|
return new ReverseIterator<>(iterator);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * It creates read-only iterator which offers limited backward iteration.
|
|
|
|
|
+ * It buffers last "max" results and allows to read back them.
|
|
|
|
|
+ *
|
|
|
|
|
+ * It does not support any modifications, including "remove".
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param max max
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return iterator
|
|
|
|
|
+ */
|
|
|
public static <T> ListIterator<T> buffered(Iterator<? extends T> iterator, int max) {
|
|
public static <T> ListIterator<T> buffered(Iterator<? extends T> iterator, int max) {
|
|
|
return new BufferedIterator<>(iterator, max);
|
|
return new BufferedIterator<>(iterator, max);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- public static <T> int next(Iterator<? extends T> iterator, int count) {
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Tries to skip "count" elements.
|
|
|
|
|
+ * Returns number of successfully skipped elements.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param count count
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return int
|
|
|
|
|
+ */
|
|
|
|
|
+ public static <T> int next(Iterator<? extends T> iterator, int count) {
|
|
|
int i=0;
|
|
int i=0;
|
|
|
for(; i<count && iterator.hasNext(); i++) {
|
|
for(; i<count && iterator.hasNext(); i++) {
|
|
|
iterator.next();
|
|
iterator.next();
|
|
|
}
|
|
}
|
|
|
return i;
|
|
return i;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Checks if provided iterators contain equal elements.
|
|
|
|
|
+ * Order of elements is important.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param a a
|
|
|
|
|
+ * @param b b
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return bool
|
|
|
|
|
+ */
|
|
|
public static <T> boolean equals(Iterator<? extends T> a, Iterator<? extends T> b) {
|
|
public static <T> boolean equals(Iterator<? extends T> a, Iterator<? extends T> b) {
|
|
|
return equals(a, b, CompareUtils::equals);
|
|
return equals(a, b, CompareUtils::equals);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Checks if provided iterators contain equal elements using provided comparison function.
|
|
|
|
|
+ * Order of elements is important.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param a a
|
|
|
|
|
+ * @param b b
|
|
|
|
|
+ * @param predicate predicate
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return bool
|
|
|
|
|
+ */
|
|
|
public static <T> boolean equals(Iterator<? extends T> a, Iterator<? extends T> b, BiPredicate<? super T,? super T> predicate) {
|
|
public static <T> boolean equals(Iterator<? extends T> a, Iterator<? extends T> b, BiPredicate<? super T,? super T> predicate) {
|
|
|
while(a.hasNext() && b.hasNext()) {
|
|
while(a.hasNext() && b.hasNext()) {
|
|
|
if( !predicate.test(a.next(), b.next())) {
|
|
if( !predicate.test(a.next(), b.next())) {
|
|
@@ -208,11 +469,32 @@ public final class IteratorUtils {
|
|
|
}
|
|
}
|
|
|
return !a.hasNext() && !b.hasNext();
|
|
return !a.hasNext() && !b.hasNext();
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Checks if provided iterators contain equal elements.
|
|
|
|
|
+ * Order of elements is important.
|
|
|
|
|
+ * It is three-value version, which returns +1, 0, -1
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param a a
|
|
|
|
|
+ * @param b b
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return int
|
|
|
|
|
+ */
|
|
|
public static <T> int compare(Iterator<? extends T> a, Iterator<? extends T> b) {
|
|
public static <T> int compare(Iterator<? extends T> a, Iterator<? extends T> b) {
|
|
|
return compare(a, b, CompareUtils.comparator());
|
|
return compare(a, b, CompareUtils.comparator());
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Checks if provided iterators contain equal elements using provided comparison function.
|
|
|
|
|
+ * Order of elements is important.
|
|
|
|
|
+ * It is three-value version, which returns +1, 0, -1
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param a a
|
|
|
|
|
+ * @param b b
|
|
|
|
|
+ * @param cmp cmp
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return int
|
|
|
|
|
+ */
|
|
|
public static <T> int compare(Iterator<? extends T> a, Iterator<? extends T> b, Comparator<? super T> cmp) {
|
|
public static <T> int compare(Iterator<? extends T> a, Iterator<? extends T> b, Comparator<? super T> cmp) {
|
|
|
while(a.hasNext() && b.hasNext()) {
|
|
while(a.hasNext() && b.hasNext()) {
|
|
|
int icmp = cmp.compare(a.next(), b.next());
|
|
int icmp = cmp.compare(a.next(), b.next());
|
|
@@ -222,7 +504,14 @@ public final class IteratorUtils {
|
|
|
}
|
|
}
|
|
|
return a.hasNext() ? +1 : b.hasNext() ? -1 : 0;
|
|
return a.hasNext() ? +1 : b.hasNext() ? -1 : 0;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Iterates through all values and removes every element which is matched by predicate.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param predicate predicate
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ */
|
|
|
public static <T> void remove(Iterator<? extends T> iterator, Predicate<? super T> predicate) {
|
|
public static <T> void remove(Iterator<? extends T> iterator, Predicate<? super T> predicate) {
|
|
|
while(iterator.hasNext()) {
|
|
while(iterator.hasNext()) {
|
|
|
T v = iterator.next();
|
|
T v = iterator.next();
|
|
@@ -232,6 +521,17 @@ public final class IteratorUtils {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Creates new infinite iterator which returns values generated by provided supplier.
|
|
|
|
|
+ * Rethrows all unchecked exceptions from generator.
|
|
|
|
|
+ * Wraps by RuntimeException all checked exceptions from generator.
|
|
|
|
|
+ *
|
|
|
|
|
+ * Probably supplier must be statefull.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param generator generator
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return iterator
|
|
|
|
|
+ */
|
|
|
public static <T> Iterator<T> infinite(CheckedSupplier<T, ?> generator) {
|
|
public static <T> Iterator<T> infinite(CheckedSupplier<T, ?> generator) {
|
|
|
return new Iterator<T>() {
|
|
return new Iterator<T>() {
|
|
|
@Override
|
|
@Override
|
|
@@ -252,6 +552,19 @@ public final class IteratorUtils {
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Creates new finite iterator which returns values generated by provided supplier.
|
|
|
|
|
+ * Iterator stops when generator returns "Optional.empty"
|
|
|
|
|
+ *
|
|
|
|
|
+ * Rethrows all unchecked exceptions from generator.
|
|
|
|
|
+ * Wraps by RuntimeException all checked exceptions from generator.
|
|
|
|
|
+ *
|
|
|
|
|
+ * Probably supplier must be statefull.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param generator generator
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return iterator
|
|
|
|
|
+ */
|
|
|
public static <T> Iterator<T> finite(CheckedSupplier<Optional<T>, ?> generator) {
|
|
public static <T> Iterator<T> finite(CheckedSupplier<Optional<T>, ?> generator) {
|
|
|
return new Iterator<T>() {
|
|
return new Iterator<T>() {
|
|
|
|
|
|
|
@@ -275,26 +588,79 @@ public final class IteratorUtils {
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Creates safe iterator which will never throw any exception except NoSuchElementException.
|
|
|
|
|
+ * All exceptions are silently ignored.
|
|
|
|
|
+ * Behaviour of iterator methods in such case:
|
|
|
|
|
+ * - "hasNext" returns false
|
|
|
|
|
+ * - "next" throws NoSuchElementException
|
|
|
|
|
+ * - "remove" does nothing
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return iterator
|
|
|
|
|
+ */
|
|
|
public static <T> Iterator<T> safe(Iterator<T> iterator) {
|
|
public static <T> Iterator<T> safe(Iterator<T> iterator) {
|
|
|
return safe(iterator, Exception.class, e -> {});
|
|
return safe(iterator, Exception.class, e -> {});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Creates safe iterator which will never throw exception of specified "type".
|
|
|
|
|
+ * Exceptions of "type" are silently ignored.
|
|
|
|
|
+ * Behaviour of iterator methods in such case:
|
|
|
|
|
+ * - "hasNext" returns false
|
|
|
|
|
+ * - "next" throws NoSuchElementException
|
|
|
|
|
+ * - "remove" does nothing
|
|
|
|
|
+ *
|
|
|
|
|
+ * Please note, that other exceptions still will be propagated without change.
|
|
|
|
|
+ *
|
|
|
|
|
+ * Please note, that NoSuchElementException will be thrown as usuall.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param type exception to ignore
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @param <E> E
|
|
|
|
|
+ * @return iterator
|
|
|
|
|
+ */
|
|
|
public static <T, E extends Throwable> Iterator<T> safe(Iterator<T> iterator, Class<E> type) {
|
|
public static <T, E extends Throwable> Iterator<T> safe(Iterator<T> iterator, Class<E> type) {
|
|
|
return safe(iterator, type, e -> {});
|
|
return safe(iterator, type, e -> {});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Creates safe iterator which will never throw exception of specified "type".
|
|
|
|
|
+ * Exceptions of "type" are sent to handler.
|
|
|
|
|
+ *
|
|
|
|
|
+ * Behaviour of iterator methods in such case:
|
|
|
|
|
+ * - "hasNext" returns false
|
|
|
|
|
+ * - "next" throws NoSuchElementException
|
|
|
|
|
+ * - "remove" does nothing
|
|
|
|
|
+ *
|
|
|
|
|
+ * Please note, that other exceptions still will be propagated without change.
|
|
|
|
|
+ *
|
|
|
|
|
+ * Please note, that NoSuchElementException will be thrown as usuall.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param iterator iterator
|
|
|
|
|
+ * @param type exception to ignore
|
|
|
|
|
+ * @param handler handler
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @param <E> E
|
|
|
|
|
+ * @return iterator
|
|
|
|
|
+ */
|
|
|
public static <T, E extends Throwable> Iterator<T> safe(Iterator<T> iterator, Class<E> type, Consumer<E> handler) {
|
|
public static <T, E extends Throwable> Iterator<T> safe(Iterator<T> iterator, Class<E> type, Consumer<E> handler) {
|
|
|
return new SafeIterator<>(iterator, type, handler);
|
|
return new SafeIterator<>(iterator, type, handler);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Creates iterator with single provided value
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param value value
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ * @return iterator
|
|
|
|
|
+ */
|
|
|
public static <T> Iterator<T> singletonIterator(T value) {
|
|
public static <T> Iterator<T> singletonIterator(T value) {
|
|
|
return new SingleIterator<>(value);
|
|
return new SingleIterator<>(value);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public static <T> Spliterator<T> singletonSpliterator(T value) {
|
|
|
|
|
- return new SingleSpliterator<>(value);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
private static final class Adapter<S, T> implements Iterator<T> {
|
|
private static final class Adapter<S, T> implements Iterator<T> {
|
|
|
|
|
|
|
|
protected final Iterator<S> delegate;
|
|
protected final Iterator<S> delegate;
|
|
@@ -737,6 +1103,12 @@ public final class IteratorUtils {
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * We implement only Iterator, because it is impossible to create correct reversed ListIterator.
|
|
|
|
|
+ * Indexing will be invalid and #add operation will insert into wrong place.
|
|
|
|
|
+ * Eventually we can implement #set operation, but it is not enough to return interface which is 90% not implemented.
|
|
|
|
|
+ * @param <T>
|
|
|
|
|
+ */
|
|
|
private static class ReverseIterator<T> implements Iterator<T> {
|
|
private static class ReverseIterator<T> implements Iterator<T> {
|
|
|
|
|
|
|
|
private final ListIterator<? extends T> iterator;
|
|
private final ListIterator<? extends T> iterator;
|
|
@@ -915,51 +1287,6 @@ public final class IteratorUtils {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private static class SingleSpliterator<T> implements Spliterator<T> {
|
|
|
|
|
-
|
|
|
|
|
- private final T value;
|
|
|
|
|
-
|
|
|
|
|
- long est = 1;
|
|
|
|
|
-
|
|
|
|
|
- public SingleSpliterator(T value) {
|
|
|
|
|
- this.value = value;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- public Spliterator<T> trySplit() {
|
|
|
|
|
- return null;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- public boolean tryAdvance(Consumer<? super T> consumer) {
|
|
|
|
|
- Objects.requireNonNull(consumer);
|
|
|
|
|
- if (est > 0) {
|
|
|
|
|
- est--;
|
|
|
|
|
- consumer.accept(value);
|
|
|
|
|
- return true;
|
|
|
|
|
- }
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- public void forEachRemaining(Consumer<? super T> consumer) {
|
|
|
|
|
- tryAdvance(consumer);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- public long estimateSize() {
|
|
|
|
|
- return est;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- public int characteristics() {
|
|
|
|
|
- int out = (value != null) ? Spliterator.NONNULL : 0;
|
|
|
|
|
-
|
|
|
|
|
- return out | Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.IMMUTABLE |
|
|
|
|
|
- Spliterator.DISTINCT | Spliterator.ORDERED;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
private static class SafeIterator<T, E extends Throwable> implements Iterator<T> {
|
|
private static class SafeIterator<T, E extends Throwable> implements Iterator<T> {
|
|
|
|
|
|
|
|
private final Iterator<? extends T> iterator;
|
|
private final Iterator<? extends T> iterator;
|