/** * Checks if this Tree is a branch. A Tree is a branch if it is a Node which has children. * Because the empty tree is not a Node, it is not a branch by definition. * * @return true if this tree is a branch, false otherwise. */ default boolean isBranch() { return !(isEmpty() || isLeaf()); }
@Override default Tree<T> peek(Consumer<? super T> action) { Objects.requireNonNull(action, "action is null"); if (!isEmpty()) { action.accept(head()); } return this; }
@Override default <U, R> Tree<R> zipWith(Iterable<? extends U> that, BiFunction<? super T, ? super U, ? extends R> mapper) { Objects.requireNonNull(that, "that is null"); Objects.requireNonNull(mapper, "mapper is null"); if (isEmpty()) { return Empty.instance(); } else { return TreeModule.zip((Node<T>) this, that.iterator(), mapper); } }
@Override default <U> Tree<U> map(Function<? super T, ? extends U> mapper) { Objects.requireNonNull(mapper, "mapper is null"); return isEmpty() ? Empty.instance() : TreeModule.map((Node<T>) this, mapper); }
@Override default Seq<T> tail() { if (isEmpty()) { throw new UnsupportedOperationException("tail of empty tree"); } else { return values().tail(); } }
@Override default T head() { if (isEmpty()) { throw new NoSuchElementException("head of empty tree"); } else { return iterator().next(); } }
@Override default <U> U foldRight(U zero, BiFunction<? super T, ? super U, ? extends U> f) { Objects.requireNonNull(f, "f is null"); if (isEmpty()) { return zero; } else { return iterator().foldRight(zero, f); } }
@Override default <U> Tree<U> flatMap(Function<? super T, ? extends Iterable<? extends U>> mapper) { Objects.requireNonNull(mapper, "mapper is null"); return isEmpty() ? Empty.instance() : TreeModule.flatMap((Node<T>) this, mapper); }
@Override default Seq<T> init() { if (isEmpty()) { throw new UnsupportedOperationException("init of empty tree"); } else { return values().init(); } }
@Override default Tree<T> replace(T currentElement, T newElement) { if (isEmpty()) { return Empty.instance(); } else { return TreeModule.replace((Node<T>) this, currentElement, newElement); } }
@Override default <U> Seq<T> distinctBy(Function<? super T, ? extends U> keyExtractor) { Objects.requireNonNull(keyExtractor, "keyExtractor is null"); if (isEmpty()) { return Stream.empty(); } else { return values().distinctBy(keyExtractor); } }
@Override default Seq<T> dropWhile(Predicate<? super T> predicate) { Objects.requireNonNull(predicate, "predicate is null"); if (isEmpty()) { return Stream.empty(); } else { return values().dropWhile(predicate); } }
@Override default Seq<T> reject(Predicate<? super T> predicate) { Objects.requireNonNull(predicate, "predicate is null"); if (isEmpty()) { return Stream.empty(); } else { return values().reject(predicate); } }
@Override default Seq<T> distinctBy(Comparator<? super T> comparator) { Objects.requireNonNull(comparator, "comparator is null"); if (isEmpty()) { return Stream.empty(); } else { return values().distinctBy(comparator); } }
@Override default Seq<T> filter(Predicate<? super T> predicate) { Objects.requireNonNull(predicate, "predicate is null"); if (isEmpty()) { return Stream.empty(); } else { return values().filter(predicate); } }
@Override default Seq<T> take(int n) { if (isEmpty()) { return Stream.empty(); } else { return values().take(n); } }
@Override default Seq<T> takeRight(int n) { if (isEmpty()) { return Stream.empty(); } else { return values().takeRight(n); } }
@SuppressWarnings("unchecked") @Override default Tuple2<Seq<T>, Seq<T>> span(Predicate<? super T> predicate) { Objects.requireNonNull(predicate, "predicate is null"); if (isEmpty()) { return Tuple.of(Stream.empty(), Stream.empty()); } else { return (Tuple2<Seq<T>, Seq<T>>) values().span(predicate); } }
@SuppressWarnings("unchecked") @Override default <T1, T2, T3> Tuple3<Tree<T1>, Tree<T2>, Tree<T3>> unzip3( Function<? super T, Tuple3<? extends T1, ? extends T2, ? extends T3>> unzipper) { Objects.requireNonNull(unzipper, "unzipper is null"); if (isEmpty()) { return Tuple.of(Empty.instance(), Empty.instance(), Empty.instance()); } else { return (Tuple3<Tree<T1>, Tree<T2>, Tree<T3>>) (Object) TreeModule.unzip3((Node<T>) this, unzipper); } }
/** * Counts the number of branches of this tree. The empty tree and a leaf have no branches. * * @return The number of branches of this tree. */ default int branchCount() { if (isEmpty() || isLeaf()) { return 0; } else { return getChildren().foldLeft(1, (count, child) -> count + child.branchCount()); } }