Subato

LinkedList Spliterator

package name.panitz.util;
import java.util.Spliterator;
import java.util.function.Consumer;

public class LL<A> implements Li<A> {
  private A hd;
  private LL<A> tl;

  public boolean isEmpty() {
    return hd == null && tl == null;
  }
  public A head(){
    return hd;
  }
  public LL<A> tail(){
    return tl;
  }

  public LL(A hd, LL<A> tl) {
    this.hd = hd;
    this.tl = tl;
  }

  public LL() {
    this(null, null);
  }

  @Override
  public Spliterator<A> getSpliterator() {
    return new MySplitter();
  }

  private class MySplitter implements Spliterator<A> {
    LL<A> it = LL.this;

    @Override
    public boolean tryAdvance(Consumer<? super A> action) {
      if (it.isEmpty())
        return false;
      action.accept(it.hd);
      it = it.tl;
      return true;
    }

    @Override
    public Spliterator<A> trySplit() {
      if (!(it.isEmpty() 
          || it.tl.isEmpty() 
          || it.tl.tl.isEmpty() 
          || it.tl.tl.tl.isEmpty()
          || it.tl.tl.tl.tl.isEmpty())) {
        Spliterator<A> result 
         =new LL<>(it.hd
            , new LL<>(it.tl.hd
                , new LL<>(it.tl.tl.hd
                    , new LL<>(it.tl.tl.tl.hd
                        , new LL<>())))).getSpliterator();
        it = it.tl.tl.tl.tl;
        return result;
      }
      return null;
    }

    @Override
    public long estimateSize() {
      return Long.MAX_VALUE;
    }

    @Override
    public int characteristics() {
      return 0;
    }
  }
  @Override 
  public String toString(){
    StringBuffer result = new StringBuffer("[");
    boolean first = true;
    for (LL<A> it = this;!it.isEmpty();it=it.tl){
      if (first){
        first = false;
      } else{
        result.append(", ");
      }
      result.append(it.hd);
    }
    result.append("]");
    return result.toString();
  }
}