吃透Java集合系列二:Collection與其子接口

文章首發(fā)博客地址:https://blog.csdn.net/u013277209?viewmode=contents

前言

本篇文章作為吃透Java集合系列第二篇文章椎组,主要探討Collection接口及其子接口List乎串、Set、Queue旺上。通過本篇文章我們需要明白如下幾個問題:
1、Collection的作用糖埋?
2宣吱、List、Set瞳别、Queue接口對Collection接口做了哪些擴(kuò)展征候,各自有什么特點(diǎn)杭攻?

一:Collection接口

Collection接口是集合層次的根接口,定義了集合的通用操作疤坝,所有集合都是在Collection基礎(chǔ)上進(jìn)行擴(kuò)展的兆解。
先看一下Collection的源碼:

/**
 * 集合層次結(jié)構(gòu)中的根接口。一個集合代表一組對象卒煞,被稱為元素痪宰。
 * 一些集合允許重復(fù)的元素,而有些則不允許畔裕。一些是有序的衣撬,另一些是無序的。
 * JDK沒有提供這個接口的任何直接的實(shí)現(xiàn):它提供更具體的子接口像 Set和 List實(shí)現(xiàn)扮饶。
 * 
 * 所有通用的Collection實(shí)現(xiàn)類(通常通過其子接口間接實(shí)現(xiàn)Collection)應(yīng)該提供兩個“標(biāo)準(zhǔn)”構(gòu)造函數(shù):
 * void(無參數(shù)) 構(gòu)造函數(shù)具练,它創(chuàng)建一個空集合,以及一個帶有Collection類型的單個參數(shù)的構(gòu)造函數(shù)甜无,
 * 它創(chuàng)建一個與它的參數(shù)具有相同元素的新集合扛点。實(shí)際上,后者的構(gòu)造函數(shù)允許用戶復(fù)制任何集合岂丘,生成所需實(shí)現(xiàn)類型的等效集合陵究。
 * 沒有辦法強(qiáng)制執(zhí)行這個約定(因?yàn)榻涌诓荒馨瑯?gòu)造函數(shù)),但是Java平臺庫中的所有通用Collection實(shí)現(xiàn)都符合奥帘。
 * 
 * 如果這個集合不支持某個操作的話铜邮,調(diào)用這些方法可能(但不是必需)拋出 UnsupportedOperationException 
 */

public interface Collection<E> extends Iterable<E> {

    /**
    * 此方法成功完成后,可確保對象包含在集合中寨蹋。
    * 如果集合被修改松蒜,則返回true,如果沒有更改已旧,則返回false秸苗。
    */
    boolean add(E e)

    /**
    * 將指定集合中的所有元素添加到這個集合
    */
    boolean addAll(Collection<? extends E> c)

    /**
    * 從這個集合中移除指定元素的一個實(shí)例
    */
    boolean remove(Object o)

    /**
    * 刪除此集合中包含的所有元素的所有元素。
    */
    boolean removeAll(Collection<?> c)
    
    /**
    * 刪除滿足給定謂詞的這個集合的所有元素运褪。
    */
    default boolean removeIf(Predicate<? super E> filter) {
        Objects.requireNonNull(filter);
        boolean removed = false;
        final Iterator<E> each = iterator();
        while (each.hasNext()) {
            if (filter.test(each.next())) {
                each.remove();
                removed = true;
            }
        }
        return removed;
    }

    /**
    * 從這個集合中移除所有不包含在指定集合中的元素的所有元素惊楼。
    */
    boolean retainAll(Collection<?> c)
    
    /**
    * 從這個集合中移除所有的元素
    */
    void clear()

    /**
    * 返回此集合中的元素的數(shù)目。如果這個集合包含多 Integer.MAX_VALUE元素,返回 Integer.MAX_VALUE。
    */
    int size();
    
    /**
    * 如果此Collection不包含元素衅枫,則返回true
    */
    boolean isEmpty()
   
    /**
    * 如果集合包含指定元素,返回 true攀芯。
    */
    boolean contains(Object o)

    /**
    * 返回 true如果這個集合包含指定集合的所有元素。
    */
    boolean containsAll(Collection<?> c)
    
