Java集合框架(二)Collection詳解

??在之前的學(xué)習(xí)中我們將Java的集合框架做了一個(gè)大致的分類,對(duì)集合的結(jié)構(gòu)有一定的了解,現(xiàn)在便是由表及里,我們深入學(xué)習(xí)Java的集合框架,今天主要學(xué)習(xí)Collection。

Collection做了什么?

??根據(jù)前一篇文章Java集合框架(一)類簡(jiǎn)介里面的集合框架圖可以知道,Collection是描述所有序列容器共性的根接口。使用接口描述的一個(gè)理由是它可以使我們能夠創(chuàng)建更通用的代碼。接口就是對(duì)一個(gè)對(duì)象進(jìn)行規(guī)范,使對(duì)象具有做某些事情的能力。
??我們知道集合是用來(lái)存儲(chǔ)數(shù)據(jù)的,我們程序中經(jīng)常要管理大量的對(duì)象,比如在學(xué)校的信息管理系統(tǒng)里,每一個(gè)學(xué)生的相關(guān)信息,都可以抽象成一個(gè)對(duì)象。這時(shí)候,我們就會(huì)把同一個(gè)類型的對(duì)象放在同一個(gè)集合中進(jìn)行集中管理。集合中存放了我們隨時(shí)可能需要使用到的對(duì)象,這就要求容器最起碼要提供增刪改等基本接口。這一點(diǎn)我們通過(guò)下面的類結(jié)構(gòu)圖也可以看出:


Collection作為根接口,定義了集合應(yīng)該具有的行為規(guī)范。

  • int size(); 獲取集合大?。系脑?cái)?shù)量)
  • boolean isEmpty(); 判斷集合是否為空(沒(méi)有元素時(shí)返回true)
  • boolean contains(Object o); 集合是否包含特定元素;
  • Iterator<E> iterator(); 返回一個(gè)Iterator(迭代器),可以用于集合遍歷
  • Object[] toArray(); 返回一個(gè)數(shù)組,該數(shù)組具有集合中的所有元素
  • <T> T[] toArray(T[] a);返回一個(gè)指定了類型的數(shù)組。不再是單純的Object。
  • boolean add(E e); 添加一個(gè)指定類型的元素
  • boolean remove(Object o); 移除一個(gè)元素
  • boolean containsAll(Collection<?> c);是否包含參數(shù)中的所有元素
  • boolean addAll(Collection<? extends E> c);添加參數(shù)中的所有元素
  • boolean removeAll(Collection<?> c);移除參數(shù)中的所有元素
  • default boolean removeIf(Predicate<? super E> filter);移除集合中滿足給定條件的所有元素
  • boolean retainAll(Collection<?> c);只保存參數(shù)中的元素。(集合有改變就返回true)
  • void clear();移除集合中所有元素
  • boolean equals(Object o);
  • int hashCode();
  • default Spliterator<E> spliterator();獲取一個(gè)Spliterator(可分割迭代器),可以并行遍歷元素
  • default Stream<E> stream();返回一個(gè)順序流(Java8新特性,Stream API)
  • default Stream<E> parallelStream();返回一個(gè)并行流(Java8新特性,Stream API)

使用Iterator遍歷集合元素

??Iterator接口經(jīng)常被稱作迭代器,它是Collection接口的父接口。Iterator主要用于遍歷集合的元素。我們可以看看Iterator的接口設(shè)計(jì):

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());
    }
}

??可以看出Iterator接口中主要定義了4個(gè)方法:

  • boolean hasNext();是否有下一個(gè)元素
  • E next();獲取下一個(gè)元素
  • default void remove();Java8新添加,非必須方法
  • default void forEachRemaining(Consumer<? super E> action);Java8新添加,非必須方法
    ??其中有兩個(gè)default方法。default這個(gè)關(guān)鍵字,我們以前沒(méi)接觸過(guò)。這是從1.8引入的,為了和以前的接口兼容,這個(gè)我們先不去管它,還有forEachRemaing是一個(gè)高階函數(shù),它可以接受一個(gè)lambda表達(dá)式。所以,實(shí)際上Iterator中也就只有兩個(gè)方法,一個(gè)是hasNext,目的是告訴使用者,還有沒(méi)有下一個(gè)元素,如果為false,說(shuō)明遍歷已經(jīng)完成了。還有一個(gè)是next,目的是取下一個(gè)元素。
    ??我們先使用這個(gè)迭代器遍歷一下List,例如:
public class IteratorExample {
    public static void main(String args[]) {
        LinkedList<Integer> ll = new LinkedList<>();
        for (int i = 0; i < 10; i++) {
            ll.addLast(i);
        }

        Iterator<Integer> ii = ll.iterator();
        while (ii.hasNext())
            System.out.print(ii.next());
    }
}

??大家可以再試一下ArrayList,體會(huì)一下Iterator的用法??梢钥吹剑覀兏揪筒恍枰P(guān)心后面的數(shù)據(jù)結(jié)構(gòu),只需要使用Iterator,不管后面是數(shù)組還是鏈表,都可以很方便地遍歷整個(gè)集合。
??如果需要我們自己來(lái)實(shí)現(xiàn)這樣一個(gè)Iterator,我們應(yīng)該怎么做呢?我們可以參考一下ArrayList的源碼:

 private class Itr implements Iterator<E> {
        protected int limit = ArrayList.this.size;
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;

        public boolean hasNext() {
            return cursor < limit;
        }

        @SuppressWarnings("unchecked")
        public E next() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            int i = cursor;
            if (i >= limit)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }

        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();

            try {
                ArrayList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;
                limit--;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }    
    }

??可以看到,ArrayList的Iterator就是在數(shù)組中逐個(gè)前進(jìn),邏輯非常簡(jiǎn)單。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,963評(píng)論 6 542
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,348評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事?!?“怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 178,083評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,706評(píng)論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,442評(píng)論 6 412
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,802評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,795評(píng)論 3 446
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,983評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,542評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,287評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,486評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,030評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,710評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,116評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,412評(píng)論 1 294
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,224評(píng)論 3 398
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,462評(píng)論 2 378