package com.zzl.util; import java.util.NoSuchElementException; public class LinkedList implements List{ private int size = 0; private Node head; private Node last; void linkFirst(Object o){ final Node h = head; final Node newNode = new Node(o, h); head = newNode; if(h == null) last = newNode; size++; } void linkLast(Object o){ final Node l = last; final Node newNode = new Node(o, null); last = newNode; if(l == null) head = newNode; else l.next = newNode; size++; } void linkBefore(Object o, Node succ){ final Node next = succ.next; final Node newNode = new Node(o, next); succ.next = newNode; size++; } @Override public void add(Object o) { linkLast(o); } @Override public void add(int index, Object o) { rangeCheck(index); if(index == 0) linkFirst(o); else if(index == size) linkLast(o); else linkBefore(o, node(index - 1)); } @Override public Object get(int index) { rangeCheck(index); return node(index).data; } @Override public Object remove(int index) { rangeCheck(index); return changeNode(node(index), index); } @Override public int size() { return size; } public void addFirst(Object o){ linkFirst(o); } public Object removeFirst(){ return remove(0); } public Object removeLast(){ return remove(size - 1); } public Iterator iterator(){ return new LinkedListIterator(); } private Object changeNode(Node oldNode, int index){ Object oldNodeValue = oldNode.data; if(index == 0){ head = oldNode.next; }else { Node oldNodePrev = node(index - 1); oldNodePrev.next = oldNode.next; if(null == oldNode.next){ last = oldNodePrev; } } oldNode.data = null; oldNode.next = null; size--; return oldNodeValue; } private void rangeCheck(int index){ if(index > size || index < 0) throw new IndexOutOfBoundsException("Index:" + index + "size:" + size); } Node node(int index){ Node x = head; for(int i = 0; i < index; i++) x = x.next; return x; } private static class Node{ Object data; Node next; private Node(Object o, Node l){ this.next = l; this.data = o; } } private class LinkedListIterator implements Iterator{ private Node lastReturned; private Node next; private int nextIndex; LinkedListIterator(){ next = LinkedList.this.head; nextIndex = 0; } @Override public boolean hasNext() { return nextIndex < size; } @Override public Object next() { if (!hasNext()) throw new NoSuchElementException(); lastReturned = next; next = next.next; nextIndex++; return lastReturned.data; } } }