    /**
    * 返回一個包含此集合中包含的所有元素的新數(shù)組文虏。
    * 如果實(shí)現(xiàn)已經(jīng)排序了元素侣诺,它將以與迭代器返回的順序相同的順序返回元素?cái)?shù)組殖演。
    * 返回的數(shù)組不反映集合的任何更改。 即使底層數(shù)據(jù)結(jié)構(gòu)已經(jīng)是一個數(shù)組年鸳,也創(chuàng)建一個新數(shù)組趴久。
    */
    Object[] toArray()
    
    /**
    * 返回包含此集合中包含的所有元素的數(shù)組。 如果指定的數(shù)組足夠大以容納元素搔确,則使用指定的數(shù)組
    * 否則將創(chuàng)建相同類型的數(shù)組彼棍。 如果使用指定的數(shù)組并且大于此集合,則Collection元素之后的數(shù)組元素將設(shè)置為null膳算。
    */
    <T> T[] toArray(T[] a)
   
    /**
    * 重寫Object中的equals方法
    */
    boolean equals(Object o)
    
    /**
    * 重寫Object中的hashCode方法
    */
    int hashCode()
    
    /**
    * 返回可用于訪問此Collection所包含的對象的Iterator實(shí)例座硕。 沒有定義迭代器返回元素的順序。
    * 只有當(dāng)Collection的實(shí)例具有定義的順序時涕蜂,才能按照該順序返回元素华匾。
    */
    Iterator<E> iterator()
    
    /**
    * 返回一個并行迭代器類Spliterator
    */
    default Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, 0);
    }
    
    /**
    * 這個集合中的元素的順序 Stream
    */
    default Stream<E> stream() {
        return StreamSupport.stream(spliterator(), false);
    }
    
    /**
    * 返回一個可能并行 Stream與集合的來源。
    */
    default Stream<E> parallelStream() {
        return StreamSupport.stream(spliterator(), true);
    }
  • Collection接口是Java語言中最基本的集合接口机隙,在JDK中沒有直接提供Collection接口的具體實(shí)現(xiàn)類蜘拉,Collection的功能實(shí)現(xiàn)類主要是對它的三個更具體的子接口List、Set和Queue的具體實(shí)現(xiàn)類有鹿。但是在Collection接口中定義了一套通用操作的實(shí)現(xiàn)方法和命名規(guī)則旭旭。
  • List、Set葱跋、Queue接口都繼承自Collection并定義了各自不同的方法對其擴(kuò)展持寄。

二:List接口

List接口擴(kuò)展了Collection,可以根據(jù)下標(biāo)index對元素進(jìn)行操作年局,每個元素都有唯一一個下標(biāo)對應(yīng)。
添加了功能更強(qiáng)大的ListIterator迭代器咸产,可以沿任一方向遍歷List矢否,并且在遍歷期間還可以修改List

/** 
 * List是維護(hù)其元素的排序的集合。 List中的每個元素都有一個索引脑溢。 因此僵朗,每個元素可以被其索引訪問,第一個索引為零屑彻。 
 * 通常验庙,與集合相比,List允許重復(fù)元素社牲,其中元素必須是唯一的粪薛。
 * 有序集合(也稱為<i>序列</ i>)。 該接口的用戶可以精確控制每個元素插入到列表中的哪個位置搏恤。 
 * 用戶可以通過整數(shù)索引(列表中的位置)訪問元素违寿,并搜索列表中的元素湃交。
 * 
 * 列表允許重復(fù)元素,也允許null元素插入
 */  
public interface List<E> extends Collection<E> {  
    /**
     * List作為Collection的子接口提供了Collection接口定義的方法 
     * 這些方法在Collection源碼中已經(jīng)分析過了藤巢,就不在說明了 
     */  
    //增
    boolean add(E e); 
    boolean addAll(Collection<? extends E> c); 
    //刪
    boolean remove(Object o); 
    boolean removeAll(Collection<?> c);
    boolean retainAll(Collection<?> c);
    default boolean removeIf(Predicate<? super E> filter)  
    void clear(); 
    //查
    int size();  
    boolean isEmpty();
    boolean contains(Object o);
    boolean containsAll(Collection<?> c);
    //轉(zhuǎn)數(shù)組
    Object[] toArray();  
    <T> T[] toArray(T[] a);  
    //重寫Object方法
    boolean equals(Object o);  
    int hashCode();
    //迭代器 
    Iterator<E> iterator();  
    default Spliterator<E> spliterator()
    
