1 public class ArrayList<E> extends AbstractList<E> 2 implements List<E>, RandomAccess, Cloneable, java.io.Serializable
LinkedList的定義:java
1 public class LinkedList<E> 2 extends AbstractSequentialList<E> 3 implements List<E>, Deque<E>, Cloneable, java.io.Serializable
從定義上能夠看到ArrayList和LinkedList都實現了List接口,ok看下List接口的定義:編程
1 public interface List<E> extends Collection<E> { 2 int size(); 3 boolean isEmpty(); 4 boolean contains(Object o); 5 Iterator<E> iterator(); 6 Object[] toArray(); 7 <T> T[] toArray(T[] a); 8 boolean add(E e); 9 boolean remove(Object o); 10 boolean containsAll(Collection<?> c); 11 boolean addAll(Collection<? extends E> c); 12 boolean addAll( int index, Collection<? extends E> c); 13 boolean removeAll(Collection<?> c); 14 boolean retainAll(Collection<?> c); 15 void clear(); 16 boolean equals(Object o); 17 int hashCode(); 18 E get( int index); 19 E set( int index, E element); 20 void add( int index, E element); 21 E remove( int index); 22 int indexOf(Object o); 23 int lastIndexOf(Object o); 24 ListIterator<E> listIterator(); 25 ListIterator<E> listIterator( int index); 26 List<E> subList( int fromIndex, int toIndex); 27 }
能夠看到List中對容器的各類操做add、remove、set、get、size等進行了統必定義,同時List實現了Collection接口,繼續看下Collection接口的定義(先不關心Iterator):設計模式
1 public interface Collection<E> extends Iterable<E> { 2 int size(); 3 boolean isEmpty(); 4 boolean contains(Object o); 5 Iterator<E> iterator(); 6 Object[] toArray(); 7 <T> T[] toArray(T[] a); 8 boolean add(E e); 9 boolean remove(Object o); 10 boolean containsAll(Collection<?> c); 11 boolean addAll(Collection<? extends E> c); 12 boolean removeAll(Collection<?> c); 13 boolean retainAll(Collection<?> c); 14 void clear(); 15 boolean equals(Object o); 16 int hashCode(); 17 }
有了這兩個接口,對於ArrayList和LinkeList的操做是否是就能夠這麼寫了呢?數組
1 Collection<String> collection = new ArrayList<String>(); 2 collection.add("hello"); 3 collection.add("java"); 4 collection.remove("hello");
對於ArrayList的實現不滿意,ok換成LinkedList實現,數據結構
1 Collection<String> collection = new LinkedList<String>(); 2 collection.add("hello"); 3 collection.add("java"); 4 collection.remove("hello");
對於用戶來講,add、remove等操做是沒有任何影響的,好了,到這裏瞭解了統一接口,面向接口編程的好處,接下來在思考另一個問題,怎麼給容器提供一種遍歷方式。多線程
1 /** Implementing this interface allows an object to be the target of 2 * the "foreach" statement. 3 * @since 1.5 4 */ 5 public interface Iterable<T> { 6 7 /** 8 * Returns an iterator over a set of elements of type T. 9 * 10 * @return an Iterator. 11 */ 12 Iterator<T> iterator(); 13 }
英文註釋說,實現iterable接口的類可使用「foreach」操做,而後並要求實現Iterator<T> iterator()方法,該方法返回一個Iterator接口對象,來看下Iterator接口,dom
1 public interface Iterator<E> { 2 // 是否還有元素 3 boolean hasNext(); 4 // 下一個元素 5 E next(); 6 // 將迭代器返回的元素刪除 7 void remove(); 8 }
Iterator接口一共有三個方法,經過這三個方法就能夠實現通用遍歷了,ok,咱們來試一下。ide
1 Collection<String> collection = new ArrayList<String>(); 2 collection.add("hello"); 3 collection.add("java"); 4 5 Iterator<String> iterator = collection.iterator(); 6 while (iterator.hasNext()) { 7 System. out.println(iterator.next()); 8 }
1 public interface MyIterator { 2 Object next(); 3 boolean hasNext(); 4 }
容器統一接口:學習
1 public interface MyCollection { 2 void add(Object o); 3 int size(); 4 MyIterator iterator(); 5 }
容器實現類和Iterator實現類(Iterator實現類爲容器內部類):this
1 public class MyArrayList implements MyCollection { 2 3 private Object[] data ; 4 private int size; 5 6 public MyArrayList() { 7 data = new Object[10]; 8 } 9 10 public void add(Object o) { 11 if (size == data. length) { 12 Object[] newData = new Object[data .length * 2]; 13 System. arraycopy(data, 0, newData, 0, data.length ); 14 data = newData; 15 } 16 data[size ] = o; 17 size++; 18 } 19 20 public int size() { 21 return size ; 22 } 23 24 @Override 25 public MyIterator iterator() { 26 return new Itr(); 27 } 28 29 private class Itr implements MyIterator { 30 private int index = 0; 31 32 @Override 33 public boolean hasNext() { 34 if (index >= size) { 35 return false; 36 } else { 37 return true; 38 } 39 } 40 41 @Override 42 public Object next() { 43 Object o = data[index ]; 44 index++; 45 return o; 46 } 47 48 } 49 }
應用一下:
1 public class Test { 2 3 public static void main(String[] args) { 4 MyCollection c = new MyArrayList(); 5 c.add( "t"); 6 c.add( "s"); 7 c.add( "t"); 8 c.add( "d"); 9 10 System. out.println(c.size()); 11 12 MyIterator itr = c.iterator(); 13 while (itr.hasNext()) { 14 System. out.println(itr.next()); 15 } 16 } 17 18 }
看看結果:
4
t
s
t
d
沒問題,很容易就實現了對不對,固然這裏只是簡單模擬,沒有過多的追求效率和優雅的設計。
1 public Iterator<E> iterator() { 2 return new Itr(); 3 }
和本身實現的同樣,採用內部類實現 Iterator接口。
1 private class Itr implements Iterator<E> { 2 // 將要next返回元素的索引 3 int cursor = 0; 4 // 當前返回的元素的索引,初始值-1 5 int lastRet = -1; 6 7 /** 8 * The modCount value that the iterator believes that the backing 9 * List should have. If this expectation is violated, the iterator 10 * has detected concurrent modification. 11 */ 12 int expectedModCount = modCount; 13 14 public boolean hasNext() { 15 // 因爲cursor是將要返回元素的索引,也就是下一個元素的索引,和size比較是否相等,也就是判斷是否已經next到最後一個元素 16 return cursor != size(); 17 } 18 19 public E next() { 20 checkForComodification(); 21 try { 22 // 根據下一個元素索引取出對應元素 23 E next = get( cursor); 24 // 更新lastRet爲當前元素的索引,cursor加1 25 lastRet = cursor ++; 26 // 返回元素 27 return next; 28 } catch (IndexOutOfBoundsException e) { 29 checkForComodification(); 30 throw new NoSuchElementException(); 31 } 32 } 33 34 public void remove() { 35 // remove前必須先next一下,先取得當前元素 36 if (lastRet == -1) 37 throw new IllegalStateException(); 38 checkForComodification(); 39 40 try { 41 AbstractList. this.remove(lastRet ); 42 // 確保lastRet比cursor小、理論上永遠lastRet比cursor小1 43 if (lastRet < cursor) 44 // 因爲刪除了一個元素cursor回退1 45 cursor--; 46 // 重置爲-1 47 lastRet = -1; 48 expectedModCount = modCount ; 49 } catch (IndexOutOfBoundsException e) { 50 throw new ConcurrentModificationException(); 51 } 52 } 53 54 final void checkForComodification() { 55 if (modCount != expectedModCount) 56 throw new ConcurrentModificationException(); 57 } 58 }
1 public Iterator<E> iterator() { 2 return listIterator(); 3 }
AbstractList的實現:
1 public ListIterator<E> listIterator() { 2 return listIterator(0); 3 } 4 public ListIterator<E> listIterator(final int index) { 5 if (index<0 || index>size()) 6 throw new IndexOutOfBoundsException( "Index: "+index); 7 8 return new ListItr(index); 9 }
看一下ListItr實現:
1 private class ListItr implements ListIterator<E> { 2 // 最後一次返回的節點,默認位header節點 3 private Entry<E> lastReturned = header; 4 // 將要返回的節點 5 private Entry<E> next ; 6 // 將要返回的節點index索引 7 private int nextIndex; 8 private int expectedModCount = modCount; 9 10 ListItr( int index) { 11 // 索引越界檢查 12 if (index < 0 || index > size) 13 throw new IndexOutOfBoundsException( "Index: "+index+ 14 ", Size: "+size ); 15 // 簡單二分,判斷遍歷的方向 16 if (index < (size >> 1)) { 17 // 取得index位置對應的節點 18 next = header .next; 19 for (nextIndex =0; nextIndex<index; nextIndex++) 20 next = next .next; 21 } else { 22 next = header ; 23 for (nextIndex =size; nextIndex>index; nextIndex --) 24 next = next .previous; 25 } 26 } 27 28 public boolean hasNext() { 29 // 根據下一個節點index是否等於size,判斷是否有下一個節點 30 return nextIndex != size; 31 } 32 33 public E next() { 34 checkForComodification(); 35 // 遍歷完成 36 if (nextIndex == size) 37 throw new NoSuchElementException(); 38 39 // 賦值最近一次返回的節點 40 lastReturned = next ; 41 // 賦值下一次要返回的節點(next後移) 42 next = next .next; 43 // 將要返回的節點index索引+1 44 nextIndex++; 45 return lastReturned .element; 46 } 47 48 public boolean hasPrevious() { 49 return nextIndex != 0; 50 } 51 52 // 返回上一個節點(雙向循環鏈表嘛、能夠兩個方向遍歷) 53 public E previous() { 54 if (nextIndex == 0) 55 throw new NoSuchElementException(); 56 57 lastReturned = next = next. previous; 58 nextIndex--; 59 checkForComodification(); 60 return lastReturned .element; 61 } 62 63 public int nextIndex() { 64 return nextIndex ; 65 } 66 67 public int previousIndex() { 68 return nextIndex -1; 69 } 70 71 public void remove() { 72 checkForComodification(); 73 // 取出當前返回節點的下一個節點 74 Entry<E> lastNext = lastReturned.next ; 75 try { 76 LinkedList. this.remove(lastReturned ); 77 } catch (NoSuchElementException e) { 78 throw new IllegalStateException(); 79 } 80 // 確認下次要返回的節點不是當前節點,若是是則修正 81 if (next ==lastReturned) 82 next = lastNext; 83 else 84 // 因爲刪除了一個節點,下次要返回的節點索引-1 85 nextIndex--; 86 // 重置lastReturned爲header節點 87 lastReturned = header ; 88 expectedModCount++; 89 } 90 91 public void set(E e) { 92 if (lastReturned == header) 93 throw new IllegalStateException(); 94 checkForComodification(); 95 lastReturned.element = e; 96 } 97 98 public void add(E e) { 99 checkForComodification(); 100 lastReturned = header ; 101 addBefore(e, next); 102 nextIndex++; 103 expectedModCount++; 104 } 105 106 final void checkForComodification() { 107 if (modCount != expectedModCount) 108 throw new ConcurrentModificationException(); 109 } 110 }