@Override public <R> BankersQueue<R> flatMap(Function<? super T, ? extends ImmutableQueue<? extends R>> fn) { return check(new Cons(sizeFront,front.flatMap(fn.andThen(q->q.lazySeq())),sizeBack,back.flatMap(fn.andThen(q->q.lazySeq())))); }
@Override public <R> BankersQueue<R> flatMap(Function<? super T, ? extends ImmutableQueue<? extends R>> fn) { return check(new Cons(sizeFront,front.flatMap(fn.andThen(q->q.lazySeq())),sizeBack,back.flatMap(fn.andThen(q->q.lazySeq())))); }
@Override default BankersQueue<T> drop(long num) { if(num<=0) return this; if(num>=size()) return empty(); return this.foldBankersQueue(c -> { ImmutableList<T> newFront = c.front.drop(num); ImmutableList<T> newBack = c.back.dropRight((int) num - c.front.size()); if (newFront.size() > 0 || newBack.size() > 0) return new Cons<>(newFront, newBack); return empty(); }, nil -> nil); }
public static <T> BankersQueue<T> cons(T value){ return new Cons<>(1, LazySeq.cons(value,()-> LazySeq.empty()),0, LazySeq.empty()); } public static <T> BankersQueue<T> ofAll(ImmutableList<T> list){
@Override public <R> BankersQueue<R> map(Function<? super T, ? extends R> map) { return check(new Cons(sizeFront,front.map(map),sizeBack,back.map(map))); }
@Override public BankersQueue<T> enqueue(T value) { return check(new Cons(sizeFront, front, sizeBack + 1, back.prepend(value))); }
public BankersQueue<T> replace(T currentElement, T newElement) { ImmutableList<T> replaceF = front.replaceFirst(currentElement, newElement); ImmutableList<T> replaceB = back.replaceFirst(currentElement, newElement); return front==replaceF && back==replaceB ? this : new Cons<>(replaceF, replaceB); } public Option<T> get(int n) {
public static <T> BankersQueue<T> ofAll(ImmutableList<T> list){ return new Cons<>(list.size(), list,0, list.emptyUnit()); } LazySeq<T> lazySeq();
public BankersQueue<T> tail() { if(size()==1) return empty(); if(sizeFront==0){ return BankersQueue.ofAll(back.fold(s->s.fold((h, t)->t), n->n)); } if(sizeFront==1){ return ofAll(back); } return new BankersQueue.Cons<>(sizeFront-1,front.fold(s->s.fold((h, t)->t), n->n),sizeBack,back); } public BankersQueue<T> replace(T currentElement, T newElement) {
private static <T> BankersQueue<T> check(Cons<T> check) { if(check.sizeBack<=check.sizeFront) return check; return new Cons((check.sizeFront + check.sizeBack), check.front.appendAll(check.back.reverse()), 0, LazySeq.empty()); }
@Override public <R> BankersQueue<R> map(Function<? super T, ? extends R> map) { return check(new Cons(sizeFront,front.map(map),sizeBack,back.map(map))); }
public static <T> BankersQueue<T> cons(T value){ return new Cons<>(1, LazySeq.cons(value,()-> LazySeq.empty()),0, LazySeq.empty()); } public static <T> BankersQueue<T> ofAll(ImmutableList<T> list){
@Override default BankersQueue<T> drop(long num) { if(num<=0) return this; if(num>=size()) return empty(); return this.foldBankersQueue(c -> { ImmutableList<T> newFront = c.front.drop(num); ImmutableList<T> newBack = c.back.dropRight((int) num - c.front.size()); if (newFront.size() > 0 || newBack.size() > 0) return new Cons<>(newFront, newBack); return empty(); }, nil -> nil); }
@Override public <R> BankersQueue<R> concatMap(Function<? super T, ? extends Iterable<? extends R>> fn) { return check(new Cons(sizeFront,front.concatMap(fn),sizeBack,back.concatMap(fn))); }
@Override public BankersQueue<T> enqueue(T value) { return check(new Cons(sizeFront, front, sizeBack + 1, back.prepend(value))); }
public static <T> BankersQueue<T> ofAll(ImmutableList<T> list){ return new Cons<>(list.size(), list,0, list.emptyUnit()); } LazySeq<T> lazySeq();
@Override public BankersQueue<T> prepend(T value) { return new Cons<>(sizeFront+1,front.prepend(value),sizeBack,back); }
private static <T> BankersQueue<T> check(Cons<T> check) { if(check.sizeBack<=check.sizeFront) return check; return new Cons((check.sizeFront + check.sizeBack), check.front.appendAll(check.back.reverse()), 0, LazySeq.empty()); }
public BankersQueue<T> replace(T currentElement, T newElement) { ImmutableList<T> replaceF = front.replaceFirst(currentElement, newElement); ImmutableList<T> replaceB = back.replaceFirst(currentElement, newElement); return front==replaceF && back==replaceB ? this : new Cons<>(replaceF, replaceB); } public Option<T> get(int n) {
public BankersQueue<T> tail() { if(size()==1) return empty(); if(sizeFront==0){ return BankersQueue.ofAll(back.fold(s->s.fold((h, t)->t), n->n)); } if(sizeFront==1){ return ofAll(back); } return new BankersQueue.Cons<>(sizeFront-1,front.fold(s->s.fold((h, t)->t), n->n),sizeBack,back); } public BankersQueue<T> replace(T currentElement, T newElement) {