    //同時List接口定義了一些自己的方法來實(shí)現(xiàn)“有序”這一功能特點(diǎn) 
    /** 
     *返回列表中指定索引的元素
     */  
    E get(int index);  
    /** 
     *設(shè)定某個列表索引的值  
     */  
    E set(int index, E element);  
    /** 
     *在指定位置插入元素搞莺,當(dāng)前元素和后續(xù)元素后移 
     *這是可選操作,類似于順序表的插入操作 
     */  
    void add(int index, E element); 
    /**
    * 在指定位置插入指定集合中的元素掂咒,當(dāng)前元素和后續(xù)元素后移
    */ 
    boolean addAll(int index, Collection<? extends E> c);  
    /** 
     * 刪除指定位置的元素(可選操作)
     */  
    E remove(int index);  
    /** 
     * 獲得指定對象的最小索引位置才沧,沒有則返回-1
     */  
    int indexOf(Object o);  
    /**
     * 獲得指定對象的最大索引位置,可以知道的是若集合中無給定元素的重復(fù)元素下 
     * 其和indexOf返回值是一樣的
     */  
    int lastIndexOf(Object o);  
    /**
     * 一種更加強(qiáng)大的迭代器绍刮,支持向前遍歷温圆,向后遍歷 
     * 插入刪除操作,此處不解釋
     */  
    ListIterator<E> listIterator();  
    ListIterator<E> listIterator(int index);  
    /** 
     * 返回索引fromIndex(包括)和toIndex(不包括)之間的視圖录淡。
     */  
    List<E> subList(int fromIndex, int toIndex);  
}  

List集合特點(diǎn)

  • 內(nèi)部元素是有序的 捌木,集合中每個元素都有其對應(yīng)的順序索引。
  • 元素是可以重復(fù)的 嫉戚,因?yàn)樗梢酝ㄟ^索引來訪問指定位置的集合元素刨裆。
  • List接口有3個常用的實(shí)現(xiàn)類,分別是ArrayList彬檀、LinkedList帆啃、Vector。

三:Set接口

Set接口完全繼承了Collection窍帝,在Collection基礎(chǔ)上并沒有什么改動努潘,但是增加了一個約定:不包含重復(fù)元素的集合!
接下來我們看一下源碼:

/**
 * Set是不允許重復(fù)元素的數(shù)據(jù)結(jié)構(gòu)坤学。
 */
public interface Set<E> extends Collection<E> {
    /**
     * Set作為Collection的子接口提供了Collection接口定義的方法 
     * 這些方法在Collection源碼學(xué)習(xí)中已經(jīng)分析過了疯坤,就不在說明了 
     */  
   //增
    boolean add(E e); 
    boolean addAll(Collection<? extends E> c); 
    //刪
    boolean remove(Object o); 
    boolean removeAll(Collection<?> c);
    boolean retainAll(Collection<?> c);
    default boolean removeIf(Predicate<? super E> filter)  
    void clear(); 
    //查
    int size();  
    boolean isEmpty();
    boolean contains(Object o);
    boolean containsAll(Collection<?> c);
    //轉(zhuǎn)數(shù)組
    Object[] toArray();  
    <T> T[] toArray(T[] a);  
    //重寫Object方法
    boolean equals(Object o);  
    int hashCode();
    //迭代器 
    Iterator<E> iterator();  
    default Spliterator<E> spliterator()
}

Set內(nèi)部元素是無序的,元素是不可以重復(fù)的

四:Queue接口

1深浮、Queue是在處理之前保存元素的集合压怠。除了基本的Collection操作外,Queue還提供額外的插入飞苇、刪除和檢查操作
2菌瘫、每個Queue方法都有兩種形式:(1)如果操作失敗則拋出異常,(2)如果操作失敗布卡,則返回特殊值(null或false雨让,具體取決于操作),接口的常規(guī)結(jié)構(gòu)如下表所示忿等。

