/** * Extends (continues) this {@code Stream} with values provided by a {@code Supplier} * * @param nextSupplier a supplier which will provide values for extending a stream * @return new {@code Stream} composed from this stream extended with values provided by the supplier */ default Stream<T> extend(Supplier<? extends T> nextSupplier) { Objects.requireNonNull(nextSupplier, "nextSupplier is null"); return Stream.ofAll(appendAll(Stream.continually(nextSupplier))); }
/** * Extends (continues) this {@code Stream} with a constantly repeated value. * * @param next value with which the stream should be extended * @return new {@code Stream} composed from this stream extended with a Stream of provided value */ default Stream<T> extend(T next) { return Stream.ofAll(this.appendAll(Stream.continually(next))); }
@Override default Stream<T> prependAll(Iterable<? extends T> elements) { Objects.requireNonNull(elements, "elements is null"); if (isEmpty()) { if (elements instanceof Stream) { @SuppressWarnings("unchecked") final Stream<T> stream = (Stream<T>) elements; return stream; } else { return Stream.ofAll(elements); } } else { return Stream.<T> ofAll(elements).appendAll(this); } }
@Override default Stream<T> leftPadTo(int length, T element) { final int actualLength = length(); if (length <= actualLength) { return this; } else { return Stream.continually(element).take(length - actualLength).appendAll(this); } }
@Override default Stream<T> insertAll(int index, Iterable<? extends T> elements) { Objects.requireNonNull(elements, "elements is null"); if (index < 0) { throw new IndexOutOfBoundsException("insertAll(" + index + ", elements)"); } else if (index == 0) { return isEmpty() ? Stream.ofAll(elements) : Stream.<T> ofAll(elements).appendAll(this); } else if (isEmpty()) { throw new IndexOutOfBoundsException("insertAll(" + index + ", elements) on Nil"); } else { return cons(head(), () -> tail().insertAll(index - 1, elements)); } }
static <T> Stream<Node<T>> traversePreOrder(Node<T> node) { return node.getChildren().foldLeft(Stream.of(node), (acc, child) -> acc.appendAll(traversePreOrder(child))); }
static <T> Stream<Node<T>> traversePostOrder(Node<T> node) { return node .getChildren() .foldLeft(Stream.<Node<T>> empty(), (acc, child) -> acc.appendAll(traversePostOrder(child))) .append(node); }
@Override default Stream<T> update(int index, T element) { if (isEmpty()) { throw new IndexOutOfBoundsException("update(" + index + ", e) on Nil"); } if (index < 0) { throw new IndexOutOfBoundsException("update(" + index + ", e)"); } Stream<T> preceding = Empty.instance(); Stream<T> tail = this; for (int i = index; i > 0; i--, tail = tail.tail()) { if (tail.isEmpty()) { throw new IndexOutOfBoundsException("update at " + index); } preceding = preceding.prepend(tail.head()); } if (tail.isEmpty()) { throw new IndexOutOfBoundsException("update at " + index); } // skip the current head element because it is replaced return preceding.reverse().appendAll(tail.tail().prepend(element)); }
static <T> Stream<Node<T>> traverseInOrder(Node<T> node) { if (node.isLeaf()) { return Stream.of(node); } else { final io.vavr.collection.List<Node<T>> children = node.getChildren(); return children .tail() .foldLeft(Stream.<Node<T>> empty(), (acc, child) -> acc.appendAll(traverseInOrder(child))) .prepend(node) .prependAll(traverseInOrder(children.head())); } }
@Override default Stream<Stream<T>> permutations() { if (isEmpty()) { return Empty.instance(); } else { final Stream<T> tail = tail(); if (tail.isEmpty()) { return Stream.of(this); } else { final Stream<Stream<T>> zero = Empty.instance(); return distinct().foldLeft(zero, (xs, x) -> { final Function<Stream<T>, Stream<T>> prepend = l -> l.prepend(x); return xs.appendAll(remove(x).permutations().map(prepend)); }); } } }
/** * Extends (continues) this {@code Stream} with values provided by a {@code Supplier} * * @param nextSupplier a supplier which will provide values for extending a stream * @return new {@code Stream} composed from this stream extended with values provided by the supplier */ default Stream<T> extend(Supplier<? extends T> nextSupplier) { Objects.requireNonNull(nextSupplier, "nextSupplier is null"); return Stream.ofAll(appendAll(Stream.continually(nextSupplier))); }
/** * Extends (continues) this {@code Stream} with a constantly repeated value. * * @param next value with which the stream should be extended * @return new {@code Stream} composed from this stream extended with a Stream of provided value */ default Stream<T> extend(T next) { return Stream.ofAll(this.appendAll(Stream.continually(next))); }
@Override default Stream<T> prependAll(Iterable<? extends T> elements) { Objects.requireNonNull(elements, "elements is null"); if (isEmpty()) { if (elements instanceof Stream) { @SuppressWarnings("unchecked") final Stream<T> stream = (Stream<T>) elements; return stream; } else { return Stream.ofAll(elements); } } else { return Stream.<T> ofAll(elements).appendAll(this); } }
@Override default Stream<T> leftPadTo(int length, T element) { final int actualLength = length(); if (length <= actualLength) { return this; } else { return Stream.continually(element).take(length - actualLength).appendAll(this); } }
@Override default Stream<T> insertAll(int index, Iterable<? extends T> elements) { Objects.requireNonNull(elements, "elements is null"); if (index < 0) { throw new IndexOutOfBoundsException("insertAll(" + index + ", elements)"); } else if (index == 0) { return isEmpty() ? Stream.ofAll(elements) : Stream.<T> ofAll(elements).appendAll(this); } else if (isEmpty()) { throw new IndexOutOfBoundsException("insertAll(" + index + ", elements) on Nil"); } else { return cons(head(), () -> tail().insertAll(index - 1, elements)); } }
static <T> Stream<Node<T>> traversePreOrder(Node<T> node) { return node.getChildren().foldLeft(Stream.of(node), (acc, child) -> acc.appendAll(traversePreOrder(child))); }
static <T> Stream<Node<T>> traversePostOrder(Node<T> node) { return node .getChildren() .foldLeft(Stream.<Node<T>> empty(), (acc, child) -> acc.appendAll(traversePostOrder(child))) .append(node); }
static <T> Stream<Node<T>> traverseInOrder(Node<T> node) { if (node.isLeaf()) { return Stream.of(node); } else { final io.vavr.collection.List<Node<T>> children = node.getChildren(); return children .tail() .foldLeft(Stream.<Node<T>> empty(), (acc, child) -> acc.appendAll(traverseInOrder(child))) .prepend(node) .prependAll(traverseInOrder(children.head())); } }