Java Collection 集合

Java Collection 學(xué)習(xí)

定義:Java 作為面向?qū)ο笳Z言茸俭,對象的操作必比然是重中之重粘都。要操作一個對象容易不跟,如果需要存儲多個對象柒巫,則需要一個容器励堡,存儲多個對象可以使用數(shù)組,但是數(shù)組的長度是不可變的堡掏。所以有了集合的概念应结。Collection 集合,就是為了方便操作處理對象而誕生的泉唁。

Collection :來源與 Java.util 包鹅龄,先看看 Collection 的全家福類圖

image

Collection 可以主要分為 set、List 亭畜、Queue 三種類型扮休。這里 Map 是不屬于 Collection 的,Map 是一個獨(dú)立的數(shù)據(jù)結(jié)構(gòu)拴鸵。但是 Collention 又和 Map 的實(shí)現(xiàn)上又戶型依賴玷坠。先說說 Collection 。

Collection 是一個的接口劲藐,是高度抽象出來的集合八堡,包含了集合的基本操作和屬性

image

紅色框是Collection的基本方法(removeif 是1.8 出現(xiàn)的方法),藍(lán)色框是 JDK 8后添加的新方法瘩燥。

一秕重、Collection 基本方法

Collection基本方法:

1、添加方法
 boolean add(Object obj)      : 添加一個對象
 boolean addAll(Collection c) : 添加一個集合的對象
2厉膀、刪除方法
 void clear() 移除所有對象
 boolean remove(Object) 移除一個對象
 boolean removeAll(Collection c) 移除一個集合的對象溶耘,只要有一個對象移除了,就返回true
3服鹅、判斷方法
 boolean contains(Object o) 判斷集合是否包含該對象
 boolean containsAll(Collection c) 判斷集合中是否包含指定的集合對象凳兵,只有包含所有的對象,才返回 true企软。
 boolean isEmpty() 判斷集合是否為空庐扫。
4、獲取方法
 Iterator<E> iterator() 迭代器
5、長度功能
 int size() 對象個數(shù)
6.交集功能
 boolean retainAll(Collection c) 移除此 Collection 中未包含在指定Collection 中的所有對象形庭,簡單說就是铅辞,集合 1 和集合 2 進(jìn)行對比,最終結(jié)果保存在集合 1 萨醒,返回值表示的是 A是否發(fā)生變化斟珊。
 
Java 8 新方法:
 boolean removeif(Predicate filter) 按照一定規(guī)則過濾集合中的對象。Predicate 用于判斷對象是否符合某個條件富纸,例:
 public static void main(String[] args) {
        List<String> list  = new ArrayList<>();
        list.add("123");
        list.add("12");
        list.add("1");

        list.removeIf(s -> s.equals("123"));
        list.forEach(s -> System.out.println(s));
    }

二囤踩、迭代器(Iterator)

在說迭代器之前先說說 Collection 繼承的 Iterable 這個接口

image

解釋一下這個 Iterable 是啥

如果一個集合對象要表明自己支持迭代,可以使用foreach語句的特權(quán)晓褪,就必須實(shí)現(xiàn)Iterable接口堵漱,表明這個集合對象是可迭代的!然而實(shí)現(xiàn)Iterable接口涣仿,就必需為foreach語句提供一個迭代器來進(jìn)行 foreach 操作勤庐。

也就是 迭代器(Iterator),所以 Iterable 接口要有 Iterator() 這個方法返回一個實(shí)現(xiàn)了 Iterator 迭代器接口的對象好港。

那為什么要用這個接口而不直接實(shí)現(xiàn) Iterator 接口呢埃元?我們帶著疑問去看看!

另外提一下 spliterator 方法媚狰,返回一個 spliterator 接口。叫做可分割迭代器(splitable iterator)阔拳,Spliterator就是為了并行遍歷元素而設(shè)計的一個迭代器崭孤,jdk1.8中的集合框架中的數(shù)據(jù)結(jié)構(gòu)都默認(rèn)實(shí)現(xiàn)了spliterator。這里只做一個簡單的介紹糊肠。

帶著疑問首先來看看 List 接口的 源代碼

image

可以看到 List 接口也有 Iterator 方法辨宠,下面我們看看 List 集合的實(shí)現(xiàn)類ArrayList