拋出異常 返回特殊值
插入 add(e) offer(e)
刪除 remove() poll()
檢查 element() peek()
/**
 * Queue是在處理之前保存元素的集合栖忠。除了基本的Collection操作外,Queue還提供額外的插入、刪除和檢查操作
 * 每個Queue方法都有兩種形式:(1)如果操作失敗則拋出異常娃闲,
 * (2)如果操作失敗虚汛,則返回特殊值(null或false,具體取決于操作)皇帮,接口的常規(guī)結(jié)構(gòu)如下表所示卷哩。
 * 插入操作的后一種形式是專為使用有容量限制 Queue實(shí)現(xiàn);在大多數(shù)實(shí)現(xiàn)中属拾,插入操作不會失敗将谊。
 * 
 * |          | 拋出異常         | 返回特殊值             |
 * |插入      | add(e)          | offer(e)              |
 * |刪除      | remove()        | poll()                |
 * |檢查      | element()       | peek()                |
 * 
 * 隊(duì)列通常(但不一定)以FIFO(先進(jìn)先出)方式對元素進(jìn)行排序,優(yōu)先級隊(duì)列除外渐白,
 * 它們根據(jù)元素的值對元素進(jìn)行排序 — 有關(guān)詳細(xì)信息尊浓,請參閱“對象排序”部分。
 * 無論使用什么排序纯衍,隊(duì)列的頭部都是通過調(diào)用remove或poll移除的元素栋齿。
 * 在FIFO隊(duì)列中,所有新元素都插入隊(duì)列的尾部襟诸,其他類型的隊(duì)列可能使用不同的放置規(guī)則瓦堵,
 * 每個Queue實(shí)現(xiàn)都必須指定其排序?qū)傩浴? *
 * Queue實(shí)現(xiàn)可以限制它所擁有的元素?cái)?shù)量,這樣的隊(duì)列被稱為有界歌亲,java.util.concurrent中的某些Queue實(shí)現(xiàn)是有界的菇用,但java.util中的實(shí)現(xiàn)不是。
 * 可不只有拋出unchecked異常添加元素陷揪。的offer方法設(shè)計(jì)時使用的失敗是正常的惋鸥,
 * 而不是特殊的情況,例如悍缠,固定容量(或“有界”)隊(duì)列卦绣。的remove()和poll()方法移除并返回隊(duì)列的頭部。
 * 從隊(duì)列中刪除的是隊(duì)列的排序策略的函數(shù)飞蚓,它不同于從“實(shí)現(xiàn)”到“實(shí)現(xiàn)”的功能滤港。的remove()和poll()方法
 * 只是他們的行為當(dāng)隊(duì)列為空的不同的remove()方法拋出一個異常,而poll()方法返回null玷坠。
 *
 * Queue從Collection繼承的add方法插入一個元素蜗搔,除非它違反了隊(duì)列的容量限制劲藐,
 * 在這種情況下它會拋出IllegalStateException八堡。offer方法,僅用于有界隊(duì)列聘芜,
 * 與add不同之處僅在于它通過返回false來表示插入元素失敗兄渺。
 *
 * remove和poll方法都移除并返回隊(duì)列的頭部,確切地移除哪個元素是隊(duì)列的排序策略的函數(shù)汰现,
 * 僅當(dāng)隊(duì)列為空時挂谍,remove和poll方法的行為才有所不同叔壤,在這些情況下,
 * remove拋出NoSuchElementException口叙,而poll返回null炼绘。
 *
 *element和peek方法返回但不移除隊(duì)列的頭部,它們之間的差異與remove和poll的方式完全相同:如果隊(duì)列為空妄田,則element拋出NoSuchElementException俺亮,而peek返回null。
 * 隊(duì)列實(shí)現(xiàn)通常不允許插入null元素疟呐,為實(shí)現(xiàn)Queue而進(jìn)行了改進(jìn)的LinkedList實(shí)現(xiàn)是一個例外脚曾,
 * 由于歷史原因,它允許null元素启具,但是你應(yīng)該避免利用它本讥,因?yàn)閚ull被poll和peek方法用作特殊的返回值。
 *隊(duì)列實(shí)現(xiàn)通常不定義equals和hashCode方法的基于元素的版本鲁冯,而是從Object繼承基于標(biāo)識的版本拷沸。
 * Queue接口不定義阻塞隊(duì)列方法,這在并發(fā)編程中很常見晓褪,這些等待元素出現(xiàn)或空間可用的方法在java.util.concurrent.BlockingQueue接口中定義堵漱,該接口擴(kuò)展了Queue。
 *
 */
