import java.util.*; /**************/ /* Interfaces */ /**************/ interface GerminalList<T> { T getSentinel(); boolean isEmpty(); int size(); String toString(final String delimiter); String toString(final String delimiter, final String begin, final String end); } interface DecomposableList<T> extends GerminalList<T> { int indexOf(final T item); boolean contains(final T item); T get(int index); T getFirst(); T getLast(); } interface RightAppendableList<T> extends GerminalList<T> { RightAppendableList<T> add(final T item); RightAppendableList<T> addMultiple(final T[] items); RightAppendableList<T> addMultiple(final List<T> items); } interface LeftAppendableList<T> extends GerminalList<T> { LeftAppendableList<T> insert(final T item); LeftAppendableList<T> insertMultiple(final T[] items); LeftAppendableList<T> insertMultiple(final List<T> items); } interface RightTruncatableList<T> extends GerminalList<T> { T removeLast(); } interface LeftTruncatableList<T> extends GerminalList<T> { T removeFirst(); } interface ShortenableList<T> extends RightTruncatableList<T>, LeftTruncatableList<T> { T remove(final int index); } interface LengthenableList<T> extends RightAppendableList<T>, LeftAppendableList<T> { LengthenableList<T> insert(int index, final T item); } interface RandomizibleList<T> extends GerminalList<T> { int getRandomIndex(); RandomizibleList<T> insertRandom(T item); T getRandom(); T removeRandom(); RandomizibleList<T> shuffle(); } interface SortableList<T> extends GerminalList<T> { SortableList<T> sort(final Comparator<T> comparator); } interface LIFOStack<T> extends RightAppendableList<T>, RightTruncatableList<T> { T getLast(); } interface FIFOQueue<T> extends LeftAppendableList<T>, LeftTruncatableList<T> { T getFirst(); } interface DEQueue<T> extends LIFOStack<T>, FIFOQueue<T> { DEQueue<T> insert(final T item); } /********************/ /* Abstract Classes */ /********************/ abstract class VersatileList<T> implements GerminalList<T>, ShortenableList<T>, LengthenableList<T>, DecomposableList<T>, SortableList<T>, RandomizibleList<T>, LIFOStack<T>, FIFOQueue<T>, DEQueue<T> { private final T sentinel; private final List<T> elements; protected VersatileList(final List<T> list, final T sentinel) { elements = list; this.sentinel = sentinel; } public VersatileList<T> add(final T item) { elements.add(item); return this; } public VersatileList<T> insertRandom(final T item) { elements.add(getRandomIndex(), item); return this; } public final VersatileList<T> addMultiple(final T[] items) { if (items != null) for (T item : items) add(item); return this; } public final VersatileList<T> addMultiple(final List<T> items) { if (items != null) for (T item : items) add(item); return this; } public boolean contains(final T item) { return elements.indexOf(item) >= 0; } public T get(final int index) { return (index >= 0 && index < elements.size()) ? elements.get(index) : sentinel; } public final int getRandomIndex() { return elements.size() > 0 ? (int)(Math.random() * elements.size()) : -1; } public final T getFirst() { return get(0); } public final T getLast() { return get(elements.size() - 1); } public final T getRandom() { return get(getRandomIndex()); } public final T getSentinel() { return sentinel; } public final int indexOf(final T item) { return elements.indexOf(item); } public VersatileList<T> insert(final T item) { elements.add(0, item); return this; } public VersatileList<T> insert(int index, final T item) { elements.add(index, item); return this; } public final VersatileList<T> insertMultiple(final T[] items) { if (items != null) for (T item : items) insert(item); return this; } public final VersatileList<T> insertMultiple(final List<T> items) { if (items != null) for (T item : items) insert(item); return this; } public boolean isEmpty() { return elements.size() == 0; } public final T remove(final int index) { return (index >= 0 && index < elements.size()) ? remove(index) : sentinel; } public final T removeFirst() { return remove(0); } public final T removeLast() { return remove(elements.size() - 1); } public final T removeRandom() { return remove(getRandomIndex()); } public final int size() { return elements.size(); } public final VersatileList<T> shuffle() { for (int n = size(); n > 1; n = n - 1) swap(n-1, (int)(Math.random() * n)); return this; } public final VersatileList<T> sort(final Comparator<T> comparator) { Collections.sort(elements, comparator); return this; } protected final VersatileList<T> swap(final int i, final int j) { // Precondition: Values of i and j must be valid indices of elements. T item = elements.get(i); elements.set(i, elements.get(j)); elements.set(j, item); return this; } public String toString() { return toString(", "); } public String toString(final String delimiter) { return toString(delimiter, "{", "}"); } public String toString(final String delimiter, final String begin, final String end) { final int n = elements.size(); StringBuilder sb = new StringBuilder(begin); if (n > 0) { sb.append(elements.get(0).toString()); } for (int i = 1; i < n; i = i + 1) { sb.append(delimiter + elements.get(i).toString()); } sb.append(end); return sb.toString(); } } abstract class VersatileListSet<T> extends VersatileList<T> { protected VersatileListSet(final List<T> list, final T sentinel) { super(list, sentinel); } public final VersatileListSet<T> add(final T item) { if (!contains(item)) super.add(item); return this; } public final VersatileListSet<T> insert(final int index, final T item) { if (!contains(item)) insert(index, item); return this; } } abstract class VersatileListMultiset<T> extends VersatileList<T> { protected VersatileListMultiset(final List<T> list, final T sentinel) { super(list, sentinel); } } /********************/ /* Concrete Classes */ /********************/ class ArrayListSet<T> extends VersatileListSet<T> { public ArrayListSet(final T sentinel) { super(new ArrayList<T>(), sentinel); } public ArrayListSet() { this(null); } } class LinkedListSet<T> extends VersatileListSet<T> { public LinkedListSet(final T sentinel) { super(new LinkedList<T>(), sentinel); } public LinkedListSet() { this(null); } } class ArrayListMultiset<T> extends VersatileListMultiset<T> { public ArrayListMultiset(final T sentinel) { super(new ArrayList<T>(), sentinel); } public ArrayListMultiset() { this(null); } } class LinkedListMultiset<T> extends VersatileListMultiset<T> { public LinkedListMultiset(final T sentinel) { super(new LinkedList<T>(), sentinel); } public LinkedListMultiset() { this(null); } } /***********/ /* Program */ /***********/ public class LinearLists { public static void main(String args[]) { final VersatileList<String> list = new ArrayListMultiset<String>().addMultiple(args).shuffle(); final LIFOStack<String> stack = list; final FIFOQueue<String> queue = list; System.out.println(list); System.out.println(stack.toString(", ", "LIFO Stack: {", "} < in-out >")); System.out.println(queue.toString(", ", "FIFO Queue: < out {", "} < in")); } }