com.ajjpj.abase.collection.immutable.AList Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of a-base Show documentation
Show all versions of a-base Show documentation
a-base is a library of basic (hence the name) classes, most notably immutable collection classes with copy-on-write operations
package com.ajjpj.abase.collection.immutable;
import com.ajjpj.abase.collection.ACollectionHelper;
import com.ajjpj.abase.collection.AEquality;
import com.ajjpj.abase.function.AFunction1;
import com.ajjpj.abase.function.APredicate;
import java.lang.reflect.Array;
import java.util.*;
/**
* This is an immutable linked list implementation. It provides "mutators" that return copies of the list without
* affecting the original ("copy on write").
*
* The API is based on terminology of functional languages. NIL is the empty list, head<
is the list's
* first element, tail
is the list without its first element, and cons()
is the
* operation that prepends an element to an existing list.
*
* @author arno
*/
abstract public class AList extends AbstractACollection> {
private final int size;
protected AList(int size) {
this.size = size;
}
/**
* Returns the empty list. All calls to this method are guaranteed to return the same instance.
*/
@SuppressWarnings("unchecked")
public static AList nil() {
return (AList) Nil.INSTANCE;
}
/**
* Creates an AList based on the contents of an existing java.util.Iterable
, copying its contents.
*/
public static AList create(Iterable elements) {
if(elements instanceof List) {
return create((List) elements);
}
AList result = nil();
for(T el: elements) {
result = result.cons(el);
}
return result.reverse();
}
/**
* Creates an AList based on the contents of an existing java.util.List
, copying its content.
*/
public static AList create(List elements) {
AList result = nil();
for(int i=elements.size()-1; i>=0; i--) {
result = result.cons(elements.get(i));
}
return result;
}
/**
* Creates an AList from a given list of elements.
*/
@SafeVarargs
public static AList create(T... elements) {
return create(Arrays.asList(elements));
}
/**
* Returns a read-only java.util.List
view of this AList.
*/
public java.util.List asJavaUtilList() {
return new JuListWrapper<>(this);
}
@Override protected AList createInternal(Collection elements) {
return AList.create(elements);
}
@Override protected AEquality equalityForEquals() {
return AEquality.EQUALS;
}
/**
* Returns this AList's head, if any.
*/
public abstract AOption optHead();
/**
* Returns the list's head, i.e. its first element. If called on the empty list, it throws a NoSuchElementException
.
*/
public abstract T head();
/**
* Returns the list's tail, i.e. the list without its first element. If called on the empty list, it throws a
* NoSuchElementException
.
*/
public abstract AList tail();
/**
* Returns a new AList with the new element prepended. This is the only operation to 'add' elements to an AList.
*/
public AList cons(T el) {
return new AHead<>(el, this);
}
/**
* Returns a copy of this AList with elements in reversed order.
*/
public AList reverse() {
AList remaining = this;
AList result = nil();
while(! remaining.isEmpty()) {
result = result.cons(remaining.head());
remaining = remaining.tail();
}
return result;
}
public int size() {
return size;
}
@Override public AList toList() {
// override as an optimization
return this;
}
@Override public AList map (AFunction1 super T, ? extends X, E> f) throws E {
return create(ACollectionHelper.map(this, f));
}
@Override public AList flatMap(AFunction1 super T, ? extends Iterable, E> f) throws E {
return create(ACollectionHelper.flatMap(this, f));
}
@SuppressWarnings("unchecked")
@Override public AList flatten() {
return (AList) create(ACollectionHelper.flatten((Iterable extends Iterable