1. 程式人生 > >(一)jdk原始碼分析之collection,List,Set

(一)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。