Back to project page sdk-hyphenation.
The source code is released under:
GNU Lesser General Public License
If you think the Android project sdk-hyphenation listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package org.silpa.hyphenation.util; //w w w .ja v a 2 s . co m import java.util.Enumeration; /** * Lispish list. * Not very lispish, but still... * The compromise is that some of operations are * destructive. */ public class List implements Cloneable { private Link head, tail; private int length; final static class Link { Object data; Link next; } /** * returns a mark set after the last element in the list */ public final class Mark { Link link; int length; Mark() { link = tail.next; this.length = List.this.length; } } /** * creates an empty list */ public List() { clear(); } /** * empties the list * * @return cleared list */ public final List clear() { head = new Link(); head.next = null; tail = new Link(); tail.next = head; length = 0; return this; } /** * calls a newInstance() to create a new list of the same type and then empties it * * @return the new list */ protected List newList() { try { return ((List) super.clone()).clear(); } catch (CloneNotSupportedException e) { throw new RuntimeException(e.getMessage()); } } /* clone/enloc are written to be as fast as possible */ /** * makes a shallow copy of the list * * @return object */ public Object clone() { List l = newList(); if (isPair()) { Link link = head.next; for (; ; ) { l.snoc(link.data); if (link == tail.next) break; link = link.next; } } return l; } /** * shallow copy reversed * * @return list */ public final List enolc() { List l = newList(); if (isPair()) { Link link = head.next; for (; ; ) { l.cons(link.data); if (link == tail.next) break; link = link.next; } } return l; } /** * reversed list * * @return reversed list */ public final List reverse() { return length > 1 ? enolc() : this; } /** * the same as cons * * @param o the object to add * @return this, modified by addition */ public final List unshift(Object o) { return cons(o); } /** * prepend one element to the list, destructive. * * @param o the element to add * @return this, modified by addition */ public final List cons(Object o) { Link link = new Link(); head.data = o; link.next = head; head = link; ++length; return this; } /** * prepend another list, destructive. * * @param l the other list * @return this, modified by addition */ public final List prepend(List l) { if (l.isPair()) { l.tail.next.next = head.next; head.next = l.head.next; length += l.length; } return this; } /** * append one element to the list, destructive. * * @param o the object to add * @return this, modified by addition */ public final List append(Object o) { return snoc(o); } /** * append one element to the list, destructive. * * @param o the object to add * @return this, modified by addition */ public final List snoc(Object o) { Link link = new Link(); link.data = o; link.next = tail.next.next; tail.next.next = link; tail.next = link; ++length; return this; } /** * append another list, destructive. * * @param l the other list * @return this, modified by addition */ public final List append(List l) { if (l.isPair()) { tail.next.next = l.head.next; tail.next = l.tail.next; length += l.length; } return this; } /** * remove first element and return it * * @return an object kept in the first link of the list */ public final Object shift() { if (!isPair()) throw new java.util.NoSuchElementException("list is not a pair"); head = head.next; --length; return head.data; } /** * whether the list is empty * * @return true if empty else false */ public final boolean isEmpty() { return !isPair(); } /** * whether the list is not empty (is a pair) * * @return true if pair else false */ public final boolean isPair() { return head.next != tail.next.next; } /** * number of links in the list * * @return int */ public final int length() { return length; } /** * the first element of the list * * @return the object kept in the first element */ public final Object head() { if (!isPair()) throw new java.util.NoSuchElementException("list is not a pair"); return head.next.data; } /** * the last element of the list * * @return the object kept in the last element */ public final Object last() { if (!isPair()) throw new java.util.NoSuchElementException("list is not a pair"); return tail.next.data; } /** * the list's longest 'tail' * * @return an object of the same type holding all the elements but the first one */ public final List longTail() { List l = newList(); if (!isPair()) throw new java.util.NoSuchElementException("list is not a pair"); l.head.next = head.next.next; l.tail = tail; l.length = length - 1; return l; } /** * the list's shortest 'tail' * * @return a list containing only the last element */ public final List shortestTail() { List l = newList(); if (!isPair()) throw new java.util.NoSuchElementException("list is not a pair"); l.head.next = tail.next; l.tail = tail; l.length = length - 1; return l; } /** * puts an object into the first element of the list * * @param o Object * @return this, after putting object into first element of list */ public final List setCar(Object o) { if (!isPair()) throw new java.util.NoSuchElementException("list is not a pair"); head.next.data = o; return this; } /** * binds value to the last link in the list * * @param o Object * @return this, after binding value to last link in list */ public final List setLast(Object o) { if (!isPair()) throw new java.util.NoSuchElementException("list is not a pair"); tail.next.data = o; return this; } /** * replaces the tail of a list with another list * * @param l list l * @return this, after */ public final List setCdr(List l) { if (!isPair()) throw new java.util.NoSuchElementException("list is not a pair"); head.next.next = l.head.next; length = l.length + 1; return this; } /** * perform an operation on each element of the list * * @param a applicator * @see org.silpa.hyphenation.util.Applicator */ public final void foreach(Applicator a) { for (Enumeration e = elements(); e.hasMoreElements(); ) a.f(e.nextElement()); } /** * (map (lambda (x) (...)) '(....)) * * @param t list to put the new values into * @param a applicator * @return the list passed as t filled with new elements * @see org.silpa.hyphenation.util.Applicator */ public final List map(List t /* target, to */, Applicator a) { for (Enumeration e = elements(); e.hasMoreElements(); ) t.append(a.f(e.nextElement())); return t; } /** * put a mark at the last element * * @return Mark object */ public final Mark mark() { return new Mark(); } /** * store an object after the mark * * @param mark mark object * @param o Object * @return this, after storing after the mark */ public final List insert(Mark mark, Object o) { Link link = new Link(); link.next = mark.link.next; link.data = o; mark.link.next = link; if (tail.next == mark.link) tail.next = link; ++length; return this; } /** * cut the list after the mark, the length value will be incorrect * if elements are inserted before the mark * * @param mark mark obj * @return new list */ public final List cut(Mark mark) { tail.next = mark.link; length = mark.length; return this; } /** * hygienic cut. The length is recomputed. * * @param mark mark * @return list */ public final List hcut(Mark mark) { tail.next = mark.link; length = 0; Link cur = head.next; while (cur != tail.next.next) { ++length; cur = cur.next; } return this; } /** * insert a list after the mark * * @param mark list mark * @param l list l * @return new list after insertion */ public final List insert(Link mark, List l) { Link next = mark.next; l.tail.next.next = next; mark.next = l.head.next; if (tail.next == mark) tail.next = l.tail.next; length += l.length; return this; } /** * Transform List to a human readable string (useful in testing and debugging). * * @return string */ public String describe() { StringBuffer buffer = new StringBuffer(); describe(buffer); return buffer.toString(); } /** * Description * * @param buffer string buffer */ private void describe(StringBuffer buffer) { buffer.append("("); String elementSeparator = ""; Enumeration enumeration = elements(); while (enumeration.hasMoreElements()) { Object o = enumeration.nextElement(); //Separate elements by space (Java does not support join) buffer.append(elementSeparator); elementSeparator = " "; if (o instanceof List) { ((List) o).describe(buffer); } else if (o instanceof int[]) { buffer.append("["); int[] ints = (int[]) o; String intSeparator = ""; for (int i : ints) { buffer.append(intSeparator + i); intSeparator = ", "; } buffer.append("]"); } else { buffer.append(o.toString()); } } buffer.append(")"); } /** * To String method * * @return string */ public String toString() { return isPair() ? longTail().addToString(head().toString()) : "()"; } private String addToString(String s) { if (isPair()) { return longTail().addToString(s + " " + head()); } else { return "(" + s + ")"; } } public final Enumeration elements() { return new Enumerator(); } private class Enumerator implements Enumeration { private Link cur; Enumerator() { cur = head.next; } public final Object nextElement() { Object o; if (cur == tail.next.next) throw new java.util.NoSuchElementException("attempt to access element past the end of a list"); o = cur.data; cur = cur.next; return o; } public final boolean hasMoreElements() { return cur != tail.next.next; } } }