image

看到這里,可以解釋為什么 Collection 不直接實(shí)現(xiàn) Iterator 接口了:

List 集合族 與 Set 集合族 货裹,都是實(shí)現(xiàn)了 Iterable 接口 嗤形,但都不是直接實(shí)現(xiàn) Iterator 接口,為什么要這樣做弧圆?

因?yàn)樵?Iterator 接口的核心方法 next()或者 hasNext ()都是依賴于迭代器當(dāng)前的迭代的位置赋兵。

如果 Collection 實(shí)現(xiàn)了 Iterator 接口,肯定會導(dǎo)致集合對象中包含當(dāng)前迭代位置的數(shù)據(jù)(指針)搔预。

當(dāng)集合在不同方法間被傳遞的時候霹期,由于當(dāng)前迭代的位置是不可以預(yù)置。那么 next 方法的結(jié)果會變成不可預(yù)知拯田。

這樣看使用 Iterable 接口就不會有這樣問題历造,每一次調(diào)用都是返回一個新的迭代器。迭代器之間是互不干擾的。

看上圖 ArrayList 的 Iterator()方法就很直觀了吭产。


public static void main(String[]args) {

      List<String>list=newArrayList<>();

      list.add("123");

      list.add("12");

      list.add("1");
      //獲取迭代器
      Iterator<String>it=list.iterator();
      
      while(it.hasNext()){

            System.out.println(it.next());

       }

   }

當(dāng)我們使用迭代器時, 就是調(diào)用 list 實(shí)現(xiàn)的具體的 iterator 方法侣监,每次使用迭代器的都是一個新的迭代器。

三臣淤、List 集合

List 接口的特點(diǎn):有序集合橄霉,可以精確控制列表中每個元素的位置插入。 用戶可以通過整數(shù)索引訪問元素荒典,并搜索列表中的元素酪劫。簡單來說就是 順序存儲,順序取出寺董「苍悖可以重復(fù)。

List 還對 Iterator 作了實(shí)現(xiàn) 遮咖, ListIterator 接口滩字。

image

ListIterator 接口比 Iterator 要多了幾個方法。

hasPrevious() 和 previous() 方法都可以實(shí)現(xiàn)逆向遍歷御吞。

add()和 set()方法可以向List 中添加和修改對象麦箍。

List 集合的常用子類

ArrayList

ArrayList 是基于數(shù)組的, ArrayList 是無序的陶珠,它按照添加的先后順序排列挟裂。如果要對 ArrayList 進(jìn)行排序,可以調(diào)用它的 sort()方法揍诽。并提供一個 Comparator 比較器诀蓉。

ArrayList 是線程不安全的。

LinkedList

LinkedList 是基于鏈表的暑脆,它是一個雙向鏈表渠啤,每個節(jié)點(diǎn)維護(hù)了一個 prev 和 next 指針。同時這個鏈表維護(hù)了 first 和 last指針添吗,分別指向第一個元素和最后一個元素沥曹。

它也是一個無序列表,也是按照插入的先后順序排序碟联。

LInkedList 對與快速訪問元素不如 ArrayList 快妓美,因?yàn)?ArrayList 訪問元素是隨機(jī)的。

LinkedList 也是線程不安全的鲤孵。

Vector

Vector 和 ArrayList 非常類似部脚,但Vector 是同步的。

由 Vector 創(chuàng)建的 Iterator 裤纹,雖然和 ArrayList 創(chuàng)建的 Iterator 是同一個接口委刘,但是由于其同步的特性丧没,當(dāng)Vector 創(chuàng)建一個 Iterator 并使用時,另一個線程改變了 Vector 的狀態(tài)锡移,比如說添加或者刪除了一些元素呕童, 這時再調(diào)用 Iterator的方法則會拋出異常。

Stack 類繼承與 Vector 類淆珊,是一個堆棧夺饲,Stack 提供的5個額外的方法 使 vector 可以當(dāng)做堆棧使用。

四施符、Set 集合

image

Set 集合的特點(diǎn)

無序往声,不可重復(fù)。

Set 集合中常用的子類

HashSet

底層數(shù)據(jù)結(jié)構(gòu)是哈希表(一個元素為鏈表的數(shù)組)

