|
|
@@ -352,6 +352,22 @@ public final class IteratorUtils {
|
|
|
return new FlatIterator<>(iterator);
|
|
|
}
|
|
|
|
|
|
+ public static <T> Iterator<T> flat(Iterator<? extends T> iterator, Function<? super T, Iterator<T>> splitter) {
|
|
|
+ return new FlatMapIterator<>(FlatMode.SHALLOW, iterator, item -> true, splitter);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static <T> Iterator<T> flatIf(Iterator<? extends T> iterator, Predicate<? super T> split, Function<? super T, Iterator<T>> splitter) {
|
|
|
+ return new FlatMapIterator<>(FlatMode.SHALLOW, iterator, split, splitter);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static <T> Iterator<T> deepFlatIf(Iterator<? extends T> iterator, Predicate<? super T> split, Function<? super T, Iterator<T>> splitter) {
|
|
|
+ return new FlatMapIterator<>(FlatMode.DEEP, iterator, split, splitter);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static <T> Iterator<T> treeFlatIf(Iterator<? extends T> iterator, Predicate<? super T> split, Function<? super T, Iterator<T>> splitter) {
|
|
|
+ return new FlatMapIterator<>(FlatMode.TREE, iterator, split, splitter);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 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).
|
|
|
@@ -1247,7 +1263,7 @@ public final class IteratorUtils {
|
|
|
}
|
|
|
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
private static final class FlatIterator<T> implements Iterator<T> {
|
|
|
|
|
|
private final Iterator<? extends Iterator<? extends T>> li;
|
|
|
@@ -1287,6 +1303,55 @@ public final class IteratorUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ private enum FlatMode {
|
|
|
+ SHALLOW,
|
|
|
+ DEEP,
|
|
|
+ TREE
|
|
|
+ }
|
|
|
+
|
|
|
+ private static class FlatMapIterator<T> extends ForwardIterator<T> {
|
|
|
+
|
|
|
+ private final Deque<Iterator<? extends T>> stack = new ArrayDeque<>(1);
|
|
|
+
|
|
|
+ private final FlatMode mode;
|
|
|
+ private final Predicate<? super T> split;
|
|
|
+ private final Function<? super T, Iterator<T>> splitter;
|
|
|
+
|
|
|
+ public FlatMapIterator(FlatMode mode, Iterator<? extends T> iterator, Predicate<? super T> split, Function<? super T, Iterator<T>> splitter) {
|
|
|
+ this.mode = mode;
|
|
|
+ this.split = split;
|
|
|
+ this.splitter = splitter;
|
|
|
+ this.stack.push(iterator);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected boolean next(Consumer<? super T> action) {
|
|
|
+ if(stack.isEmpty()) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!stack.peek().hasNext()) {
|
|
|
+ stack.pop();
|
|
|
+ return next(action);
|
|
|
+ }
|
|
|
+
|
|
|
+ T item = stack.peek().next();
|
|
|
+ if((stack.size() == 1 || mode != FlatMode.SHALLOW) && split.test(item)) {
|
|
|
+ stack.push(splitter.apply(item));
|
|
|
+ if(mode == FlatMode.TREE) {
|
|
|
+ action.accept(item);
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ return next(action);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ action.accept(item);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
private static class SingleIterator<T> implements Iterator<T> {
|
|
|
|
|
|
private final T value;
|