來源於網上(感謝大佬的製做)java
容器,就是能夠容納其餘Java對象的對象,在正式進入容器以前,咱們先來看幾個接口的定義,後學的方法會用到。git
須要注意的是,Collection繼承的是Iterable<T>
,Collection中有個iterator()方法,它的做用是返回一個Iterator接口。一般,咱們經過Iterator迭代器來遍歷集合。ListIterator是List接口所特有的,在List接口中,經過ListIterator()返回一個ListIterator對象。github
Implementing this interface allows an object to be the target of the "foreach" statement
最爲關鍵那,實現此接口的均可以用 foreach
進行遍歷,爲啥啊。爲了偷懶啊,foreeach底層使用了迭代器。數組
重點須要注意的是Iterable<T>
這個泛型,用處很是很是大。能夠迭代任何類型的對象,泛型是JDK5提出的一個"語法糖",編譯後會擦除。關於這裏的知識點後續在研究。安全
我的感受泛型 + 反射,能力大過天。要在加一點那就是內部類。架構
import java.util.Iterator; /** * Implementing this interface allows an object to be the target of * the "foreach" statement. */ public interface Iterable<T> { /** * Returns an iterator over a set of elements of type T.. */ Iterator<T> iterator(); }
/** * An iterator over a collection. {@code Iterator} takes the place of * {@link Enumeration} in the Java Collections Framework. */ public interface Iterator<E> { /** * Returns {@code true} if the iteration has more elements. */ boolean hasNext(); /** * Returns the next element in the iteration. */ E next(); /** * Removes from the underlying collection the last element returned * by this iterator (optional operation). */ void remove(); }
/** * An iterator for lists that allows the programmer * to traverse the list in either direction, modify * the list during iteration, and obtain the iterator's * current position in the list. */ public interface ListIterator<E> extends Iterator<E> { // Query Operations /** * Returns {@code true} if this list iterator has more elements when * traversing the list in the forward direction. */ boolean hasNext(); /** * Returns the next element in the list and advances the cursor position. */ E next(); /** * Returns {@code true} if this list iterator has more elements when * traversing the list in the reverse direction. (In other words, * returns {@code true} if {@link #previous} would return an element * rather than throwing an exception.) */ boolean hasPrevious(); /** * Returns the previous element in the list and moves the cursor * position backwards. This method may be called repeatedly to * iterate through the list backwards, or intermixed with calls to * {@link #next} to go back and forth. */ E previous(); /** * Returns the index of the element that would be returned by a * subsequent call to {@link #next}. (Returns list size if the list * iterator is at the end of the list.) */ int nextIndex(); /** * Returns the index of the element that would be returned by a * subsequent call to {@link #previous}. */ int previousIndex(); /** * Removes from the list the last element that was returned by {@link * #next} or {@link #previous} (optional operation). */ void remove(); /** * Replaces the last element returned by {@link #next} or * {@link #previous} with the specified element (optional operation). */ void set(E e); /** * Inserts the specified element into the list (optional operation). */ void add(E e); }
接下來,咱們正式進入主題吧,有些英文不會解釋。app
首先看看Collection中具體有哪些方法。less
Josh Bloch
這位大佬曾是Google的首席架構師,他的Twitter。dom
9行代碼,索賠超過10億美金,那麼每一行代碼價值一億多美金,這也一度被外界解讀爲史上最昂貴的代碼之一。ide
想知道在哪裏嗎?上次咱們分析了數組檢查是否越界
/** * Checks that {@code fromIndex} and {@code toIndex} are in * the range and throws an exception if they aren't. */ private static void rangeCheck(int arrayLength, int fromIndex, int toIndex) { if (fromIndex > toIndex) { throw new IllegalArgumentException( "fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")"); } if (fromIndex < 0) { throw new ArrayIndexOutOfBoundsException(fromIndex); } if (toIndex > arrayLength) { throw new ArrayIndexOutOfBoundsException(toIndex); } }
注意這裏使用了泛型,具體的在實現類中,在這裏只是定義了一些通用的方法,在抽象類中類中實現。凡是繼承此接口的均可以用。最好的設計理念是中間加入了AbstractCollection
,爲啥要這麼設計呢?由於抽象類天生就是用來被繼承的,你要是實現接口,你必須實現全部的方法,JDK8中加入了默認方法,來看圖。
來源於網上(感謝大佬的製做)
在來看看在IDEA中的結構圖,
public class ArrayList<E> extends AbstractList<E implements List<E>{..}
這樣設計的主要目的是方便擴展,接下來,咱們簡單看看AbstractCollection
是怎麼實現的
/** * The root interface in the <i>collection hierarchy</i>. A collection * represents a group of objects, known as its <i>elements</i>. Some * collections allow duplicate elements and others do not. Some are ordered * and others unordered. The JDK does not provide any <i>direct</i> * implementations of this interface: it provides implementations of more * specific subinterfaces like <tt>Set</tt> and <tt>List</tt>. This interface is typically used to pass collections around and manipulate them where maximum generality is desired. * * * @param <E> the type of elements in this collection //注意泛型 * * @author Josh Bloch * @author Neal Gafter * @since 1.2 */ public interface Collection<E> extends Iterable<E> { // Query Operations /** * Returns the number of elements in this collection. */ int size(); /** * Returns <tt>true</tt> if this collection contains no elements. */ boolean isEmpty(); /** * Returns <tt>true</tt> if this collection contains the specified element. */ boolean contains(Object o); /** * Returns an iterator over the elements in this collection. There are no * guarantees concerning the order in which the elements are returned * (unless this collection is an instance of some class that provides a * guarantee). * * @return an <tt>Iterator</tt> over the elements in this collection */ Iterator<E> iterator(); /** * Returns an array containing all of the elements in this collection. * If this collection makes any guarantees as to what order its elements * are returned by its iterator, this method must return the elements in * the same order. */ Object[] toArray(); // Modification Operations /** * Ensures that this collection contains the specified element (optional * operation). Returns <tt>true</tt> if this collection changed as a * result of the call. */ boolean add(E e); /** * Removes a single instance of the specified element from this * collection, if it is present (optional operation). */ boolean remove(Object o); // Bulk Operations /** * Returns <tt>true</tt> if this collection contains all of the elements * in the specified collection. */ boolean containsAll(Collection<?> c); /** * Adds all of the elements in the specified collection to this collection * (optional operation). The behavior of this operation is undefined if * the specified collection is modified while the operation is in progress. */ boolean addAll(Collection<? extends E> c); /** * Removes all of this collection's elements that are also contained in the * specified collection (optional operation). After this call returns, * this collection will contain no elements in common with the specified * collection. */ boolean removeAll(Collection<?> c); /** * Retains only the elements in this collection that are contained in the * specified collection (optional operation). */ boolean retainAll(Collection<?> c); /** * Removes all of the elements from this collection (optional operation). * The collection will be empty after this method returns. */ void clear(); /** * Compares the specified object with this collection for equality. <p> */ boolean equals(Object o); /** * Returns the hash code value for this collection. */ int hashCode(); }
to minimize the effort required to implement this interface
這裏解釋了緣由
** * This class provides a skeletal implementation of the <tt>Collection</tt> * interface, to minimize the effort required to implement this interface. <p> */ public abstract class AbstractCollection<E> implements Collection<E> { /** * Sole constructor. (For invocation by subclass constructors, typically * implicit.) */ protected AbstractCollection() { } // Query Operations /** * Returns an iterator over the elements contained in this collection */ public abstract Iterator<E> iterator(); public abstract int size(); --------------------------------------------------------------------------------- /** * <p>This implementation returns <tt>size() == 0</tt>. */ public boolean isEmpty() { return size() == 0; } /** * <p>This implementation iterates over the elements in the collection, * checking each element in turn for equality with the specified element. */ public boolean contains(Object o) { Iterator<E> it = iterator(); //使用迭代器進行遍歷選擇 if (o==null) { while (it.hasNext()) if (it.next()==null) //注意null return true; } else { while (it.hasNext()) if (o.equals(it.next())) //調用o。qualse()方法。 return true; } return false; //木有,不含夠 //大致思路就是首先判斷傳進來的是否爲null,是否還有還一個,下一個等於null,成爲返回true。 //傳進來o不等於null,是否還有還一個,下一個等於null,成爲返回true。 } --------------------------------------------------------------------------------- /** * {@inheritDoc} * * <p>This implementation returns an array containing all the elements * returned by this collection's iterator, in the same order, stored in * consecutive elements of the array, starting with index {@code 0}. * <p>This method is equivalent to: * //方法等同於下面這個, * <pre> {@code * List<E> list = new ArrayList<E>(size()); * for (E e : this) * list.add(e); * return list.toArray(); * }</pre> */ public Object[] toArray() { // Estimate size of array; be prepared to see more or fewer elements Object[] r = new Object[size()]; Iterator<E> it = iterator(); for (int i = 0; i < r.length; i++) { if (! it.hasNext()) // fewer elements than expected return Arrays.copyOf(r, i); //這裏使用了Arrays.copyOf(),以前講過,此時返回一個空數組 r[i] = it.next(); //取出下一個放到r[i]中,如if中有一條語句老外通常不用{} } return it.hasNext() ? finishToArray(r, it) : r; //尚未的元素的話就完成ToArary。 } ------------------------------------------------------------------------------------------ /** *處於安全性考慮,Collections提供了大量額外的非功能性方法,其中之一即是生成原Collection的不可修改視圖。 *即返回的Collection和原Collection在元素上保持一致,但不可修改。 *該實現主要是經過重寫add,remove等方法來實現的。即在可能修改的方法中直接拋出異常。 * <p>This implementation always throws an * <tt>UnsupportedOperationException</tt>. * * @throws UnsupportedOperationException {@inheritDoc} * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} * @throws IllegalStateException {@inheritDoc} */ public boolean add(E e) { throw new UnsupportedOperationException(); } /** * <p>This implementation iterates over the collection looking for the * specified element. */ public boolean remove(Object o) { Iterator<E> it = iterator(); if (o==null) { while (it.hasNext()) { if (it.next()==null) { it.remove(); //和上面contains邏輯差很少 return true; //這裏調用迭代器的remove方法移除 } } } else { while (it.hasNext()) { if (o.equals(it.next())) { it.remove(); //同理 return true; } } } return false; } ------------------------------------------------------------------------------------- // Bulk Operations /** * <p>This implementation iterates over the specified collection, * checking each element returned by the iterator in turn to see * if it's contained in this collection. */ public boolean containsAll(Collection<?> c) { for (Object e : c) if (!contains(e)) //這裏循環遍歷,只要一個不包含則fasle。 return false; return true; } /** * <p>This implementation iterates over the specified collection, and adds * each object returned by the iterator to this collection, in turn. */ public boolean addAll(Collection<? extends E> c) { boolean modified = false; //使用一個標記 for (E e : c) //這裏沒用大括號是否是簡潔多了? if (add(e)) //循環添加,若是爲真,修改modified,返回 modified = true; return modified; } /** * <p>This implementation iterates over this collection, checking each * element returned by the iterator in turn to see if it's contained * in the specified collection. */ public boolean removeAll(Collection<?> c) { boolean modified = false; //修改標記 Iterator<?> it = iterator(); //使用迭代, while (it.hasNext()) { //判斷是否還有下一個, if (c.contains(it.next())) { //有才能刪除,沒有刪除毛線 it.remove(); modified = true; //刪除以後修改標記, } } return modified; } --------------------------------------------------------------------------- /** * <p>This implementation iterates over this collection, removing each * element using the <tt>Iterator.remove</tt> operation. Most * implementations will probably choose to override this method for * efficiency. */ public void clear() { Iterator<E> it = iterator(); while (it.hasNext()) { it.next(); it.remove(); } } ------------------------------------------------------------------------------- // String conversion /** * Returns a string representation of this collection. The string * representation consists of a list of the collection's elements in the * order they are returned by its iterator, enclosed in square brackets * (<tt>"[]"</tt>). * @return a string representation of this collection */ public String toString() { Iterator<E> it = iterator(); if (! it.hasNext()) //沒有下一個直接返回"[]",熟悉吧? return "[]"; StringBuilder sb = new StringBuilder(); 這裏使用了StringBuilder追加形式, sb.append('['); for (;;) { //能夠這樣寫嗎? E e = it.next(); sb.append(e == this ? "(this Collection)" : e); if (! it.hasNext()) return sb.append(']').toString(); //這裏判斷是否沒有元素來。 sb.append(',').append(' '); //[1,2,3,4,5] } }
其實不少類中的方法差很少,只是邏輯上有細微的變化。看人家的代碼,再看看咱們本身寫的代碼。
加油吧,但願本身也能夠寫出這樣的代碼。gogogo。
接下來咱們在看看List中特有的方法,具體的實如今AbstrctList中。和上面重複的就不在多介紹了
摘抄以前的一些筆記
選擇List的具體實現:
-
List接口:1,有序的,2.容許有多個null元素,三、具體的實現類經常使用的有:ArrayList,Vector,LinkedList
List接口特有的方法,帶有索引的功能
also known as a sequence
一般第一段是重點
/** * An ordered collection (also known as a <i>sequence</i>). The user of this * interface has precise control over where in the list each element is * inserted. The user can access elements by their integer index (position in * the list), and search for elements in the list.<p> * @author Josh Bloch */ public interface List<E> extends Collection<E> { //省略Collection中的方法 // Positional Access Operations //位置訪問操做 /** * Returns the element at the specified position in this list. 返回指定位置上的元素 */ E get(int index); /** * Replaces the element at the specified position in this list with the * specified element (optional operation). */ E set(int index, E element); /** * Inserts the specified element at the specified position in this list * (optional operation). Shifts the element currently at that position * (if any) and any subsequent elements to the right (adds one to their * indices). */ void add(int index, E element); /** * Removes the element at the specified position in this list (optional * operation). Shifts any subsequent elements to the left (subtracts one * from their indices). Returns the element that was removed from the * list. */ E remove(int index); // Search Operations //查詢操做 /** * Returns the index of the first occurrence of the specified element * in this list, or -1 if this list does not contain the element. *第一次出現的位置,不存在-1 */ int indexOf(Object o); /** * Returns the index of the last occurrence of the specified element * in this list, or -1 if this list does not contain the element. *最後出現的索引位置,不存在則返回-1 */ int lastIndexOf(Object o); // List Iterators /** * Returns a list iterator over the elements in this list (in proper * sequence). */ ListIterator<E> listIterator(); /** * Returns a list iterator over the elements in this list (in proper * sequence), starting at the specified position in the list. * 指定開始的索引 */ ListIterator<E> listIterator(int index); // View /** * Returns a view of the portion of this list between the specified * <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive. * 返回子List的視圖,可能會拋出索引越界異常,須要檢查。也就是用那九行代碼。 */ List<E> subList(int fromIndex, int toIndex); }
接下來咱們看看這個具體的實現,重複的忽略。這個也是重點,
注意注意的是:
一、LinkedList是繼承AbstractSequentialList
的而後他在繼承AbstractList。爲啥要這樣設計?留點疑問,待會到LinkdedList的時候講。注意必定看認真看類名。
二、鎖住的是內部類,在Collections中定義的,@return an immutable list containing only the specified object
/** * Returns an immutable list containing only the specified object. * The returned list is serializable. */ public static <T> List<T> singletonList(T o) { return new SingletonList<>(o); } ---------------------------------------------------------------------------------- private static class SingletonList<E> extends AbstractList<E> implements RandomAccess, Serializable { public int size() {return 1;} //直接給你返回1,你服不服? public E get(int index) { if (index != 0) //只要索引不爲0就給你拋個異常, throw new IndexOutOfBoundsException("Index: "+index+", Size: 1"); return element; } } --------------------------------回顧--------------------------------------------- public static final List EMPTY_LIST = new EmptyList<>(); /** * Returns the empty list (immutable). */ @SuppressWarnings("unchecked") public static final <T> List<T> emptyList() { return (List<T>) EMPTY_LIST; } -------------------------------------------------------------------------------- /** * Returns a fixed-size list backed by the specified array. */ public static <T> List<T> asList(T... a) { return new ArrayList<>(a); } private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable { public int size() { return a.length; } public E get(int index) { return a[index]; } }
三、ArrayLIst接下來就是咱們的真正主題了,
四、注意Vector也是實現AbstractList的(List),他有個子類是Stack
由於是同步的,線程安全的。全部效率比較低。
import java.util.LinkedList; public class Stack<T> { private LinkedList<T> storage = new LinkedList<T>(); public void push(T v) { storage.addFirst(v); } public T peek() { return storage.getFirst(); } public T pop() { return storage.removeFirst(); } public boolean empty() { return storage.isEmpty(); } public String toString() { return storage.toString(); } }
//對方法添加了synchronized以保證線程安全,讀多寫少的情景下建議使用CopyOnWriteArrayList public class Vector<E>extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{}
以上Vector類不過多介紹,Stack能夠先看看, last-in-first-out
/** * The <code>Stack</code> class represents a last-in-first-out * (LIFO) stack of objects. It extends class <tt>Vector</tt> with five * */ publicclass Stack<E> extends Vector<E> { ...}
首先須要注意的是它繼承自AbstractCollection
具有了它裏面的全部方法,本身又額外添加了一些索引方法的
package java.util; /** * This class provides a skeletal implementation of the {@link List} * interface to minimize the effort required to implement this interface * backed by a "random access" data store (such as an array). For sequential * access data (such as a linked list), {@link AbstractSequentialList} should * be used in preference to this class. */ public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> { // Search Operations /** * <p>This implementation first gets a list iterator (with * {@code listIterator()}). Then, it iterates over the list until the * specified element is found or the end of the list is reached. */ public int indexOf(Object o) { ListIterator<E> it = listIterator(); //注意調用的是ListIterator if (o==null) { while (it.hasNext()) if (it.next()==null) return it.previousIndex(); //這裏返回的是上一個索引位置的。 } else { while (it.hasNext()) if (o.equals(it.next())) return it.previousIndex(); } return -1; } /** * <p>This implementation first gets a list iterator that points to the end * of the list (with {@code listIterator(size())}). */ public int lastIndexOf(Object o) { ListIterator<E> it = listIterator(size()); if (o==null) { while (it.hasPrevious()) if (it.previous()==null) return it.nextIndex(); //返回下一個位置的索引 } else { while (it.hasPrevious()) if (o.equals(it.previous())) return it.nextIndex(); } return -1; } // Bulk Operations /** * Removes all of the elements from this list (optional operation). * The list will be empty after this call returns. */ public void clear() { removeRange(0, size()); } ------------------------------------------------------------------------------- /** * Removes from this list all of the elements whose index is between * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive. * Shifts any succeeding elements to the left (reduces their index). */ protected void removeRange(int fromIndex, int toIndex) { ListIterator<E> it = listIterator(fromIndex); for (int i=0, n=toIndex-fromIndex; i<n; i++) { it.next(); it.remove(); } } ----------------------------------------------------------------------------- /** * {@inheritDoc} * * <p>This implementation gets an iterator over the specified collection * and iterates over it, inserting the elements obtained from the * iterator into this list at the appropriate position, one at a time, * using {@code add(int, E)}. */ public boolean addAll(int index, Collection<? extends E> c) { rangeCheckForAdd(index); //檢查範圍 boolean modified = false; for (E e : c) { add(index++, e); //循環進行添加, modified = true; //完成以後修改標記 } return modified; } -------------------------------------------------------------------------------- /** * The number of times this list has been <i>structurally modified</i>. * Structural modifications are those that change the size of the * list, or otherwise perturb it in such a fashion that iterations in * progress may yield incorrect results. */ protected transient int modCount = 0; private void rangeCheckForAdd(int index) { if (index < 0 || index > size()) //拋出越界異常, throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } // Comparison and hashing 比較與哈希。 /** * Compares the specified object with this list for equality. Returns * {@code true} if and only if the specified object is also a list, both * lists have the same size, and all corresponding pairs of elements in * the two lists are <i>equal</i>. */ public boolean equals(Object o) { if (o == this) //1.判斷是不是當前對象 return true; if (!(o instanceof List)) //二、是List的實例嗎? return false; ListIterator<E> e1 = listIterator(); ListIterator e2 = ((List) o).listIterator(); while (e1.hasNext() && e2.hasNext()) { //兩個都不能爲空, E o1 = e1.next(); Object o2 = e2.next(); if (!(o1==null ? o2==null : o1.equals(o2))) //這裏使用了三目運算, return false; } return !(e1.hasNext() || e2.hasNext()); } /** * Returns the hash code value for this list. */ public int hashCode() { int hashCode = 1; for (E e : this) hashCode = 31*hashCode + (e==null ? 0 : e.hashCode()); //31是素數 return hashCode; }
-------------------------以前講過了設計的很精妙------------------------------------ // Iterators /** * Returns an iterator over the elements in this list in proper sequence. */ public Iterator<E> iterator() { //3 return new Itr(); } /** * <p>This implementation returns {@code listIterator(0)}. */ public ListIterator<E> listIterator() { return listIterator(0); // 1 } public ListIterator<E> listIterator(final int index) { //2 return new ListItr(index); } ------------------------------------------------------------------------------- private class Itr implements Iterator<E> { //注意這裏,實現 //4 public boolean hasNext() {..} public E next() {..} public void remove() {..} } --------------------------------------------------------------------------------- private class ListItr extends Itr implements ListIterator<E> { //這裏繼承又實現。 ListItr(int index) { cursor = index; } public boolean hasPrevious() { return cursor != 0; } public E previous() {...} public int nextIndex() { return cursor; } public int previousIndex() { return cursor-1; } public void set(E e) {... } public void add(E e) {...} }
先到這裏吧,下一個主題具體到ArrayList和LinkdedList。gogogo。