package com.googlecode.totallylazy.collections; import com.googlecode.totallylazy.functions.Function1; import com.googlecode.totallylazy.functions.Function2; import com.googlecode.totallylazy.functions.Callables; import com.googlecode.totallylazy.functions.Curried2; import com.googlecode.totallylazy.Iterators; import com.googlecode.totallylazy.Option; import com.googlecode.totallylazy.Pair; import com.googlecode.totallylazy.predicates.Predicate; import com.googlecode.totallylazy.Segment; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.RandomAccess; import static com.googlecode.totallylazy.Option.some; import static com.googlecode.totallylazy.predicates.Predicates.in; import static com.googlecode.totallylazy.predicates.Predicates.not; import static com.googlecode.totallylazy.Sequences.sequence; import static com.googlecode.totallylazy.Sets.set; import static com.googlecode.totallylazy.numbers.Numbers.intValue; public class TreeList<T> extends AbstractList<T> implements PersistentList<T>, RandomAccess { private final PersistentSortedMap<Integer, T> map; private TreeList(PersistentSortedMap<Integer, T> map) {this.map = map;} public static <T> TreeList<T> treeList(PersistentSortedMap<Integer, T> map) {return new TreeList<T>(map);} public static <T> TreeList<T> treeList() { return treeList(PersistentSortedMap.constructors.<Integer, T>emptySortedMap()); } public static <T> TreeList<T> treeList(T first) { return treeList(sequence(first)); } public static <T> TreeList<T> treeList(T first, T second) { return treeList(sequence(first, second)); } public static <T> TreeList<T> treeList(T first, T second, T third) { return treeList(sequence(first, second, third)); } public static <T> TreeList<T> treeList(T first, T second, T third, T fourth) { return treeList(sequence(first, second, third, fourth)); } public static <T> TreeList<T> treeList(T first, T second, T third, T fourth, T fifth) { return treeList(sequence(first, second, third, fourth, fifth)); } @SafeVarargs public static <T> TreeList<T> treeList(T... values) { return treeList(sequence(values)); } public static <T> TreeList<T> treeList(Iterable<? extends T> iterable) { return treeList(PersistentSortedMap.constructors.<Integer, T>sortedMap(sequence(iterable). zipWithIndex().map(Callables.<Number, T, Integer>first(intValue)))); } @Override public TreeList<T> empty() { return treeList(); } @Override public boolean isEmpty() { return map.isEmpty(); } @Override public T head() throws NoSuchElementException { if(map.isEmpty()) throw new NoSuchElementException(); return map.get(0).second(); } @Override public Option<T> headOption() { return isEmpty() ? Option.<T>none() : some(head()); } @Override public TreeList<T> tail() throws NoSuchElementException { return treeList(map.delete(map.first().first())); } @Override public TreeList<T> cons(T head) { int index = map.isEmpty() ? 0 : map.first().first(); return treeList(map.cons(Pair.pair(--index, head))); } @Override public TreeList<T> append(T value) { int index = map.isEmpty() ? 0 : map.last().first(); return treeList(map.cons(Pair.pair(++index, value))); } @Override public TreeList<T> delete(T value) { return treeList(toSequence().delete(value)); } @Override public <C extends Segment<T>> C joinTo(C rest) { return toSequence().joinTo(rest); } @Override public boolean contains(Object other) { return toSequence().contains(other); } @Override public boolean exists(Predicate<? super T> predicate) { return toSequence().exists(predicate); } @Override public int size() { return map.size(); } @Override public T get(int i) throws IndexOutOfBoundsException { return map.get(i).second(); } @Override public int indexOf(Object t) { return toSequence().indexOf(t); } @Override public Iterator<T> iterator() { return Iterators.map(map.iterator(), Callables.<T>second()); } }