一篇文章了解Java常用集合

這段時間一直在總結(jié)過去的知識融虽,今天來總結(jié)一下Java中常用的集合有额,在工作中使用最多的可能就在這里

下面來看下Java集合中總的框架結(jié)構(gòu)

Collection系列

image

Map系列

image

這張圖可以很好的了解各個集合之間的關(guān)系

下面是最常用的集合


image
Java集合大致可以分為Set、List笋熬、Queue和Map四種體系

1, Set代表無序胳螟、不可重復(fù)的集合;

2, List代表有序秘遏、重復(fù)的集合;

3, Map則代表具有映射關(guān)系的集合;

4, Java 5 又增加了Queue體系集合舍扰,代表一種隊(duì)列集合實(shí)現(xiàn)

下面開始分別介紹四大派系

Set系列

Collection是父接口,Set,Queue,List都是繼承Collection接口的陵且。

HashSet

HashSet是Set接口的實(shí)現(xiàn)類慕购,它實(shí)現(xiàn)了Set接口中的所有方法沪悲,并沒有添加額外的方法,大多數(shù)時候使用Set集合時就是使用這個實(shí)現(xiàn)類阱表。

特點(diǎn)

1,HashSet按Hash算法來存儲集合中的元素,因此具有很好的存取和查找性能殿如。

2,不可以存放重復(fù)元素,元素存取是無序的

3,集合元素值可以是null固歪。

4, HashSet不是同步的。因此是多線程訪問時必須通過代碼來同步

4, HashSet集合判斷兩個元素相等的標(biāo)準(zhǔn)是兩個對象通過equals()方法比較相等,并且兩個對象的hashCode()方法返回值也相等

注意:HashSet底層是HashMap實(shí)現(xiàn)的溉箕,HashSet的所有集合元素,構(gòu)成了HashMap的key,其value為一個靜態(tài)Object對象。因此HashSet的所有性質(zhì),HashMap的key所構(gòu)成的集合都具備

List 集合

List是一個元素有序、可重復(fù)的集合幅垮,集合中每個元素都有其對應(yīng)的順序索引潮峦。

ArrayList和Vector

ArrayList和Vector都是List實(shí)現(xiàn)類分苇。

ArrayList和Vector類封裝了一個動態(tài)的盆偿、允許再分配的Object[]數(shù)組罐农。ArrayList或Vector對象使用initalCapacity參數(shù)來設(shè)置該數(shù)組的長度麸恍,當(dāng)向ArrayList或Vector中添加元素超過了該數(shù)組的長度時逝薪,它們的initalCapacity會自動增加欢搜。

因此 ArrayList是一個動態(tài)擴(kuò)展的數(shù)組缘琅,Vector也同樣如此
ArrayList和Vector的區(qū)別

1, ArrayList是線程不安全的受啥,Vector是線程安全的。

2, Vector的性能比ArrayList差

LinkedList

LinkedList類也是List的實(shí)現(xiàn)類,so可以根據(jù)索引來隨機(jī)訪問集合中的元素。除此之外,LinkedList還實(shí)現(xiàn)了Deque接口,可以被當(dāng)作成雙端隊(duì)列來使用

注意:==LinkedList底層的數(shù)據(jù)結(jié)構(gòu)是鏈表結(jié)構(gòu)==