HashSet 是基于 HashMap 實(shí)現(xiàn)的戳吝,有點(diǎn)像是對 HashMap 做了封裝浩销,而且只是用了 HashMap 的 key 來實(shí)現(xiàn)其特性。

HashSet 不允許重復(fù)听哭,如果出現(xiàn)重復(fù)就覆蓋慢洋,允許為空。

HashSet 是線程不安全的陆盘。

TreeSet

底層數(shù)據(jù)結(jié)構(gòu)是紅黑樹 (一個自平衡的二叉樹)

TreeSet 是一個有序的集合普筹,它的作用是提供有序的Set集合。

TreeSet的性能比HashSet差但是我們在需要排序的時候可以用TreeSet因?yàn)樗亲匀慌判蛞簿褪巧?/p>

LinkedHashSet

底層數(shù)據(jù)結(jié)構(gòu)是由哈希表和鏈表組成隘马。

LinkedHashSet 是不重復(fù)的太防,按插入的順序排序。

LinkedHashSet 是線程不安全的酸员。

五杏头、Map 集合

為什么 Map 不繼承 Collection?

首先 Map 提供的是鍵值對映射沸呐,而 Collection 是集合接口,提供的是一組數(shù)據(jù)呢燥。如果 Map 繼承了 Collection 接口崭添,那么所有 Map 的實(shí)現(xiàn)類到底是使用鍵值對還是使用 Collection 來存放數(shù)據(jù)呢?所以既然是兩種數(shù)據(jù)結(jié)構(gòu)叛氨,那也就沒有必要去繼承 Collection接口了呼渣,同時還不違反接口隔離原則。假如有實(shí)現(xiàn)類需要使用的 Collection 接口寞埠,也不該是 Map 去繼承 Collection 接口屁置。

六、總結(jié)

了解了以上的這些集合后仁连,實(shí)際工作功能該如何選擇呢蓝角?

如果涉及到堆棧阱穗,隊列等操作,應(yīng)該考慮使用 List 使鹅,對于需要快速插入揪阶,刪除元素,應(yīng)該使用 LinkedList 患朱。需要快速隨機(jī)訪問元素鲁僚,則使用 ArrayList。

如果程序在單線程環(huán)境中裁厅,或者訪問僅在一個線程中進(jìn)行冰沙,考慮非同步的類,其效率較高执虹,如果多個線程則考慮 **同步 **的類拓挥。

要注意對哈希表的操作。作為 key 的對象要正確復(fù)寫 equals 和 hashCode 方法

感謝您的觀看声畏,如果發(fā)現(xiàn)錯誤歡迎指出撞叽,謝謝!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末插龄,一起剝皮案震驚了整個濱河市愿棋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌均牢,老刑警劉巖糠雨,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異徘跪,居然都是意外死亡甘邀,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進(jìn)店門垮庐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來松邪,“玉大人,你說我怎么就攤上這事哨查《阂郑” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵寒亥,是天一觀的道長邮府。 經(jīng)常有香客問我,道長溉奕,這世上最難降的妖魔是什么褂傀? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮加勤,結(jié)果婚禮上仙辟,老公的妹妹穿的比我還像新娘同波。我一直安慰自己,他們只是感情好欺嗤,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布参萄。 她就那樣靜靜地躺著,像睡著了一般煎饼。 火紅的嫁衣襯著肌膚如雪讹挎。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天吆玖,我揣著相機(jī)與錄音筒溃,去河邊找鬼。 笑死沾乘,一個胖子當(dāng)著我的面吹牛怜奖,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播翅阵,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼歪玲,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了掷匠?” 一聲冷哼從身側(cè)響起滥崩,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎讹语,沒想到半個月后钙皮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡顽决,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年短条,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片才菠。...
    茶點(diǎn)故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡茸时,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出赋访,到底是詐尸還是另有隱情可都,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布进每,位于F島的核電站,受9級特大地震影響命斧,放射性物質(zhì)發(fā)生泄漏田晚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一国葬、第九天 我趴在偏房一處隱蔽的房頂上張望贤徒。 院中可真熱鬧芹壕,春花似錦、人聲如沸接奈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽序宦。三九已至睁壁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間互捌,已是汗流浹背潘明。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留秕噪,地道東北人钳降。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像腌巾,于是被迫代替她去往敵國和親遂填。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評論 2 354