/** * Creates a Tree of the given elements. * * @param <T> Component type of the List. * @param values Zero or more values. * @return A Tree containing the given values. * @throws NullPointerException if {@code values} is null */ @SuppressWarnings("varargs") @SafeVarargs static <T> Tree<T> of(T... values) { Objects.requireNonNull(values, "values is null"); List<T> list = List.of(values); return list.isEmpty() ? Empty.instance() : new Node<>(list.head(), list.tail().map(Tree::of)); }
/** * Creates a Tree of the given elements. * * <p>If the given iterable is a tree, it is returned as result. if the iteration order of the * elements is stable. * * @param <T> Component type of the List. * @param iterable An Iterable of elements. * @return A list containing the given elements in the same order. * @throws NullPointerException if {@code elements} is null */ @SuppressWarnings("unchecked") static <T> Tree<T> ofAll(Iterable<? extends T> iterable) { Objects.requireNonNull(iterable, "iterable is null"); if (iterable instanceof Tree) { return (Tree<T>) iterable; } else { final List<T> list = List.ofAll(iterable); return list.isEmpty() ? Empty.instance() : new Node<>(list.head(), list.tail().map(Tree::of)); } }
@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) Unzip.apply3((Node<T>) this, unzipper); } }
@Override default Tree<T> replace(T currentElement, T newElement) { if (isEmpty()) { return Empty.instance(); } else { return Replace.apply((Node<T>) this, currentElement, newElement); } }
@Override default <U> Tree<Tuple2<T, U>> zip(Iterable<U> that) { Objects.requireNonNull(that, "that is null"); if (isEmpty()) { return Empty.instance(); } else { return Zip.apply((Node<T>) this, that.iterator()); } }
@SuppressWarnings("unchecked") static <T, U> Tree<Tuple2<T, U>> apply(Node<T> node, java.util.Iterator<U> that) { if (!that.hasNext()) { return Empty.instance(); } else { final Tuple2<T, U> value = Tuple.of(node.getValue(), that.next()); final List<Node<Tuple2<T, U>>> children = (List<Node<Tuple2<T, U>>>) (Object) node.getChildren().map(child -> Zip.apply(child, that)).filter(Tree::isDefined); return new Node<>(value, children); } }
/** * Returns the singleton empty tree. * * @param <T> Type of tree values. * @return The empty tree. */ static <T> Empty<T> empty() { return Empty.instance(); }
@Override default <U> Tree<U> map(Function<? super T, ? extends U> mapper) { Objects.requireNonNull(mapper, "mapper is null"); return isEmpty() ? Empty.instance() : TreeModule.Map.apply((Node<T>) this, mapper); }