基于鏈表特性,新增的一些方法

  /**
     * 將指定元素插入此列表的開頭惭嚣。
     */
    public void addFirst(E e) {
        throw new RuntimeException("Stub!");
    }

    /**
     * 將指定元素添加到此列表的結(jié)尾载矿。
     */
    public void addLast(E e) {
        throw new RuntimeException("Stub!");
    }

    /**
     * 返回此列表的第一個元素
     */
    public E getFirst() {
        throw new RuntimeException("Stub!");
    }

    /**
     * 返回此列表的最后一個元素
     */
    public E getLast() {
        throw new RuntimeException("Stub!");
    }

    /**
     * 在此列表的開頭插入指定的元素
     */
    public boolean offerFirst(E e) {
        throw new RuntimeException("Stub!");
    }

    /**
     * 在此列表末尾插入指定的元素
     */
    public boolean offerLast(E e) {
        throw new RuntimeException("Stub!");
    }


    /**
     * 獲取但不移除此列表的第一個元素;如果此列表為空,則返回 null
     */
    public E peekFirst() {
        throw new RuntimeException("Stub!");
    }


    /**
     * 獲取但不移除此列表的最后一個元素句占;如果此列表為空杨拐,則返回 null舱痘。
     */
    public E peekLast() {
        throw new RuntimeException("Stub!");
    }


    /**
     * 獲取并移除此列表的第一個元素翎猛;如果此列表為空鹃两,則返回 null
     */
    public E pollFirst() {
        throw new RuntimeException("Stub!");
    }

    /**
     * 獲取并移除此列表的最后一個元素梯醒;如果此列表為空,則返回 null
     */
    public E pollLast() {
        throw new RuntimeException("Stub!");
    }

    /**
     * 移除并返回此列表的第一個元素极景。
     */
    public E removeFirst() {
        throw new RuntimeException("Stub!");
    }

    /**
     * 移除并返回此列表的最后一個元素
     */
    public E removeLast() {
        throw new RuntimeException("Stub!");
    }

    /**
     * 從此列表中移除第一次出現(xiàn)的指定元素(從頭部到尾部遍歷列表時)
     */
    public boolean removeFirstOccurrence(Object o) {
        throw new RuntimeException("Stub!");
    }
    
    /**
     * 從此列表中移除最后一次出現(xiàn)的指定元素(從頭部到尾部遍歷列表時)
     */
    public boolean removeLastOccurrence(Object o) {
        throw new RuntimeException("Stub!");
    }

集合 數(shù)組結(jié)構(gòu) 線程安全 性能 使用場景
List 需要保留存儲順序, 并且保留重復(fù)元素, 使用List
ArrayList 動態(tài)數(shù)組 非線程安全 隨機(jī)訪問元素性能出色 查詢較多, 使用ArrayList
Vector 動態(tài)數(shù)組 線程安全 比ArrayList差 需要線程安全稍途,使用Vector
LinkList 鏈表 非線程安全 在插入、刪除元素時性能比較出色但隨機(jī)訪問集合元素時性能較差 存取較多,使用LinkedList

Queue集合

Queue用戶模擬隊(duì)列這種數(shù)據(jù)結(jié)構(gòu)共屈,隊(duì)列通常是指“先進(jìn)先出”(FIFO,first-in-first-out)的容器班缎。隊(duì)列的頭部是在隊(duì)列中存放時間最長的元素,隊(duì)列的尾部是保存在隊(duì)列中存放時間最短的元素。新元素插入(offer)到隊(duì)列的尾部蹂随,訪問元素(poll)操作會返回隊(duì)列頭部的元素乒躺。通常娜遵,隊(duì)列不允許隨機(jī)訪問隊(duì)列中的元素

PriorityQueue

  • PriorityQueue是Queue的實(shí)現(xiàn)類万皿,本質(zhì)也是一個動態(tài)數(shù)組位岔,在這一方面與ArrayList是一致的。
  • PriorityQueue中的元素可以默認(rèn)自然排序(也就是數(shù)字默認(rèn)是小的在隊(duì)列頭巾遭,字符串則按字典序排列)或者通過提供的Comparator(比較器)在隊(duì)列實(shí)例化時指定的排序方式
特點(diǎn):

PriorityQueue保存隊(duì)列元素的順序不是按加入隊(duì)列的順序末捣,而是按隊(duì)列元素的大小進(jìn)行重新排序。
所以調(diào)用peek()或pool()方法取出隊(duì)列中頭部的元素時,并不是取出最先進(jìn)入隊(duì)列的元素,而是取出隊(duì)列中的最小的元素

PriorityQueue不是線程安全的

不允許插入 null 元素

接下來看下Map,說到Map當(dāng)然離不開他的兩個重要的實(shí)現(xiàn)類HashMap和Hashtable

Map集合存放具有映射關(guān)系的數(shù)據(jù),
因此Map集合里保存著兩組數(shù)骗灶,一組值中保存Map里的key,另一組值中保存Map里的value移迫,key和value都可以是任何引用類型的數(shù)據(jù)。

特點(diǎn):Map的key不允許重復(fù)机杜,即同一個Map對象中任何兩個key通過equals方法比較返回的一定是false

HashMap

HashMap 是一個散列表蚀苛,它存儲的內(nèi)容是鍵值對(key-value)映射。

