(一)jdk原始碼分析之collection,List,Set
前言
標題取得有點大,一口氣分析三塊的原始碼,看上去是個很大的話題,不過在個人看來,一方面,這三個都是介面,不涉及程式碼實現,讀起來比較快,另一方面,大家都知道List,Set這兩個介面都繼承自collection,他們之間存在關聯,所以放在一塊分析討論最能凸顯,這三塊介面的區別和特色。
Collection
public interface Collection<E> extends Iterable<E>{
int size();
boolean isEmpty();
Iterator<E> iterator();
Object[] toArray();
<T> T[] toArray(T[] a);
boolean add(E e);
boolean remove(Object o);
boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E> c);
//方法未列全
}
我們首先看到Collection介面繼承了Iterable,返回迭代器的方法Collection要有。然後對於集合類公有的操作,包括返回一個集合內物件的陣列,新增,刪除元素,檢查指定元素是否存在等方法,也必須要由。
在我的理解中,Collection介面實際上是對java集合類的特性的高度抽象,一個集合類,它至少要擁有對元素,這是所有集合類的共性。而Set和List介面作為Collection介面的繼承,除了Collection本身的東西之外,還必須要有些針對自己型別特化出來的方法。
List
List介面相對於Collection一定要有一些自己的東西,那麼有哪些東西是屬於他自己的呢
public interface List<E> extends Collection<E> {
@SuppressWarnings({"unchecked", "rawtypes"}) //禁止顯示警報的註解 default void sort(Comparator<? super E> c) { Object[] a = this.toArray(); Arrays.sort(a, (Comparator) c); ListIterator<E> i = this.listIterator(); for (Object e : a) { i.next(); i.set((E) e); } }
E get(int index);
E set(int index, E element);
void add(int index, E element);
E remove(int index);
ListIterator<E> listIterator();
ListIterator<E> listIterator(int index);
List<E> subList(int fromIndex, int toIndex);
}
在這裡我們可以看到,List相較於Collection,主要是多了可以根據下標去訪問修改指定元素,以及排序的方法,這裡就凸顯出了List介面和Collection介面的不同之處,作為List,相較於高度抽象的集合類,它的特點是有序的,所以對於List這種集合而言,它應該可以被排序,以及能夠被下標訪問。
還有很有趣的一點,我們發現List介面還要求他的實現能夠返回一種特殊的迭代器listIterator();,這種迭代器有什麼特別的呢。我們去檢視一下listIterator的原始碼。
public interface ListIterator<E> extends Iterator<E> { boolean hasNext(); E next(); boolean hasPrevious(); E previous(); int nextIndex(); int previousIndex(); void remove(); void set(E e); void add(E e); }
這個介面的方法有哪些特別之處呢,我們對比一下Iterator的介面,很快就能夠顯現出來了。
public interface Iterator<E> {
boolean hasNext();
E next();
default void remove() { throw new UnsupportedOperationException("remove"); }
default void forEachRemaining(Consumer<? super E> action) { Objects.requireNonNull(action); while (hasNext()) action.accept(next()); }
}
看來listiterator方法比Iterator還是要多上不少的,主要多了哪些方法呢?我們看到,listiterator不但能通過next()向下訪問,還能夠通過previous向上訪問,也可以再迭代器訪問到的點進行插入,取代,刪除,以及知道自己所迭代到的下標位置。
所以由此我們不難發現,listiterator相較於iterator,還是主要針對List有序這一點添加了一些方法,這個迭代器相較於普通的迭代器功能更加強大,不但可以有序地向上向下遍歷,甚至還可以通過迭代器去操作List本身,可以說是非常牛逼了。
最後,我們發現List還有一個叫subList()的方法,這個方法是幹什麼的呢。閱讀註解後我知道了他會根據你傳入的下標返還List的一個子集,但返還的到底是怎樣的子集肯定還是要看具體實現,在此不談。
Set
終於輪到了Set的原始碼,Set介面和前兩者又有什麼區別呢
public interface Set<E> extends Collection<E> {
int size();
boolean isEmpty();
boolean contains(Object o);
Iterator<E> iterator();
Object[] toArray();
<T> T[] toArray(T[] a);
boolean add(E e);
boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E> c);
boolean retainAll(Collection<?> c);
boolean removeAll(Collection<?> c);
void clear();
boolean equals(Object o);
int hashCode();
}
好像和collection沒啥區別……不過Set本身好像確實和集合,不能出現重複元素的特性應該也是在實現類中,也不存在什麼基於自己特性的新方法,over。