public interface Queue<E> extends Collection<E> {
    /**
     * 將指定的元素插入到此隊(duì)列中涣仿,如果不違反容量限制立即執(zhí)行此操作 
     * 成功后返回true勤庐,如果當(dāng)前沒有可用空間,則拋出IllegalStateException好港。
     */
    boolean add(E e);

    /**
     * 如果在不違反容量限制的情況下立即執(zhí)行愉镰,則將指定的元素插入到此隊(duì)列中。 
     * 當(dāng)使用容量限制隊(duì)列時钧汹,此方法通常優(yōu)于add(E) 丈探,這可能無法僅通過拋出異常來插入元素。 
     * 成功返回true拔莱,失敗返回false
     */
    boolean offer(E e);

    /**
     * 檢索并刪除此隊(duì)列的頭碗降。 此方法與poll不同之處在于,如果此隊(duì)列為空塘秦,它將拋出異常讼渊。
     */
    E remove();

    /**
     * 檢索并刪除此隊(duì)列的頭,如果此隊(duì)列為空尊剔,則返回 null 爪幻。
     */
    E poll();

    /**
     * 檢索,但不刪除,這個隊(duì)列的頭挨稿。 此方法與peek的不同之處在于仇轻,如果此隊(duì)列為空,它將拋出異常奶甘。
     */
    E element();

    /**
     * 檢索但不刪除此隊(duì)列的頭部篷店,如果此隊(duì)列為空,則返回 null 臭家。
     */
    E peek();
}

Queue接口特點(diǎn):

  • 先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu)船庇,即從容器的一端放入對象,從另一端取出侣监,并且對象放入容器的順序與取出的順序是相同的鸭轮。
  • 雖然Queue接口繼承Collection接口,但是Queue接口中的方法都是獨(dú)立的橄霉,在創(chuàng)建具有Queue功能的實(shí)現(xiàn)時窃爷,不需要使用Collection方法。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末姓蜂,一起剝皮案震驚了整個濱河市按厘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌钱慢,老刑警劉巖逮京,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異束莫,居然都是意外死亡懒棉,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進(jìn)店門览绿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來策严,“玉大人,你說我怎么就攤上這事饿敲∑薜迹” “怎么了?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵怀各,是天一觀的道長倔韭。 經(jīng)常有香客問我,道長瓢对,這世上最難降的妖魔是什么寿酌? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮沥曹,結(jié)果婚禮上份名,老公的妹妹穿的比我還像新娘。我一直安慰自己妓美,他們只是感情好僵腺,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著壶栋,像睡著了一般辰如。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上贵试,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天琉兜,我揣著相機(jī)與錄音,去河邊找鬼毙玻。 笑死豌蟋,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的桑滩。 我是一名探鬼主播梧疲,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼运准!你這毒婦竟也來了幌氮?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤胁澳,失蹤者是張志新(化名)和其女友劉穎该互,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體韭畸,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宇智,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了胰丁。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片普筹。...
    茶點(diǎn)故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖隘马,靈堂內(nèi)的尸體忽然破棺而出太防,到底是詐尸還是另有隱情,我是刑警寧澤酸员,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布蜒车,位于F島的核電站,受9級特大地震影響幔嗦,放射性物質(zhì)發(fā)生泄漏酿愧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一邀泉、第九天 我趴在偏房一處隱蔽的房頂上張望嬉挡。 院中可真熱鬧钝鸽,春花似錦、人聲如沸庞钢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽基括。三九已至颜懊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間风皿,已是汗流浹背河爹。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留桐款,地道東北人咸这。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像魔眨,于是被迫代替她去往敵國和親炊苫。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評論 2 350