理解HashMap本質(zhì)


 public HashMap() {
        throw new RuntimeException("Stub!");
    }
    
 public HashMap(int initialCapacity) {
        throw new RuntimeException("Stub!");
    }
    
 public HashMap(int initialCapacity, float loadFactor) {
        throw new RuntimeException("Stub!");
    }

 public HashMap(Map<? extends K, ? extends V> m) {
        throw new RuntimeException("Stub!");
    }
    

構(gòu)造函數(shù)中有兩個重要的參數(shù):容量大小(initialCapacity)和加載因子(loadFactor)

  • 容量(initialCapacity)是: 哈希表的容量膘怕,初始容量是哈希表在創(chuàng)建時的容量(即DEFAULT_INITIAL_CAPACITY = 1 << 4)

  • 加載因子(loadFactor): 是哈希表在其容量自動增加之前可以達(dá)到多滿的一種尺度。當(dāng)哈希表中的條目數(shù)超出了加載因子與當(dāng)前容量的乘積時,則要對該哈希表進(jìn)行 resize操作(即重建內(nèi)部數(shù)據(jù)結(jié)構(gòu))垦缅,從而哈希表將具有大約兩倍的桶數(shù)。默認(rèn)加載因子是 0.75(即DEFAULT_LOAD_FACTOR = 0.75f),

注:

HashMap是通過"拉鏈法"實(shí)現(xiàn)的哈希表赢底。它包括幾個重要的成員變量:table, size, threshold, loadFactor失都。

table是一個Node[]數(shù)組類型柏蘑,而Node實(shí)際上就是一個單向鏈表幸冻。哈希表的"key-value鍵值對"都是存儲在Node數(shù)組中的。

size是HashMap的大小咳焚,它是HashMap保存的鍵值對的數(shù)量洽损。

threshold是HashMap的閾值,用于判斷是否需要調(diào)整HashMap的容量革半。threshold的值="容量*加載因子"碑定,當(dāng)HashMap中存儲數(shù)據(jù)的數(shù)量達(dá)到threshold時,就需要將HashMap的容量加倍又官。

loadFactor 為加載因子

HashMap遍歷方式

    Map<Integer, String> map = new HashMap<>();
        map.put(1, "acfgdws");
        map.put(2, "bwdfrx");
        map.put(3, "abrgcs");
        map.put(4, "absrfgr");
        map.put(5, "abcderf");

        /**
         *  第一種:通過Map.keySet遍歷key和value
         */
        for (Integer key : map.keySet()) { //map.keySet()返回的是所有key的值
            String str = map.get(key);//得到每個key多對用value的值
            Log.d("Map", key + "     " + str);
        }

        /**
         *第二種:通過Map.entrySet使用iterator遍歷key和value
         */
        Iterator<Map.Entry<Integer, String>> it = map.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<Integer, String> entry = it.next();
            Log.d("Map", "key= " + entry.getKey() + " and value= " + entry.getValue());
        }


        /** 第三種:推薦延刘,尤其是容量大時 通過Map.entrySet遍歷key和value
         Map.entry<Integer,String> 映射項(xiàng)(鍵-值對)  
         map.entrySet() 返回此映射中包含的映射關(guān)系的 Set視圖。
         */
        for (Map.Entry<Integer, String> entry : map.entrySet()) {
            Log.d("Map", "key= " + entry.getKey() + " and value= " + entry.getValue());
        }

        /**
         * 第四種:通過Map.values()遍歷所有的value六敬,但不能遍歷key
         */
        for (String v : map.values()) {
            Log.d("Map", "value= " + v);
        }

Hashtable

是一個散列表碘赖,它存儲的內(nèi)容是鍵值對(key-value)映射

構(gòu)造函數(shù)

 public Hashtable() {
        throw new RuntimeException("Stub!");
    }
    
      public Hashtable(int initialCapacity) {
        throw new RuntimeException("Stub!");
    }
    
  public Hashtable(int initialCapacity, float loadFactor) {
        throw new RuntimeException("Stub!");
    }

    public Hashtable(Map<? extends K, ? extends V> t) {
        throw new RuntimeException("Stub!");
    }

從構(gòu)造函數(shù)可以看出和HashMap一樣有兩個重要的參數(shù):容量大小(initialCapacity)和加載因子(loadFactor)

