/** * Created by spike on 2/19/17. */ public class LinkedList implements List { private LinkedListNode head; private LinkedListNode tail; private int size; private static class LinkedListNode { private Object data; private LinkedListNode prev; private LinkedListNode next; private LinkedListNode(Object data, LinkedListNode prev, LinkedListNode next) { this.data = data; this.prev = prev; this.next = next; } } @Override public String toString() { StringBuilder builder = new StringBuilder("List: [ "); LinkedListNode idx = head; while (idx != null) { builder.append(idx.data); builder.append(" "); idx = idx.next; } builder.append("]"); return builder.toString(); } public void add(int index, Object object) { if (index < 0 || index > size) { throw new IllegalArgumentException(); } if (index == size) { // insert after add(object); } else { // insert before LinkedListNode target = findNodeByIndex(index); LinkedListNode nd = new LinkedListNode(object, target.prev, target); if (head == target) { head = nd; } else { target.prev.next = nd; } } ++size; } public void add(Object object) { if (head == null) { LinkedListNode nd = new LinkedListNode(object, null, null); head = tail = nd; } else { LinkedListNode nd = new LinkedListNode(object, tail, null); tail.next = nd; tail = nd; } ++size; } public Object get(int index) { if (index < 0 || index >= size) { throw new IllegalArgumentException(); } LinkedListNode target = findNodeByIndex(index); return target.data; } public Object remove(int index) { if (index < 0 || index >= size) { throw new IllegalArgumentException(); } LinkedListNode target = findNodeByIndex(index); if (target == head) { if (head == tail) { head = tail = null; } else { head = head.next; head.prev = null; } } else if (target == tail) { tail = tail.prev; tail.next = null; } else { target.prev.next = target.next; target.next.prev = target.prev; } target.prev = target.next = null; --size; return target.data; } private LinkedListNode findNodeByIndex(int index) { LinkedListNode target = head; for (int i = 0; i != index; ++i) { target = target.next; } return target; } public int size() { return size; } public Iterator iterator() { return new LinkedListIterator(); } private class LinkedListIterator implements Iterator { LinkedListNode cursor = head; public boolean hasNext() { return cursor != null; } public Object next() { Object toRet = cursor.data; cursor = cursor.next; return toRet; } } }