edu.emory.mathcs.backport.java.util.LinkedList Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of virtdata-lib-curves4 Show documentation
Show all versions of virtdata-lib-curves4 Show documentation
Statistical sampling library for use in virtdata libraries, based
on apache commons math 4
package edu.emory.mathcs.backport.java.util;
import java.io.*;
import java.util.List;
import java.util.Iterator;
import java.util.Collection;
import java.util.ListIterator;
import java.util.AbstractSequentialList;
import java.lang.reflect.Array;
import java.util.NoSuchElementException;
import java.util.ConcurrentModificationException;
public class LinkedList extends AbstractSequentialList
implements List, Deque, Cloneable, Serializable
{
private static final long serialVersionUID = 876323262645176354L;
private transient int size = 0;
private transient int modCount;
// bi-directional cyclic list; head contains a sentinel entry
private transient Entry head;
private static class Entry {
Entry prev;
Entry next;
Object val;
Entry(Object val) {
this.val = val;
}
}
public LinkedList() {
Entry sentinel = new Entry(null);
sentinel.next = sentinel.prev = sentinel;
head = sentinel;
}
public LinkedList(Collection c) {
this();
addAll(c);
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public boolean contains(Object o) {
return findFirst(o) != null;
}
private Entry getAt(int idx) {
Entry e;
int size = this.size;
if (idx < 0 || idx >= size) {
throw new ArrayIndexOutOfBoundsException("Index: " + idx +
"; Size: " + size);
}
if (idx < (size >> 1)) {
for (e = head.next; idx>0; idx--) e = e.next;
return e;
}
else {
idx = size-idx-1;
for (e = head.prev; idx>0; idx--) e = e.prev;
return e;
}
}
private Entry findFirst(Object o) {
if (o == null) {
for (Entry e = head.next; e != head; e = e.next) {
if (e.val == null) return e;
}
}
else {
for (Entry e = head.next; e != head; e = e.next) {
if (o.equals(e.val)) return e;
}
}
return null;
}
private Entry findLast(Object o) {
if (o == null) {
for (Entry e = head.prev; e != head; e = e.prev) {
if (e.val == null) return e;
}
}
else {
for (Entry e = head.prev; e != head; e = e.prev) {
if (o.equals(e.val)) return e;
}
}
return null;
}
public int indexOf(Object o) {
int idx=0;
if (o == null) {
for (Entry e = head.next; e != head; e = e.next, idx++) {
if (e.val == null) return idx;
}
}
else {
for (Entry e = head.next; e != head; e = e.next, idx++) {
if (o.equals(e.val)) return idx;
}
}
return -1;
}
public int lastIndexOf(Object o) {
int idx=size-1;
if (o == null) {
for (Entry e = head.prev; e != head; e = e.prev, idx--) {
if (e.val == null) return idx;
}
}
else {
for (Entry e = head.prev; e != head; e = e.prev, idx--) {
if (o.equals(e.val)) return idx;
}
}
return -1;
}
public Object[] toArray() {
Object[] a = new Object[size];
int i=0;
for (Entry e = head.next; e != head; e = e.next) a[i++] = e.val;
return a;
}
public Object[] toArray(Object[] a) {
int size = this.size;
if (a.length < size) {
a = (Object[])Array.newInstance(a.getClass().getComponentType(), size);
}
int i=0;
for (Entry e = head.next; e != head; e = e.next) a[i++] = e.val;
if (i < a.length) a[i++] = null;
return a;
}
public boolean add(Object o) {
insertBefore(head, o);
return true;
}
private void insertAfter(Entry e, Object val) {
modCount++;
Entry succ = e.next;
Entry newe = new Entry(val);
newe.prev = e;
newe.next = succ;
e.next = newe;
succ.prev = newe;
size++;
}
private void insertBefore(Entry e, Object val) {
modCount++;
Entry pred = e.prev;
Entry newe = new Entry(val);
newe.prev = pred;
newe.next = e;
pred.next = newe;
e.prev = newe;
size++;
}
private Object remove(Entry e) {
if (e == head) throw new NoSuchElementException();
modCount++;
Entry succ = e.next;
Entry pred = e.prev;
pred.next = succ;
succ.prev = pred;
size--;
return e.val;
}
public boolean remove(Object o) {
Entry e = findFirst(o);
if (e == null) return false;
remove(e);
return true;
}
public boolean addAll(Collection c) {
return insertAllBefore(head, c);
}
public boolean addAll(int index, Collection c) {
return insertAllBefore((index == size) ? head : getAt(index), c);
}
private boolean insertAllBefore(Entry succ, Collection c) {
Iterator itr = c.iterator();
if (!itr.hasNext()) return false;
modCount++;
Entry first = new Entry(itr.next());
Entry prev = first;
Entry curr = first;
int added = 1;
while (itr.hasNext()) {
curr = new Entry(itr.next());
prev.next = curr;
curr.prev = prev;
prev = curr;
added++;
}
Entry pred = succ.prev;
first.prev = pred;
curr.next = succ;
pred.next = first;
succ.prev = curr;
size += added;
return true;
}
public void clear() {
modCount++;
head.next = head.prev = head;
size = 0;
}
public Object get(int index) {
return getAt(index).val;
}
public Object set(int index, Object element) {
Entry e = getAt(index);
Object old = e.val;
e.val = element;
return old;
}
public void add(int index, Object element) {
if (index == size) insertBefore(head, element);
else insertBefore(index == size ? head : getAt(index), element);
}
public Object remove(int index) {
return remove(getAt(index));
}
public ListIterator listIterator() {
return new Itr();
}
public ListIterator listIterator(int index) {
return new Itr(index == size ? head : getAt(index), index);
}
public void addFirst(Object e) {
insertAfter(head, e);
}
public void addLast(Object e) {
insertBefore(head, e);
}
public boolean offerFirst(Object e) {
insertAfter(head, e);
return true;
}
public boolean offerLast(Object e) {
insertBefore(head, e);
return true;
}
public Object removeFirst() {
return remove(head.next);
}
public Object removeLast() {
return remove(head.prev);
}
public Object pollFirst() {
return (size == 0) ? null : remove(head.next);
}
public Object pollLast() {
return (size == 0) ? null : remove(head.prev);
}
public Object getFirst() {
if (size == 0) throw new NoSuchElementException();
else return head.next.val;
}
public Object getLast() {
if (size == 0) throw new NoSuchElementException();
else return head.prev.val;
}
public Object peekFirst() {
return (size == 0) ? null : head.next.val;
}
public Object peekLast() {
return (size == 0) ? null : head.prev.val;
}
public boolean removeFirstOccurrence(Object o) {
Entry e = findFirst(o);
if (e == null) return false;
remove(e);
return true;
}
public boolean removeLastOccurrence(Object o) {
Entry e = findLast(o);
if (e == null) return false;
remove(e);
return true;
}
public boolean offer(Object e) {
return add(e);
}
public Object remove() {
return removeFirst();
}
public Object poll() {
return pollFirst();
}
public Object element() {
return getFirst();
}
public Object peek() {
return peekFirst();
}
public void push(Object e) {
addFirst(e);
}
public Object pop() {
return removeFirst();
}
public Iterator descendingIterator() {
return new DescItr();
}
private class Itr implements ListIterator {
int expectedModCount;
int idx;
Entry cursor;
Entry lastRet;
Itr(Entry cursor, int idx) {
this.cursor = cursor;
this.idx = idx;
this.expectedModCount = modCount;
}
Itr() {
this(head.next, 0);
}
public boolean hasNext() {
return cursor != head;
}
public int nextIndex() {
return idx;
}
public boolean hasPrevious() {
return cursor.prev != head;
}
public int previousIndex() {
return idx-1;
}
public Object next() {
if (expectedModCount != modCount) throw new ConcurrentModificationException();
if (cursor == head) throw new NoSuchElementException();
lastRet = cursor;
cursor = cursor.next;
idx++;
return lastRet.val;
}
public Object previous() {
if (expectedModCount != modCount) throw new ConcurrentModificationException();
if (cursor.prev == head) throw new NoSuchElementException();
lastRet = cursor = cursor.prev;
idx--;
return lastRet.val;
}
public void add(Object val) {
if (expectedModCount != modCount) throw new ConcurrentModificationException();
insertBefore(cursor, val);
lastRet = null;
idx++;
expectedModCount++;
}
public void set(Object newVal) {
if (lastRet == null) throw new IllegalStateException();
lastRet.val = newVal;
}
public void remove() {
if (expectedModCount != modCount) throw new ConcurrentModificationException();
if (lastRet == null) throw new IllegalStateException();
if (lastRet.next == cursor) idx--; else cursor = lastRet.next;
LinkedList.this.remove(lastRet);
lastRet = null;
expectedModCount++;
}
}
private class DescItr implements ListIterator {
int expectedModCount;
int idx;
Entry cursor;
Entry lastRet;
DescItr(Entry cursor, int idx) {
this.cursor = cursor;
this.idx = idx;
this.expectedModCount = modCount;
}
DescItr() {
this(head.prev, 0);
}
public boolean hasNext() {
return cursor != head;
}
public int nextIndex() {
return idx;
}
public boolean hasPrevious() {
return cursor.next != head;
}
public int previousIndex() {
return idx-1;
}
public Object next() {
if (expectedModCount != modCount) throw new ConcurrentModificationException();
if (cursor == head) throw new NoSuchElementException();
lastRet = cursor;
cursor = cursor.prev;
idx++;
return lastRet.val;
}
public Object previous() {
if (expectedModCount != modCount) throw new ConcurrentModificationException();
if (cursor.next == head) throw new NoSuchElementException();
lastRet = cursor = cursor.next;
idx--;
return lastRet;
}
public void add(Object val) {
if (expectedModCount != modCount) throw new ConcurrentModificationException();
insertAfter(cursor, val);
lastRet = null;
idx++;
expectedModCount++;
}
public void set(Object newVal) {
if (lastRet == null) throw new IllegalStateException();
lastRet.val = newVal;
}
public void remove() {
if (expectedModCount != modCount) throw new ConcurrentModificationException();
if (lastRet == null) throw new IllegalStateException();
if (lastRet.next == cursor) idx--; else cursor = lastRet.next;
LinkedList.this.remove(lastRet);
lastRet = null;
expectedModCount++;
}
}
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
out.writeInt(size);
for (Entry e = head.next; e != head; e = e.next) {
out.writeObject(e.val);
}
}
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException
{
in.defaultReadObject();
int size = in.readInt();
Entry head = new Entry(null);
head.next = head.prev = head;
for (int i=0; i < size; i++) {
insertBefore(head, in.readObject());
}
this.size = size;
this.head = head;
}
public Object clone() {
LinkedList clone = null;
try { clone = (LinkedList) super.clone(); }
catch (CloneNotSupportedException e) { throw new InternalError(); }
Entry head = new Entry(null);
head.next = head.prev = head;
clone.head = head;
clone.addAll(this);
return clone;
}
}