圖1 嵌套類java
如上圖一所示是嵌套類的分類和一些使用策略,主要須要注意的就是,嵌套類主要是爲外部類服務的,最好是僅僅在外部類中使用,如在其餘類中須要使用另一個類的嵌套類,那麼該嵌套類就應該作爲頂級類,而不是嵌套類。node
若是須要使用嵌套類,那麼優秀考慮靜態成員類,能夠參考 effictive java 2版 22節 優先考慮靜態成員類。由於每個非靜態成員類的實例會維護一個外部類的實例,因此有空間和時間的開銷。若是確實須要外部類的實例引用,例如要直接訪問外部類的飛靜態成員變量等,那麼就能夠考慮非靜態成員類。多線程
若是隻須要類的一個實例,而且有預置類型,例如不少繼承Thread的類,或者實現Runnable的類就能夠作成匿名類。若是沒有預置類型就能夠考慮局部類。this
上面講了一些緣由和策略,下面來看一下具體的應用,咱們以LinkedList的源碼爲例,LinkedList也是Josh Block寫的,代碼裏面對於嵌套類使用應該是對嵌套類使用的最佳實踐了。spa
package java.util; /** * * List 和 Deque雙向鏈表的實現 * */ public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable { //3個成員變量都是transient修飾的,不會被系列化 transient int size = 0; transient Node<E> first; transient Node<E> last; public LinkedList() { } public LinkedList(Collection<? extends E> c) { this(); addAll(c); } /** * 把元素放入雙向鏈表中的第一個位置 * * 首先構造一個節點(Node),由於是插入在1個節點以前因此它的前一個(prev)節點爲null, * 後一個節點(succ)就是原來的第一節點f */ private void linkFirst(E e) { final Node<E> f = first; final Node<E> newNode = new Node<>(null, e, f); first = newNode; //f爲null說明原來沒有節點,因此第一個節點也是最後一個節點,last也指向它 if (f == null) last = newNode; else f.prev = newNode;//若是原來鏈表不爲null,新節點(newNode)就是原來第一個節點的前一個(prev)節點 size++; modCount++; } /** * 把元素放入雙向鏈表中的最後一個位置 * * 由於是插入在最後一個位置,因此新的節點的前一個節點(prev)就是 * 原來的最後一個節點,後一個節點(succ)爲null */ void linkLast(E e) { final Node<E> l = last; final Node<E> newNode = new Node<>(l, e, null); last = newNode; if (l == null)//若是最後一個節點爲空,說明鏈表原來爲空,新節點既是最後一個也是第一個節點 first = newNode; else l.next = newNode; size++; modCount++; } /** * 把指定元素插入都指定元素succ以前 */ void linkBefore(E e, Node<E> succ) { // assert succ != null; final Node<E> pred = succ.prev; final Node<E> newNode = new Node<>(pred, e, succ); succ.prev = newNode;//把succ節點的前一個(pred)節點設置爲新節點(newNode) if (pred == null)//若是succ的原來的前一個節點爲null,說明succ節點是第一個節點 first = newNode; else pred.next = newNode; //把新節點的後一個(next)節點設置爲succ size++; modCount++; } /** * 移除第一個元素 */ private E unlinkFirst(Node<E> f) { // assert f == first && f != null; final E element = f.item; final Node<E> next = f.next; f.item = null; f.next = null; // help GC first = next; if (next == null) last = null; else next.prev = null; size--; modCount++; return element; } /** * 移除最後一個元素 */ private E unlinkLast(Node<E> l) { // assert l == last && l != null; final E element = l.item; final Node<E> prev = l.prev; l.item = null; l.prev = null; // help GC last = prev; if (prev == null) first = null; else prev.next = null; size--; modCount++; return element; } /** * Unlinks non-null node x. */ E unlink(Node<E> x) { // assert x != null; final E element = x.item; final Node<E> next = x.next; final Node<E> prev = x.prev; if (prev == null) { first = next; } else { prev.next = next; x.prev = null; } if (next == null) { last = prev; } else { next.prev = prev; x.next = null; } x.item = null; size--; modCount++; return element; } /** * 獲取第一個節點元素O(1) * */ public E getFirst() { final Node<E> f = first; if (f == null) throw new NoSuchElementException(); return f.item; } /** * 獲取最後一個節點元素O(1) * */ public E getLast() { final Node<E> l = last; if (l == null) throw new NoSuchElementException(); return l.item; } /** * 移除第一個元素O(1) * */ public E removeFirst() { final Node<E> f = first; if (f == null) throw new NoSuchElementException(); return unlinkFirst(f); } /** * 移除最後一個O(1) * */ public E removeLast() { final Node<E> l = last; if (l == null) throw new NoSuchElementException(); return unlinkLast(l); } /** * 把元素e插入雙向鏈表的第一個位置 * O(1) */ public void addFirst(E e) { linkFirst(e); } /** * 把元素插入雙向鏈表最後一個位置 * O(1) * */ public void addLast(E e) { linkLast(e); } /** * 檢查是否包含指定元素O(n) */ public boolean contains(Object o) { return indexOf(o) != -1; } /** * 返回元素個數 * */ public int size() { return size; } /** * 把元素插入雙向鏈表最後一個位置 * O(1) * */ public boolean add(E e) { linkLast(e); return true; } /** * * */ public boolean remove(Object o) { if (o == null) { for (Node<E> x = first; x != null; x = x.next) { if (x.item == null) { unlink(x); return true; } } } else { for (Node<E> x = first; x != null; x = x.next) { if (o.equals(x.item)) { unlink(x); return true; } } } return false; } /** * * */ public boolean addAll(Collection<? extends E> c) { return addAll(size, c); } /** * * */ public boolean addAll(int index, Collection<? extends E> c) { checkPositionIndex(index); Object[] a = c.toArray(); int numNew = a.length; if (numNew == 0) return false; Node<E> pred, succ; if (index == size) { succ = null; pred = last; } else { succ = node(index); pred = succ.prev; } for (Object o : a) { @SuppressWarnings("unchecked") E e = (E) o; Node<E> newNode = new Node<>(pred, e, null); if (pred == null) first = newNode; else pred.next = newNode; pred = newNode; } if (succ == null) { last = pred; } else { pred.next = succ; succ.prev = pred; } size += numNew; modCount++; return true; } /** * 幫助GC * */ public void clear() { // Clearing all of the links between nodes is "unnecessary", but: // - helps a generational GC if the discarded nodes inhabit // more than one generation // - is sure to free memory even if there is a reachable Iterator for (Node<E> x = first; x != null; ) { Node<E> next = x.next; x.item = null; x.next = null; x.prev = null; x = next; } first = last = null; size = 0; modCount++; } /** * 獲取指定位置的元素 * */ public E get(int index) { checkElementIndex(index); return node(index).item; } /** * * 使用指定元素替換指定位置的元素 */ public E set(int index, E element) { checkElementIndex(index); Node<E> x = node(index); E oldVal = x.item; x.item = element; return oldVal; } /** * * 把指定元素插入都指定位置以前 * */ public void add(int index, E element) { checkPositionIndex(index); if (index == size) linkLast(element); else linkBefore(element, node(index)); } /** * 移除指定位置的元素 * */ public E remove(int index) { checkElementIndex(index); return unlink(node(index)); } /** * 判斷指定元素是否存在 */ private boolean isElementIndex(int index) { return index >= 0 && index < size; } /** * 檢查是否但是一個合法的索引或者能夠添加元素的位置 */ private boolean isPositionIndex(int index) { return index >= 0 && index <= size; } private String outOfBoundsMsg(int index) { return "Index: "+index+", Size: "+size; } private void checkElementIndex(int index) { if (!isElementIndex(index)) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } private void checkPositionIndex(int index) { if (!isPositionIndex(index)) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } /** * 獲取指定位置的節點(Node) */ Node<E> node(int index) { // assert isElementIndex(index); //簡單二分,size>>1等價於size/2 //若是index值小於元素的一半,就從第一個元素開始查找 //不然就從最後一個位置開始查找 if (index < (size >> 1)) { Node<E> x = first; for (int i = 0; i < index; i++) x = x.next; return x; } else { Node<E> x = last; for (int i = size - 1; i > index; i--) x = x.prev; return x; } } // Search Operations /** * * 查找指定元素的位置 O(n) * */ public int indexOf(Object o) { int index = 0; if (o == null) { for (Node<E> x = first; x != null; x = x.next) { if (x.item == null) return index; index++; } } else { for (Node<E> x = first; x != null; x = x.next) { if (o.equals(x.item)) return index; index++; } } return -1; } /** * 查找指定元素的位置 O(n) */ public int lastIndexOf(Object o) { int index = size; if (o == null) { for (Node<E> x = last; x != null; x = x.prev) { index--; if (x.item == null) return index; } } else { for (Node<E> x = last; x != null; x = x.prev) { index--; if (o.equals(x.item)) return index; } } return -1; } // Queue operations. /** * 獲取第一個元素,可是不刪除 * */ public E peek() { final Node<E> f = first; return (f == null) ? null : f.item; } /** * 獲取第一個元素,可是不刪除 * */ public E element() { return getFirst(); } /** * 獲取而且刪除第一個元素 * */ public E poll() { final Node<E> f = first; return (f == null) ? null : unlinkFirst(f); } /** * 獲取而且刪除第一個元素 * */ public E remove() { return removeFirst(); } /** * 把指定元素插入到鏈表末尾 * */ public boolean offer(E e) { return add(e); } /** * 把指定元素插入到鏈表開始 * */ public boolean offerFirst(E e) { addFirst(e); return true; } /** * 把指定元素插入到鏈表末尾 * */ public boolean offerLast(E e) { addLast(e); return true; } /** * 獲取鏈表中的第一個元素 * * */ public E peekFirst() { final Node<E> f = first; return (f == null) ? null : f.item; } /** * 獲取鏈表中的最後一個元素 * * */ public E peekLast() { final Node<E> l = last; return (l == null) ? null : l.item; } /** * 獲取而且刪除鏈表中第一個元素 * * */ public E pollFirst() { final Node<E> f = first; return (f == null) ? null : unlinkFirst(f); } /** * 獲取而且刪除鏈表中最後一個元素 * * */ public E pollLast() { final Node<E> l = last; return (l == null) ? null : unlinkLast(l); } /** * 把指定元素加入到鏈表開頭O(1) */ public void push(E e) { addFirst(e); } /** * 移除鏈表第一個元素O(1) */ public E pop() { return removeFirst(); } /** * 移除鏈表中第一個指定元素 */ public boolean removeFirstOccurrence(Object o) { return remove(o); } /** * 移除鏈表中最後一個指定元素 */ public boolean removeLastOccurrence(Object o) { if (o == null) { for (Node<E> x = last; x != null; x = x.prev) { if (x.item == null) { unlink(x); return true; } } } else { for (Node<E> x = last; x != null; x = x.prev) { if (o.equals(x.item)) { unlink(x); return true; } } } return false; } /** * 返回一個迭代器 */ public ListIterator<E> listIterator(int index) { checkPositionIndex(index); return new ListItr(index); } /** * 非靜態成員類,LinkedList迭代器,只是爲LinkedList服務的 * 由於ListItr要使用外部類的非靜態成員變量,須要外部實例的 * 引用,因此使用的是非靜態內部類 */ private class ListItr implements ListIterator<E> { private Node<E> lastReturned = null;//迭代器的前一個位置 private Node<E> next; private int nextIndex; //在類(ListItr)初始化的時候記錄修改的次數,以便於檢查在迭代過程當中數據有沒有修改 private int expectedModCount = modCount; ListItr(int index) { // assert isPositionIndex(index); next = (index == size) ? null : node(index);//初始化迭代器的開始位置 nextIndex = index;//初始化迭代器的開始索引值 } public boolean hasNext() { return nextIndex < size; } //把當前位置標記爲前一個位置,而後next指向下一個位置 //下一個索引位置值+1,最後把迭代器當前位置的元素返回 public E next() { checkForComodification(); if (!hasNext()) throw new NoSuchElementException(); lastReturned = next; next = next.next; nextIndex++; return lastReturned.item; } public boolean hasPrevious() { return nextIndex > 0; } public E previous() { checkForComodification(); if (!hasPrevious()) throw new NoSuchElementException(); lastReturned = next = (next == null) ? last : next.prev; nextIndex--; return lastReturned.item; } public int nextIndex() { return nextIndex; } public int previousIndex() { return nextIndex - 1; } //把迭代器當前位置的元素移除 public void remove() { checkForComodification(); if (lastReturned == null) throw new IllegalStateException(); Node<E> lastNext = lastReturned.next; unlink(lastReturned); if (next == lastReturned) next = lastNext; else nextIndex--; lastReturned = null; expectedModCount++; } public void set(E e) { if (lastReturned == null) throw new IllegalStateException(); checkForComodification(); lastReturned.item = e; } public void add(E e) { checkForComodification(); lastReturned = null; if (next == null) linkLast(e); else linkBefore(e, next); nextIndex++; expectedModCount++; } //這個的假設是不會在迭代過程當中使用LinkedList的引用修改操做(參考LinkedListTest) //若是假設成立,那麼只有在多線程中其餘線程修改了LinkedList的實例纔會知足 //modCount != expectedModCount條件,說明產生了髒數據,直接拋出異常 final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } } /** * * 私用靜態內部類,爲外部內LinkedList服務,做爲LinkedList的一個組件 * 做爲一個外部類的成員,外部類就能夠像這樣訪問: * * final Node<E> f = first; * return (f == null) ? null : f.item; * */ private static class Node<E> { E item; Node<E> next; Node<E> prev; Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } } public Iterator<E> descendingIterator() { return new DescendingIterator(); } /** * 反向迭代器類 */ private class DescendingIterator implements Iterator<E> { private final ListItr itr = new ListItr(size()); public boolean hasNext() { return itr.hasPrevious(); } public E next() { return itr.previous(); } public void remove() { itr.remove(); } } @SuppressWarnings("unchecked") private LinkedList<E> superClone() { try { return (LinkedList<E>) super.clone(); } catch (CloneNotSupportedException e) { throw new InternalError(); } } /** * 淺拷貝 */ public Object clone() { LinkedList<E> clone = superClone(); // Put clone into "virgin" state clone.first = clone.last = null; clone.size = 0; clone.modCount = 0; // Initialize clone with our elements for (Node<E> x = first; x != null; x = x.next) clone.add(x.item); return clone; } public Object[] toArray() { Object[] result = new Object[size]; int i = 0; for (Node<E> x = first; x != null; x = x.next) result[i++] = x.item; return result; } @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { if (a.length < size) a = (T[])java.lang.reflect.Array.newInstance( a.getClass().getComponentType(), size); int i = 0; Object[] result = a; for (Node<E> x = first; x != null; x = x.next) result[i++] = x.item; if (a.length > size) a[size] = null; return a; } private static final long serialVersionUID = 876323262645176354L; /** * 系列化 */ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { // Write out any hidden serialization magic s.defaultWriteObject(); // Write out size s.writeInt(size); // Write out all elements in the proper order. for (Node<E> x = first; x != null; x = x.next) s.writeObject(x.item); } /** * 反系列化 */ @SuppressWarnings("unchecked") private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in any hidden serialization magic s.defaultReadObject(); // Read in size int size = s.readInt(); // Read in all elements in the proper order. for (int i = 0; i < size; i++) linkLast((E)s.readObject()); } }
import java.util.LinkedList; import java.util.ListIterator; public class LinkedListTest { public static void main(String[] args) { LinkedList<String> list = new LinkedList<String>(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); list.add("e"); //通常咱們不會像下面這樣使用迭代器,不,是絕對不能 //那麼引發ConcurrentModificationException異常 //就多是其餘線程修改了list的數據了 ListIterator<String> iterator = list.listIterator(); if(iterator.hasNext()) System.out.println(iterator.next()); list.add("f");//在迭代過程當中不能使用得到迭代器的實例來修改數據 if(iterator.hasNext()) System.out.println(iterator.next()); } }