遍歷方式

     Hashtable<String, Integer> table = new Hashtable<>();
        table.put("a", 10);
        table.put("b", 20);
        table.put("c", 30);
        table.put("d", 40);

        /**
         * 方式1: 鍵值對遍歷entrySet()
         */
        for (Map.Entry<String, Integer> entry : table.entrySet()) {
            String key = entry.getKey();
            int value = entry.getValue();
            Log.d("Hashtable", "entrySet:" + key + " " + value);
        }


        /***
         * 方式2: key鍵的遍歷
         */
        for (String key : table.keySet()) {
            int value = table.get(key);
            Log.d("Hashtable", "keySet:" + key + " " + value);
        }


        /**
         * 方式3: 通過Enumeration來遍歷Hashtable
         */
        Enumeration<String> enu = table.keys();
        while (enu.hasMoreElements()) {
            Log.d("Hashtable", "Enumeration:" + table.keys() + " " + enu.nextElement());
        }
HashMap與Hashtable的區(qū)別
集合類型 數(shù)據(jù)結(jié)構(gòu) 基類 線程安全 性能 key或value是否可以為null
HashMap 哈希表來存儲鍵值對 AbstractMap 線程安全 比Hashtable性能好 可以
Hashtable 哈希表來存儲鍵值對 Dictionary 不安全 多個線程訪問同一個map性能好 不可以
注:

Dictionary是什么?它是任何可將鍵映射到相應(yīng)值的類的抽象父類,而AbstractMap是基于Map接口的骨干實(shí)現(xiàn)普泡,它以最大限度地減少實(shí)現(xiàn)此接口所需的工作

補(bǔ)充:HashMap僅支持Iterator的遍歷方式播掷,Hashtable支持Iterator和Enumeration兩種遍歷方式。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末撼班,一起剝皮案震驚了整個濱河市歧匈,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌砰嘁,老刑警劉巖件炉,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異般码,居然都是意外死亡妻率,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進(jìn)店門板祝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宫静,“玉大人,你說我怎么就攤上這事券时」吕铮” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵橘洞,是天一觀的道長捌袜。 經(jīng)常有香客問我,道長炸枣,這世上最難降的妖魔是什么虏等? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮适肠,結(jié)果婚禮上霍衫,老公的妹妹穿的比我還像新娘。我一直安慰自己侯养,他們只是感情好敦跌,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著逛揩,像睡著了一般柠傍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上辩稽,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天惧笛,我揣著相機(jī)與錄音,去河邊找鬼逞泄。 笑死患整,一個胖子當(dāng)著我的面吹牛静檬,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播并级,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼拂檩,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了嘲碧?” 一聲冷哼從身側(cè)響起稻励,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎愈涩,沒想到半個月后望抽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡履婉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年煤篙,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片毁腿。...
    茶點(diǎn)故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡辑奈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出已烤,到底是詐尸還是另有隱情鸠窗,我是刑警寧澤,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布胯究,位于F島的核電站稍计,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏裕循。R本人自食惡果不足惜臣嚣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望剥哑。 院中可真熱鬧硅则,春花似錦、人聲如沸星持。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽督暂。三九已至,卻和暖如春穷吮,著一層夾襖步出監(jiān)牢的瞬間逻翁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工捡鱼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留八回,地道東北人。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像缠诅,于是被迫代替她去往敵國和親溶浴。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Java集合類可用于存儲數(shù)量不等的對象,并可以實(shí)現(xiàn)常用的數(shù)據(jù)結(jié)構(gòu)如棧,隊(duì)列等,Java集合還可以用于保存具有映射關(guān)...
    小徐andorid閱讀 1,942評論 0 13
  • 一、集合入門總結(jié) 集合框架: Java中的集合框架大類可分為Collection和Map褥伴;兩者的區(qū)別: 1谅将、Col...
    程序員歐陽閱讀 11,562評論 2 61
  • 在一個方法內(nèi)部定義的變量都存儲在棧中,當(dāng)這個函數(shù)運(yùn)行結(jié)束后重慢,其對應(yīng)的棧就會被回收饥臂,此時,在其方法體中定義的變量將不...
    Y了個J閱讀 4,418評論 1 14
  • 聽朋友說起他和前任3年的感情似踱。 我應(yīng)該是無動于衷的隅熙,可不知為何,這次竟然會突覺失落核芽。 對于以往朋友的傾訴猛们,我總是自...
    錢先森森閱讀 152評論 0 0
  • 在一些行業(yè)里尤其是互聯(lián)網(wǎng)行業(yè)新老員工“薪酬倒掛”十分普遍弯淘,同樣的崗位,新員工工資比老員工更高吉懊。HR迫于用人部...
    我薪閱讀 4,220評論 1 2