/** * Creates a Queue consisting of a front List and a rear List. * <p> * For a {@code Queue(front, rear)} the following invariant holds: {@code Queue is empty <=> front is empty}. * In other words: If the Queue is not empty, the front List contains at least one element. * * @param front A List of front elements, in correct order. * @param rear A List of rear elements, in reverse order. */ private Queue(io.vavr.collection.List<T> front, io.vavr.collection.List<T> rear) { final boolean frontIsEmpty = front.isEmpty(); this.front = frontIsEmpty ? rear.reverse() : front; this.rear = frontIsEmpty ? front : rear; }
@Override default <U> List<U> map(Function<? super T, ? extends U> mapper) { Objects.requireNonNull(mapper, "mapper is null"); List<U> list = empty(); for (T t : this) { list = list.prepend(mapper.apply(t)); } return list.reverse(); }
@Override default <U> List<U> flatMap(Function<? super T, ? extends Iterable<? extends U>> mapper) { Objects.requireNonNull(mapper, "mapper is null"); List<U> list = empty(); for (T t : this) { for (U u : mapper.apply(t)) { list = list.prepend(u); } } return list.reverse(); }
/** * Creates a List that contains the elements of the given {@link java.util.stream.Stream}. * * @param javaStream A {@link java.util.stream.Stream} * @param <T> Component type of the Stream. * @return A List containing the given elements in the same order. */ static <T> List<T> ofAll(java.util.stream.Stream<? extends T> javaStream) { Objects.requireNonNull(javaStream, "javaStream is null"); final java.util.Iterator<? extends T> iterator = javaStream.iterator(); List<T> list = List.empty(); while (iterator.hasNext()) { list = list.prepend(iterator.next()); } return list.reverse(); }
@Override default Tuple2<List<T>, List<T>> partition(Predicate<? super T> predicate) { Objects.requireNonNull(predicate, "predicate is null"); List<T> left = empty(), right = empty(); for (T t : this) { if (predicate.test(t)) { left = left.prepend(t); } else { right = right.prepend(t); } } return Tuple.of(left.reverse(), right.reverse()); }
@Override default <T1, T2> Tuple2<List<T1>, List<T2>> unzip( Function<? super T, Tuple2<? extends T1, ? extends T2>> unzipper) { Objects.requireNonNull(unzipper, "unzipper is null"); List<T1> xs = Nil.instance(); List<T2> ys = Nil.instance(); for (T element : this) { final Tuple2<? extends T1, ? extends T2> t = unzipper.apply(element); xs = xs.prepend(t._1); ys = ys.prepend(t._2); } return Tuple.of(xs.reverse(), ys.reverse()); }
@Override default List<T> prependAll(Iterable<? extends T> elements) { Objects.requireNonNull(elements, "elements is null"); return isEmpty() ? ofAll(elements) : ofAll(elements).reverse().foldLeft(this, List::prepend); }
@Override public Queue<T> reverse() { return isEmpty() ? this : ofAll(toList().reverse()); }
@Override public io.vavr.collection.List<T> toList() { io.vavr.collection.List<T> results = io.vavr.collection.List.empty(); for (PriorityQueue<T> queue = this; !queue.isEmpty(); ) { final Tuple2<T, PriorityQueue<T>> dequeue = queue.dequeue(); results = results.prepend(dequeue._1); queue = dequeue._2; } return results.reverse(); }
@Override public int indexOf(T element, int from) { final int frontIndex = front.indexOf(element, from); if (frontIndex != -1) { return frontIndex; } else { // we need to reverse because we search the first occurrence final int rearIndex = rear.reverse().indexOf(element, from - front.length()); return (rearIndex == -1) ? -1 : rearIndex + front.length(); } }
@Override default List<T> takeWhile(Predicate<? super T> predicate) { Objects.requireNonNull(predicate, "predicate is null"); List<T> result = Nil.instance(); for (List<T> list = this; !list.isEmpty() && predicate.test(list.head()); list = list.tail()) { result = result.prepend(list.head()); } return result.length() == length() ? this : result.reverse(); }
@Override default List<T> take(int n) { if (n <= 0) { return empty(); } if (n >= length()) { return this; } List<T> result = Nil.instance(); List<T> list = this; for (int i = 0; i < n; i++, list = list.tail()) { result = result.prepend(list.head()); } return result.reverse(); }
@Override default Tuple2<List<T>, List<T>> splitAt(Predicate<? super T> predicate) { if (isEmpty()) { return Tuple.of(empty(), empty()); } else { final Tuple2<List<T>, List<T>> t = SplitAt.splitByPredicateReversed(this, predicate); if (t._2.isEmpty()) { return Tuple.of(this, empty()); } else { return Tuple.of(t._1.reverse(), t._2); } } }
static <T> Stream<T> apply(io.vavr.collection.List<T> front, io.vavr.collection.List<T> rear, Stream<T> remaining) { if (remaining.isEmpty()) { return remaining; } else if (front.isEmpty()) { return apply(rear.reverse(), io.vavr.collection.List.empty(), remaining); } else { return Stream.cons(front.head(), () -> apply(front.tail(), rear.prepend(remaining.head()), remaining.tail())); } } }
@Override default Tuple2<List<T>, List<T>> splitAt(int n) { if (isEmpty()) { return Tuple.of(empty(), empty()); } else { List<T> init = Nil.instance(); List<T> tail = this; while (n > 0 && !tail.isEmpty()) { init = init.prepend(tail.head()); tail = tail.tail(); n--; } return Tuple.of(init.reverse(), tail); } }
@Override default Tuple2<List<T>, List<T>> splitAtInclusive(Predicate<? super T> predicate) { if (isEmpty()) { return Tuple.of(empty(), empty()); } else { final Tuple2<List<T>, List<T>> t = SplitAt.splitByPredicateReversed(this, predicate); if (t._2.isEmpty() || t._2.tail().isEmpty()) { return Tuple.of(this, empty()); } else { return Tuple.of(t._1.prepend(t._2.head()).reverse(), t._2.tail()); } } }