|
@@ -1,6 +1,5 @@
|
|
|
package net.ranides.assira.collection.query.derived;
|
|
package net.ranides.assira.collection.query.derived;
|
|
|
|
|
|
|
|
-import lombok.RequiredArgsConstructor;
|
|
|
|
|
import net.ranides.assira.collection.iterators.ForwardIterator;
|
|
import net.ranides.assira.collection.iterators.ForwardIterator;
|
|
|
import net.ranides.assira.collection.query.CQuery;
|
|
import net.ranides.assira.collection.query.CQuery;
|
|
|
import net.ranides.assira.collection.query.CQueryAbstract;
|
|
import net.ranides.assira.collection.query.CQueryAbstract;
|
|
@@ -12,7 +11,6 @@ import net.ranides.assira.functional.Predicates;
|
|
|
|
|
|
|
|
import java.util.Collections;
|
|
import java.util.Collections;
|
|
|
import java.util.Iterator;
|
|
import java.util.Iterator;
|
|
|
-import java.util.LinkedList;
|
|
|
|
|
import java.util.Stack;
|
|
import java.util.Stack;
|
|
|
import java.util.function.Consumer;
|
|
import java.util.function.Consumer;
|
|
|
import java.util.function.Function;
|
|
import java.util.function.Function;
|
|
@@ -20,15 +18,36 @@ import java.util.function.Predicate;
|
|
|
import java.util.function.Supplier;
|
|
import java.util.function.Supplier;
|
|
|
import java.util.stream.Stream;
|
|
import java.util.stream.Stream;
|
|
|
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * Stream implementation for tree traversal.
|
|
|
|
|
+ * It uses DFS algorithm.
|
|
|
|
|
+ *
|
|
|
|
|
+ * It can visit any tree, as long as it can provide 3 operations:
|
|
|
|
|
+ * - root node
|
|
|
|
|
+ * - list of children of provided node
|
|
|
|
|
+ * - predicate returning true, if node is terminal
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param <T> T
|
|
|
|
|
+ */
|
|
|
public class CQTreeDFS<T> extends CQueryAbstract<T> {
|
|
public class CQTreeDFS<T> extends CQueryAbstract<T> {
|
|
|
|
|
|
|
|
protected final Supplier<T> root;
|
|
protected final Supplier<T> root;
|
|
|
|
|
|
|
|
- protected final Function<T, CQuery<T>> splitter;
|
|
|
|
|
|
|
+ protected final Predicate<T> isTerm;
|
|
|
|
|
|
|
|
- public CQTreeDFS(Supplier<T> root, Function<T, CQuery<T>> splitter) {
|
|
|
|
|
|
|
+ protected final Function<T, CQuery<T>> children;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Creates new stream
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param root root
|
|
|
|
|
+ * @param isTerm isTerm
|
|
|
|
|
+ * @param children children
|
|
|
|
|
+ */
|
|
|
|
|
+ public CQTreeDFS(Supplier<T> root, Predicate<T> isTerm, Function<T, CQuery<T>> children) {
|
|
|
this.root = root;
|
|
this.root = root;
|
|
|
- this.splitter = splitter;
|
|
|
|
|
|
|
+ this.isTerm = isTerm;
|
|
|
|
|
+ this.children = children;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -46,6 +65,11 @@ public class CQTreeDFS<T> extends CQueryAbstract<T> {
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public boolean hasFastEach() {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
@Override
|
|
@Override
|
|
|
public Stream<T> stream() {
|
|
public Stream<T> stream() {
|
|
|
return BaseIterable.stream(this);
|
|
return BaseIterable.stream(this);
|
|
@@ -80,14 +104,19 @@ public class CQTreeDFS<T> extends CQueryAbstract<T> {
|
|
|
|
|
|
|
|
private void forEach0(T node, Consumer<? super T> consumer) {
|
|
private void forEach0(T node, Consumer<? super T> consumer) {
|
|
|
consumer.accept(node);
|
|
consumer.accept(node);
|
|
|
- splitter.apply(node).forEach(child -> forEach0(child, consumer));
|
|
|
|
|
|
|
+ if(!isTerm.test(node)) {
|
|
|
|
|
+ children.apply(node).forEach(child -> forEach0(child, consumer));
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private boolean whileEach0(T node, Predicate<? super T> consumer) {
|
|
private boolean whileEach0(T node, Predicate<? super T> consumer) {
|
|
|
if(!consumer.test(node)) {
|
|
if(!consumer.test(node)) {
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
- return splitter.apply(node).whileEach(child -> whileEach0(child, consumer));
|
|
|
|
|
|
|
+ if(!isTerm.test(node)) {
|
|
|
|
|
+ return children.apply(node).whileEach(child -> whileEach0(child, consumer));
|
|
|
|
|
+ }
|
|
|
|
|
+ return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -111,7 +140,9 @@ public class CQTreeDFS<T> extends CQueryAbstract<T> {
|
|
|
if (nodes.hasNext()) {
|
|
if (nodes.hasNext()) {
|
|
|
T node = nodes.next();
|
|
T node = nodes.next();
|
|
|
action.accept(node);
|
|
action.accept(node);
|
|
|
- window.push( splitter.apply(node).iterator() );
|
|
|
|
|
|
|
+ if(!isTerm.test(node)) {
|
|
|
|
|
+ window.push(children.apply(node).iterator());
|
|
|
|
|
+ }
|
|
|
return true;
|
|
return true;
|
|
|
} else {
|
|
} else {
|
|
|
window.pop();
|
|
window.pop();
|