Java集合筆記

集合框架概述

  • 一方面,面向?qū)ο笳Z言對(duì)事物的體現(xiàn)都是以對(duì)象的形式扎瓶,為了方便對(duì)多個(gè)對(duì)象的操作颗祝,就要對(duì)對(duì)象進(jìn)行存儲(chǔ)浊闪。另一方面,使用Array存儲(chǔ)對(duì)象方面具有一些弊端螺戳,而Java集合就像一種容器搁宾,可以動(dòng)態(tài)地把多個(gè)對(duì)象的引用放入容器中。
    • 數(shù)組在內(nèi)存存儲(chǔ)方面的特點(diǎn)
      • 數(shù)組初始化以后倔幼,長(zhǎng)度就確定了盖腿;
      • 數(shù)組聲明的類型,就決定了進(jìn)行元素初始化時(shí)的類型损同;
    • 數(shù)組在存儲(chǔ)數(shù)據(jù)方面的弊端:
      • 數(shù)組初始化以后翩腐,長(zhǎng)度就不可變了,不便于擴(kuò)展膏燃;
      • 數(shù)組中提供的屬性和方法少茂卦,不便于進(jìn)行添加、刪除组哩、插入等操作等龙,且效率不高处渣。同時(shí)無法直接獲取存儲(chǔ)元素的個(gè)數(shù);
      • 數(shù)組存儲(chǔ)的數(shù)據(jù)是有序的而咆、可以重復(fù)的。-->存儲(chǔ)數(shù)據(jù)的特點(diǎn)單一幕袱;
  • Java集合類可以用于存儲(chǔ)數(shù)量不等的多個(gè)對(duì)象暴备,還可用于保存具有映射關(guān)系的關(guān)聯(lián)數(shù)組。

集合框架

兩種體系

Java集合可分為CollectionMap兩種體系:

  • Collection接口:單列數(shù)據(jù)们豌,定義了存取一組對(duì)象的方法的集合涯捻,未提供直接實(shí)現(xiàn)類
    • List:元素有序、可重復(fù)的集合
    • Set:元素?zé)o序望迎、不可重復(fù)的集合
  • Map接口:雙列數(shù)據(jù)障癌,保存具有映射關(guān)系"key-value對(duì)"的集合,提供了直接的實(shí)現(xiàn)類

繼承和實(shí)現(xiàn)關(guān)系

|---- Collection接口:?jiǎn)瘟屑?    |----List接口
       |----Vector實(shí)現(xiàn)類
       |----ArrayList實(shí)現(xiàn)類
       |----LinkedList實(shí)現(xiàn)類

    |----Set接口
        |----HashSet實(shí)現(xiàn)類
           |----LinkedHashSet實(shí)現(xiàn)類
        |----SortedSet接口
           |----TreeSet實(shí)現(xiàn)類
|----Map接口:雙列集合
    |----Hashtable實(shí)現(xiàn)類
        |----Properties實(shí)現(xiàn)類
    |----HashMap實(shí)現(xiàn)類
        |----LinkedHashMap實(shí)現(xiàn)類
    |----SortedMap接口
        |----TreeMap實(shí)現(xiàn)類

JDK提供的集合API位于java.util包內(nèi)辩尊,下圖中:

  • 實(shí)線表示繼承關(guān)系
  • 虛線表示實(shí)現(xiàn)關(guān)系

Collection接口繼承樹

Map接口繼承樹

Collection接口

Collection接口是List涛浙、SetQueue接口的父接口,該接口里定義的方法既可用于操作Set集合摄欲,也可用于操作ListQueue集合轿亮。

JDK不提供此接口的任何直接實(shí)現(xiàn),而是提供更具體的子接口(如:SetList)實(shí)現(xiàn)胸墙。

在Java5之前我注,Java集合會(huì)丟失容器中所有對(duì)象的數(shù)據(jù)類型,把所有對(duì)象都當(dāng)成Object類型處理迟隅;從 JDK 5.0 增加了泛型以后但骨,Java集合可以記住容器中對(duì)象的數(shù)據(jù)類型。

Collection接口中的方法

  1. 添加

    • add(Object obj)
    Collection collection = new ArrayList();
         
    collection.add("AA");
    collection.add("BB");
    collection.add(123);
    collection.add(new Date());
    
    System.out.println(collection);
    
    • addAll(Collection coll)
    Collection collection2 = new ArrayList();
    collection2.add(new Date());
    collection2.addAll(collection);
    System.out.println(collection2);
    
  2. 獲取有效元素的個(gè)數(shù)

    • int size()
    Collection collection = new ArrayList();
         
    collection.add("AA");
    collection.add("BB");
    collection.add(123);
    collection.add(new Date());
         
    System.out.println(collection.size());
    
  1. 清空集合

    • void clear()
    Collection collection = new ArrayList();
    
    collection.add("AA");
    collection.add("BB");
    collection.add(123);
    collection.add(new Date());
    
    System.out.println(collection.size());
    collection.clear();
    System.out.println(collection.size());
    
  1. 是否是空集合

    • boolean isEmpty()
    Collection collection = new ArrayList();
    
    collection.add("AA");
    collection.add("BB");
    collection.add(123);
    collection.add(new Date());
    
    System.out.println(collection.size());
    collection.clear();
    System.out.println(collection.isEmpty());
    
  1. 是否包含某個(gè)元素
    • boolean contains(Object obj):是通過元素的equals方法來判斷是否是同一個(gè)對(duì)象
   Collection collection = new ArrayList();
   
   collection.add("AA");
   collection.add("BB");
   collection.add(123);
   collection.add(new Date());
   
   System.out.println(collection.contains(123));
  • boolean containsAll(Collection c):也是調(diào)用元素的equals方法來比較的智袭。拿兩個(gè)集合的元素挨個(gè)比較奔缠。
Collection collection = new ArrayList();

collection.add("AA");
collection.add("BB");
collection.add(123);
collection.add(new Date());

System.out.println(collection.containsAll(Arrays.asList(123,"BB")));
  1. 刪除

    • boolean remove(Object obj) :通過元素的equals方法判斷是否是要?jiǎng)h除的那個(gè)元素。只會(huì)刪除找到的第一個(gè)元素
    Collection collection = new ArrayList();
    
    collection.add("AA");
    collection.add("BB");
    collection.add(123);
    collection.add(new Date());
    
    collection.remove("AA");
    System.out.println(collection);
    
    • boolean removeAll(Collection coll):取當(dāng)前集合的差集
    Collection collection = new ArrayList();
    
    collection.add("AA");
    collection.add("BB");
    collection.add(123);
    collection.add(new Date());
    
    System.out.println(collection);
    
    Collection collection2 = new ArrayList();
    collection2.add("BB");
    collection2.add(123);
    collection.removeAll(collection2);
    System.out.println(collection);
    
  2. 取兩個(gè)集合的交集

    • boolean retainAll(Collection c):把交集的結(jié)果存在當(dāng)前集合中吼野,不影響c
    Collection collection = new ArrayList();
    
    collection.add("AA");
    collection.add("BB");
    collection.add(123);
    collection.add(new Date());
    
    System.out.println(collection);
    
    
    Collection collection2 = new ArrayList();
    collection2.add("BB");
    collection2.add(123);
    collection.retainAll(collection2);
    System.out.println(collection);
    
  3. 集合是否相等

    • boolean equals(Object obj)
    Collection collection = new ArrayList();
    
    collection.add("AA");
    collection.add("BB");
    collection.add(123);
    collection.add(new Date());
    
    System.out.println(collection);
    
    
    Collection collection2 = new ArrayList();
    collection2.addAll(collection);
    System.out.println(collection.equals(collection2));
    
  4. 轉(zhuǎn)成對(duì)象數(shù)組

    • Object[] toArray()
    Collection collection = new ArrayList();
    
    collection.add("AA");
    collection.add("BB");
    collection.add(123);
    collection.add(new Date());
    
    System.out.println(Arrays.toString(collection.toArray()));
    
  5. 獲取集合對(duì)象的哈希值

    • hashCode()
    Collection collection = new ArrayList();
    
    collection.add("AA");
    collection.add("BB");
    collection.add(123);
    collection.add(new Date());
    
    System.out.println(collection.hashCode());
    
  6. 遍歷

    • iterator():返回迭代器對(duì)象添坊,用于集合遍歷
    Collection collection = new ArrayList();
    
    collection.add("AA");
    collection.add("BB");
    collection.add(123);
    collection.add(new Date());
    
    System.out.println(collection.iterator());  // java.util.ArrayList$Itr@7506e922
    

使用contains、containsAll箫锤、remove贬蛙、removeAll、retainAll谚攒、equals方法時(shí)阳准,被添加的數(shù)據(jù)對(duì)象所在類需要重寫equals方法

Iterator迭代器

Iterator迭代器接口

  • Iterator對(duì)象稱為迭代器(設(shè)計(jì)模式的一種)馏臭,主要用于遍歷 Collection 集合中的元素野蝇。
  • GOF給迭代器模式的定義為:提供一種方法訪問一個(gè)容器(container)對(duì)象中各個(gè)元素讼稚,而又不需暴露該對(duì)象的內(nèi)部細(xì)節(jié)。 迭代器模式绕沈,就是為容器而生锐想。類似于“公交車上的售票員”、“火車上的乘務(wù)員”乍狐、“空姐”赠摇。
  • Collection接口繼承了java.lang.Iterable接口,該接口有一個(gè)iterator()方法浅蚪,那么所有實(shí)現(xiàn)了Collection接口的集合類都有一個(gè)iterator()方法藕帜,用以返回一個(gè)實(shí)現(xiàn)了Iterator接口的對(duì)象。
  • Iterator僅用于遍歷集合惜傲,Iterator本身并不提供承裝對(duì)象的能力洽故。如果需要?jiǎng)?chuàng)建Iterator對(duì)象,則必須有一個(gè)被迭代的集合盗誊。
  • 集合對(duì)象每次調(diào)用iterator()方法都得到一個(gè)全新的迭代器對(duì)象时甚,默認(rèn)游標(biāo)都在集合的第一個(gè)元素之前。

Iterator接口的方法

返回類型 方法 描述
boolean hasNext() 如果迭代具有更多元素哈踱,則返回true 撞秋。
E next() 返回迭代中的下一個(gè)元素。
default void remove() 從底層集合中刪除此迭代器返回的最后一個(gè)元素(可選操作)嚣鄙。

在調(diào)用it.next()方法之前必須要調(diào)用it.hasNext()進(jìn)行檢測(cè)吻贿。若不調(diào)用,且下一條記錄無效哑子,直接調(diào)用it.next()會(huì)拋出NoSuchElementException異常舅列。

remove()示例
Iterator iter = coll.iterator();
while(iter.hasNext()){
  Object obj = iter.next();
  if(obj.equals("Tom")){
    iter.remove();
  }
}

注意:

  • Iterator可以刪除集合的元素,但是是遍歷過程中通過迭代器對(duì)象的remove方法卧蜓,不是集合對(duì)象的remove方法帐要。
  • 如果還未調(diào)用next()或在上一次調(diào)用next方法之后已經(jīng)調(diào)用了remove方法,再調(diào)用remove都會(huì)報(bào)IllegalStateException弥奸。

遍歷Collection元素

Collection collection = new ArrayList();

collection.add("AA");
collection.add("BB");
collection.add(123);
collection.add(new Date());
方式一:使用next()方法
System.out.println(iterator.next());
System.out.println(iterator.next());
System.out.println(iterator.next());
System.out.println(iterator.next());
方式二:使用for循環(huán)
for (int i = 0; i < collection.size(); i++) {
    System.out.println(iterator.next());
}
方式三:使用while循環(huán)
// hasNext():判斷是否還有下一個(gè)元素
while (iterator.hasNext()) {
  // next():①指針下移 ②將下移以后集合位置上的元素返回
    System.out.println(iterator.next());
}
方式四:使用foreach循環(huán)
// 內(nèi)部調(diào)用迭代器
for (Object object : collection) {
    System.out.println(object);
}

List接口

  • 鑒于Java中數(shù)組用來存儲(chǔ)數(shù)據(jù)的局限性榨惠,我們通常使用List替代數(shù)組
  • List集合類中 元素有序、且可重復(fù)盛霎,集合中的每個(gè)元素都有其對(duì)應(yīng)的順序索引赠橙。
  • List容器中的元素都對(duì)應(yīng)一個(gè)整數(shù)型的序號(hào)記載其在容器中的位置,可以根據(jù)序號(hào)存取容器中的元素愤炸。
  • JDK APIList接口的實(shí)現(xiàn)類常用的有:ArrayList期揪、LinkedListVector

方法

List除了從Collection集合繼承的方法外规个,List集合里添加了一些根據(jù)索引來操作集合元素的方法凤薛。

  • void add(int index, Object ele): 在index位置插入ele元素
  • boolean addAll(int index, Collection eles): 從index位置開始將eles中的所有元素添加進(jìn)來
  • Object get(int index): 獲取指定index位置的元素
  • int indexOf(Object obj): 返回obj在集合中首次出現(xiàn)的位置
  • int lastIndexOf(Object obj): 返回obj在當(dāng)前集合中末次出現(xiàn)的位置
  • Object remove(int index): 移除指定index位置的元素姓建,并返回此元素
  • Object set(int index, Object ele): 設(shè)置指定index位置的元素為ele
  • List subList(int fromIndex, int toIndex): 返回從fromIndextoIndex位置的子集合

實(shí)現(xiàn)類

|----List接口
    |----ArrayList實(shí)現(xiàn)類:作為L(zhǎng)ist接口的主要實(shí)現(xiàn)類;線程不安全缤苫,效率高速兔;底層使用`Object[] elementData`存儲(chǔ)
    |----LinkedList實(shí)現(xiàn)類:底層使用雙向鏈表存儲(chǔ);適用于`頻繁插入活玲、刪除操作`涣狗,操作效率比`ArrayList`高
    |----Vector實(shí)現(xiàn)類:List接口的古老實(shí)現(xiàn)類;線程安全翼虫,效率低屑柔;底層使用`Object[] elementData`存儲(chǔ)
ArrayList實(shí)現(xiàn)類
  • ArrayListList接口的典型實(shí)現(xiàn)類屡萤、主要實(shí)現(xiàn)類
  • 本質(zhì)上珍剑,ArrayList是對(duì)象引用的一個(gè)”變長(zhǎng)”數(shù)組
  • ArrayList的JDK1.8 之前與之后的實(shí)現(xiàn)區(qū)別?
    • JDK1.7:ArrayList像餓漢式死陆,直接創(chuàng)建一個(gè)初始容量為10的數(shù)組
    • JDK1.8:ArrayList像懶漢式招拙,一開始創(chuàng)建一個(gè)長(zhǎng)度為0的數(shù)組,當(dāng)添加第一個(gè)元素時(shí)再創(chuàng)建一個(gè)始容量為10的數(shù)組
  • Arrays.asList(…) 方法返回的List集合措译,既不是ArrayList實(shí)例别凤,也不是Vector實(shí)例。Arrays.asList(…) 返回值是一個(gè)固定長(zhǎng)度的List集合.
LinkedList實(shí)現(xiàn)類

對(duì)于頻繁的插入或刪除元素的操作领虹,建議使用LinkedList類规哪,效率較高。

LinkedList內(nèi)部使用雙向鏈表塌衰,沒有聲明數(shù)組诉稍,而是定義了Node類型的firstlast,用于記錄首末元素最疆。同時(shí)杯巨,定義內(nèi)部類Node,作為LinkedList中保存數(shù)據(jù)的基本結(jié)構(gòu)努酸。Node除了保存數(shù)據(jù)服爷,還定義了兩個(gè)變量:

  • prev變量記錄前一個(gè)元素的位置
  • next變量記錄下一個(gè)元素的位置

新增方法:

  • void addFirst(Object obj)
  • void addLast(Object obj)
  • Object getFirst()
  • Object getLast()
  • Object removeFirst()
  • Object removeLast()
Vector實(shí)現(xiàn)類
  • Vector是一個(gè)古老的集合,JDK1.0就有了获诈。大多數(shù)操作與ArrayList相同仍源,區(qū)別之處在于Vector是線程安全的。

  • 在各種list中舔涎,最好把ArrayList作為缺省選擇镜会。當(dāng)插入、刪除頻繁時(shí)终抽,使用LinkedList戳表;Vector總是比ArrayList慢桶至,所以盡量避免使用

新增方法:

  • void addElement(Object obj)
  • void insertElementAt(Object obj,int index)
  • void setElementAt(Object obj,int index)
  • void removeElement(Object obj)
  • void removeAllElements()

Set接口

  • Set接口是Collection的子接口匾旭,set接口沒有提供額外的方法
  • Set集合不允許包含相同的元素镣屹,如果試把兩個(gè)相同的元素加入同一個(gè)Set集合中,則添加操作失敗价涝。
  • Set判斷兩個(gè)對(duì)象是否相同不是使用==運(yùn)算符女蜈,而是根據(jù)equals()方法

實(shí)現(xiàn)類

|----Set接口
    |----HashSet實(shí)現(xiàn)類:作為Set接口的主要實(shí)現(xiàn)類;線程不安全色瘩;可以存儲(chǔ)null值
        |----LinkedHashSet實(shí)現(xiàn)類:作為HashSet的子類伪窖;遍歷其內(nèi)部數(shù)據(jù)時(shí),可以按照添加的順序遍歷居兆;對(duì)于頻繁的遍歷操作覆山,LinkedHashSet效率高于HashSet
    |----SortedSet接口
        |----TreeSet實(shí)現(xiàn)類:可以按照添加**對(duì)象的指定屬性**進(jìn)行排序;
HashSet實(shí)現(xiàn)類

HashSet中添加元素的過程:

  • 當(dāng)向HashSet集合中存入一個(gè)元素時(shí)泥栖,HashSet會(huì)調(diào)用該對(duì)象的hashCode()方法來得到該對(duì)象的hashCode值簇宽,然后根據(jù)hashCode值,通過某種散列函數(shù)決定該對(duì)象在HashSet底層數(shù)組中的存儲(chǔ)位置吧享。(這個(gè)散列函數(shù)會(huì)與底層數(shù)組的長(zhǎng)度相計(jì)算得到在數(shù)組中的下標(biāo)魏割,并且這種散列函數(shù)計(jì)算還盡可能保證能均勻存儲(chǔ)元素,越是散列分布钢颂,該散列函數(shù)設(shè)計(jì)的越好
  • 如果兩個(gè)元素的hashCode()值相等钞它,會(huì)再繼續(xù)調(diào)用equals方法,如果equals方法結(jié)果為true殊鞭,添加失斣舛狻;如果為false钱豁,那么會(huì)保存該元素耻卡,但是該數(shù)組的位置已經(jīng)有元素了,那么會(huì)通過鏈表的方式繼續(xù)鏈接牲尺。

如果兩個(gè)元素的equals()方法返回true卵酪,但它們的hashCode()返回值不相等,hashSet將會(huì)把它們存儲(chǔ)在不同的位置谤碳,但依然可以添加成功溃卡。

底層也是數(shù)組,初始容量為16蜒简,當(dāng)如果使用率超過0.75瘸羡,(16*0.75=12)就會(huì)擴(kuò)大容量為原來的2倍。(16擴(kuò)容為32搓茬,依次為64,128....等)

重寫hashCode()方法的基本原則

  • 在程序運(yùn)行時(shí)犹赖,同一個(gè)對(duì)象多次調(diào)用hashCode()方法應(yīng)該返回相同的值队他。
  • 當(dāng)兩個(gè)對(duì)象的equals()方法比較返回true時(shí),這兩個(gè)對(duì)象的hashCode()方法的返回值也應(yīng)相等峻村。
  • 對(duì)象中用作equals()方法比較的Field麸折,都應(yīng)該用來計(jì)算hashCode值。

問題:為什么用Eclipse/IDEA復(fù)寫hashCode方法粘昨,有31這個(gè)數(shù)字垢啼?

  1. 選擇系數(shù)的時(shí)候要選擇盡量大的系數(shù)。因?yàn)槿绻?jì)算出來的hash地址越大张肾,所謂的“沖突”就越少芭析,查找起來效率也會(huì)提高。(減少?zèng)_突)
  2. 31只占用5bits吞瞪,相乘造成數(shù)據(jù)溢出的概率較小馁启。
  3. 31可以由i*31==(i<<5)-1來表示,現(xiàn)在很多虛擬機(jī)里面都有做相關(guān)優(yōu)化。(提高算法效率)
  4. 31是一個(gè)素?cái)?shù)尸饺,素?cái)?shù)作用就是进统,如果我用一個(gè)數(shù)字來乘以這個(gè)素?cái)?shù)助币,那么最終出來的結(jié)果只能被素?cái)?shù)本身和被乘數(shù)還有1來整除浪听!(減少?zèng)_突)

重寫equals()方法的基本原則

復(fù)寫equals方法的時(shí)候一般都需要同時(shí)復(fù)寫hashCode方法。通常參與計(jì)算hashCode的對(duì)象的屬性也應(yīng)該參與到equals()眉菱。

LinkedHashSet實(shí)現(xiàn)類
  • LinkedHashSetHashSet的子類
  • LinkedHashSet根據(jù)元素的hashCode值來決定元素的存儲(chǔ)位置迹栓,但它同時(shí)使用雙向鏈表維護(hù)元素的次序,這使得元素看起來是以插入順序保存的俭缓。
  • LinkedHashSet插入性能略低于HashSet克伊,但在迭代訪問Set里的全部元素時(shí)有很好的性能。
  • LinkedHashSet不允許集合元素重復(fù)华坦。

LinkedHashSet中每個(gè)元素都是被鏈表的Node節(jié)點(diǎn)包裝的愿吹,節(jié)點(diǎn)中包含指向上一個(gè)節(jié)點(diǎn)和下一個(gè)節(jié)點(diǎn)的指針。

TreeSet實(shí)現(xiàn)類
  • TreeSetSortedSet接口的實(shí)現(xiàn)類惜姐,TreeSet可以確保集合元素處于排序狀態(tài)犁跪。
  • TreeSet底層使用紅黑結(jié)構(gòu)存儲(chǔ)數(shù)據(jù)。
  • TreeSet中添加的數(shù)據(jù)歹袁,要求是相同類的對(duì)象

新增的方法:

  • Comparator comparator()
  • Object first()
  • Object last()
  • Object lower(Object e)
  • Object higher(Object e)
  • SortedSet subSet(fromElement, toElement)
  • SortedSet headSet(toElement)
  • SortedSet tailSet(fromElement)

TreeSet和后面要講的TreeMap采用紅黑樹的存儲(chǔ)結(jié)構(gòu)坷衍。特點(diǎn):有序,查詢速度比List快条舔。

兩種排序方法:自然排序定制排序枫耳。默認(rèn)情況下,TreeSet采用自然排序孟抗。

自然排序

  • TreeSet會(huì)調(diào)用集合元素的compareTo(Object obj)方法來比較元素之間的大小關(guān)系迁杨,然后將集合元素按升序(默認(rèn)情況)排列

  • <span style="color:red;">如果試圖把一個(gè)對(duì)象添加到TreeSet時(shí)钻心,則該對(duì)象的類必須實(shí)現(xiàn)Comparable接口。</span>

    • 實(shí)現(xiàn)Comparable的類必須實(shí)現(xiàn)compareTo(Object obj)方法铅协,兩個(gè)對(duì)象即通過compareTo(Object obj)方法的返回值來比較大小扔役。
  • Comparable的典型實(shí)現(xiàn)

    • BigDecimalBigInteger以及所有的數(shù)值型對(duì)應(yīng)的包裝類:按它們對(duì)應(yīng)的數(shù)值大小進(jìn)行比較
    • Character:按字符的unicode`值來進(jìn)行比較
    • Booleantrue對(duì)應(yīng)的包裝類實(shí)例大于false對(duì)應(yīng)的包裝類實(shí)例
    • String:按字符串中字符的unicode值進(jìn)行比較
    • Date警医、Time:后邊的時(shí)間亿胸、日期比前面的時(shí)間、日期大
  • TreeSet中添加元素時(shí)预皇,只有第一個(gè)元素?zé)o須比較compareTo()方法侈玄,后面添加的所有元素都會(huì)調(diào)用compareTo()方法進(jìn)行比較。

  • <span style="color:red;">因?yàn)橹挥邢嗤惖膬蓚€(gè)實(shí)例才會(huì)比較大小吟温,所以向TreeSet中添加的應(yīng)該是同一個(gè)類的對(duì)象序仙。</span>

  • 對(duì)于TreeSet集合 而言,它判斷兩個(gè)對(duì)象是否相等的唯一標(biāo)準(zhǔn)是:兩個(gè)對(duì)象通過compareTo(Object obj)方法比較返回值鲁豪。

  • 當(dāng)需要把一個(gè)對(duì)象放入TreeSet中潘悼,重寫該對(duì)象對(duì)應(yīng)的equals()方法時(shí),應(yīng)保證該方法與compareTo(Object obj)方法有一致的結(jié)果:如果兩個(gè)對(duì)象通過equals()方法比較返回true爬橡,則通過compareTo(Object obj)方法比較應(yīng)返回0治唤。否則,讓人難以理解糙申。

// User類宾添,實(shí)現(xiàn)Comparable接口,用于TreeSet添加時(shí)進(jìn)行比較
public class User implements Comparable {
    private String name;
    private int age;

    public User() {
    }

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        User other = (User) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "User [name=" + name + ", age=" + age + "]";
    }

  // 按姓名由小到大柜裸,年齡由小到大排列
    @Override
    public int compareTo(Object o) {
        if (o instanceof User) {
            User another = (User) o;
            int compareTo = this.name.compareTo(another.name);
            if (compareTo != 0) {
                return compareTo;
            } else {
                return Integer.compare(this.age, another.age);
            }
        } else {
            throw new RuntimeException("類型不匹配");
        }
    }
  
}


@Test
public void testTreeSet() {
  TreeSet treeSet = new TreeSet();

  treeSet.add(new User("Tom", 12));
  treeSet.add(new User("Jerry", 23));
  treeSet.add(new User("Kim", 16));
  treeSet.add(new User("Mary", 24));
  treeSet.add(new User("Rose", 12));
  treeSet.add(new User("Kim", 13));

  for (Object object : treeSet) {
    System.out.println(object);
  }
}

輸出:

User [name=Jerry, age=23]
User [name=Kim, age=13]
User [name=Kim, age=16]
User [name=Mary, age=24]
User [name=Rose, age=12]
User [name=Tom, age=12]

定制排序

  • TreeSet的自然排序要求元素所屬的類實(shí)現(xiàn)Comparable接口缕陕,如果元素所屬的類沒有實(shí)現(xiàn)Comparable接口,或不希望按照升序(默認(rèn)情況)的方式排列元素或希望按照其它屬性大小進(jìn)行排序疙挺,則考慮使用定制排序扛邑。定制排序,通過Comparator接口來實(shí)現(xiàn)铐然。需要重寫compare(T o1,T o2)方法蔬崩。
  • 利用int compare(T o1,T o2)方法,比較o1o2的大薪蹙簟:如果方法返回正整數(shù)舱殿,則表示o1大于o2;如果返回0险掀,表示相等沪袭;返回負(fù)整數(shù),表示o1小于o2
  • 要實(shí)現(xiàn)定制排序冈绊,需要將實(shí)現(xiàn)Comparator接口的實(shí)例作為形參傳遞給TreeSet的構(gòu)造器侠鳄。
  • 此時(shí),仍然只能向TreeSet中添加類型相同的對(duì)象死宣。否則發(fā)生ClassCastException異常伟恶。
  • 使用定制排序判斷兩個(gè)元素相等的標(biāo)準(zhǔn)是:通過Comparator比較兩個(gè)元素返回了0。
@Test
public void testTreeSetComparator() {
  // 按年齡由大到小排列
  Comparator<User> comparator = new Comparator<User>() {
  @Override
  public int compare(User o1, User o2) {
  return -Integer.compare(o1.getAge(), o2.getAge());
  }
  };

  TreeSet treeSet = new TreeSet(comparator);

  treeSet.add(new User("Tom", 12));
  treeSet.add(new User("Jerry", 23));
  treeSet.add(new User("Kim", 16));
  treeSet.add(new User("Mary", 24));
  treeSet.add(new User("Rose", 12));
  treeSet.add(new User("Kim", 13));

  for (Object object : treeSet) {
    System.out.println(object);
  }

}

輸出:由于new User("Rose", 12)new User("Tom", 12))的年齡相同毅该,比較的返回值為0博秫,且排在Tom的后面,就會(huì)認(rèn)為RoseTom是相同的眶掌,所以沒有添加到TreeSet中去挡育。

User [name=Mary, age=24]
User [name=Jerry, age=23]
User [name=Kim, age=16]
User [name=Kim, age=13]
User [name=Tom, age=12]

?????????????????????????????????????????????????????????????????????????

自然排序中,比較兩個(gè)對(duì)象是否相同的標(biāo)準(zhǔn)為:compareTo()返回0朴爬,不再是equals()即寒。

定制排序中,比較兩個(gè)對(duì)象是否相同的標(biāo)準(zhǔn)為:compare()返回0召噩,不再是equals()母赵。

?????????????????????????????????????????????????????????????????????????

Map接口

  • MapCollection并列存在。用于保存具有 映射關(guān)系的數(shù)據(jù):key-value
  • Map中的keyvalue都可以是任何引用類型的數(shù)據(jù)
  • Map 中的 key 用Set來存放具滴, 不允許重復(fù)凹嘲,即同一個(gè) Map 對(duì)象所對(duì)應(yīng)的類,須重寫hashCode()和equals()方法
  • 常用String類作為Map的“鍵”
  • key 和 value 之間存在單向一對(duì)一關(guān)系抵蚊,即通過指定的 key 總能找到唯一的施绎、確定的 value
  • Map接口的常用實(shí)現(xiàn)類:HashMap溯革、TreeMap贞绳、LinkedHashMap和Properties。其中致稀,HashMap是 Map 接口使用頻率最高的實(shí)現(xiàn)類

繼承結(jié)構(gòu)

|----Map接口:雙列集合
    |----HashMap實(shí)現(xiàn)類:作為Map的主要實(shí)現(xiàn)類冈闭;線程不安全,效率高抖单;可以存儲(chǔ)null的key和value萎攒;key所在類要重寫equals()和hashCode();value所在類要重寫equals()
        |----LinkedHashMap實(shí)現(xiàn)類:保證在遍歷map元素時(shí)矛绘,可以按照添加的順序?qū)崿F(xiàn)遍歷耍休。原因:在原有的HashMap底層結(jié)構(gòu)上,添加一對(duì)指針货矮,指向前一個(gè)和后一個(gè)元素羊精,對(duì)于頻繁的遍歷操作,此類執(zhí)行效率高于HashMap囚玫。
    |----SortedMap接口
        |----TreeMap實(shí)現(xiàn)類:保證按照添加的key-value進(jìn)行排序喧锦,實(shí)現(xiàn)排序遍歷读规。考慮key的自然排序或定制排序燃少。底層使用紅黑樹
    |----Hashtable實(shí)現(xiàn)類:古老的實(shí)現(xiàn)類束亏;線程安全,效率低阵具;不能存儲(chǔ)null的key和value
        |----Properties實(shí)現(xiàn)類:常用來處理配置文件碍遍。key和value都是String類型。

HashMap和Hashtable的關(guān)系類似于ArrayList和Vector的關(guān)系阳液,HashMap和ArrayList要比Hashtable和Vector新雀久,所以后續(xù)使用時(shí),主要使用HashMap和ArrayList趁舀。

Map結(jié)構(gòu)的理解

  • Map中的key:無序的赖捌、不可重復(fù)的愧膀,使用Set存儲(chǔ)所有的key --> key所在類要重寫equals()和hashCode()(以HashMap為例)
  • Map中的value:無序的权逗、可重復(fù)的,使用Collection存儲(chǔ)所有的value --> value所在的類要重寫equals()
  • 一個(gè)鍵值對(duì):key-value構(gòu)成一個(gè)Entry對(duì)象
  • Map中的entry:無序的诺舔、不可重復(fù)的奉狈,使用Set存儲(chǔ)所有的entry

常用方法

  • 添加卤唉、刪除、修改操作:
    • Object put(Object key,Object value):將指定key-value添加到(或修改)當(dāng)前map對(duì)象中
    • void putAll(Map m):將m中的所有key-value對(duì)存放到當(dāng)前map中
    • Object remove(Object key):移除指定key的key-value對(duì)仁期,并返回value
    • void clear():清空當(dāng)前map中的所有數(shù)據(jù)
  • 元素 查詢的操作:
    • Object get(Object key):獲取指定key對(duì)應(yīng)的value
    • boolean containsKey(Object key):是否包含指定的key
    • boolean containsValue(Object value):是否包含指定的value
    • int size():返回map中key-value對(duì)的個(gè)數(shù)
    • boolean isEmpty():判斷當(dāng)前map是否為空
    • boolean equals(Object obj):判斷當(dāng)前map和參數(shù)對(duì)象obj是否相等
  • 元視圖操作的方法:
    • Set keySet():返回所有key構(gòu)成的Set集合
    • Collection values():返回所有value構(gòu)成的Collection集合
    • Set entrySet():返回所有key-value對(duì)構(gòu)成的Set集合

實(shí)現(xiàn)類

HashMap實(shí)現(xiàn)類

  • HashMapMap接口使用頻率最高的實(shí)現(xiàn)類桑驱。

  • 允許使用null鍵和null值,與HashSet一樣跛蛋,不保證映射的順序熬的。

  • 所有的key構(gòu)成的集合是Set:無序的、不可重復(fù)的赊级。所以押框,key所在的類要重寫:equals()hashCode()

  • 所有的value構(gòu)成的集合是Collection:無序的、可以重復(fù)的理逊。所以橡伞,value所在的類要重寫:equals()

  • 一個(gè)key-value構(gòu)成一個(gè)entry

  • 所有的entry構(gòu)成的集合是Set:無序的、不可重復(fù)的

  • HashMap判斷兩個(gè)key相等的標(biāo)準(zhǔn)是:兩個(gè)key通過equals()方法返回true晋被,hashCode值也相等兑徘。

  • HashMap判斷兩個(gè)value相等的標(biāo)準(zhǔn)是:兩個(gè)value通過equals()方法返回true

HashMap的存儲(chǔ)結(jié)構(gòu)
JDK 7及以前版本:HashMap是數(shù)組+鏈表結(jié)構(gòu)(即為鏈地址法)羡洛。

HashMap的內(nèi)部存儲(chǔ)結(jié)構(gòu)其實(shí)是數(shù)組和鏈表的結(jié)合挂脑。當(dāng)實(shí)例化一個(gè)HashMap時(shí),系統(tǒng)會(huì)創(chuàng)建一個(gè)長(zhǎng)度為CapacityEntry數(shù)組,這個(gè)長(zhǎng)度在哈希表中被稱為容量(Capacity)最域,在這個(gè)數(shù)組中可以存放元素的位置我們稱之為“桶”(bucket)谴分,每個(gè)bucket都有自己的索引,系統(tǒng)可以根據(jù)索引快速的查找bucket中的元素镀脂。

每個(gè)bucket中存儲(chǔ)一個(gè)元素牺蹄,即一個(gè)Entry對(duì)象,但每一個(gè)Entry對(duì)象可以帶一個(gè)引用變量薄翅,用于指向下一個(gè)元素沙兰,因此,在一個(gè)桶中翘魄,就有可能生成一個(gè)Entry鏈鼎天。而且新添加的元素作為鏈表的head

添加元素的過程

HashMap中添加entry1(key暑竟,value)斋射,需要首先計(jì)算entry1key的哈希值(根據(jù)key所在類的hashCode()計(jì)算得到),此哈希值經(jīng)過處理以后但荤,得到在底層Entry[]數(shù)組中要存儲(chǔ)的位置i罗岖。如果位置i上沒有元素,則entry1直接添加成功腹躁。如果位置i上已經(jīng)存在entry2(或還有鏈表存在的entry3桑包,entry4),則需要通過循環(huán)的方法纺非,依次比較entry1key和其他的entry哑了。如果彼此hash不同,則直接添加成功烧颖。如果hash值不同弱左,繼續(xù)比較二者是否equals。如果返回值為true倒信,則使用entry1value去替換equalstrueentryvalue科贬。如果遍歷一遍以后,發(fā)現(xiàn)所有的equals返回都為false,則entry1仍可添加成功鳖悠。entry1指向原有的entry元素。

HashMap的擴(kuò)容

當(dāng)HashMap中的元素越來越多的時(shí)候优妙,hash沖突的幾率也就越來越高乘综,因?yàn)閿?shù)組的長(zhǎng)度是固定的。所以為了提高查詢的效率套硼,就要對(duì)HashMap的數(shù)組進(jìn)行擴(kuò)容卡辰,而在HashMap數(shù)組擴(kuò)容之后,最消耗性能的點(diǎn)就出現(xiàn)了:原數(shù)組中的數(shù)據(jù)必須重新計(jì)算其在新數(shù)組中的位置,并放進(jìn)去九妈,這就是resize反砌。

HashMap的擴(kuò)容時(shí)機(jī)

當(dāng)HashMap中的元素個(gè)數(shù)超過數(shù)組大小(數(shù)組總大小length,不是數(shù)組中個(gè)數(shù)size)loadFactor*時(shí),就會(huì)進(jìn)行數(shù)組擴(kuò)容萌朱,loadFactor的默認(rèn)值(DEFAULT_LOAD_FACTOR)為0.75宴树,這是一個(gè)折中的取值。也就是說晶疼,默認(rèn)情況下酒贬,數(shù)組大小(DEFAULT_INITIAL_CAPACITY)為16,那么當(dāng)HashMap中元素個(gè)數(shù)超過16*0.75=12(這個(gè)值就是代碼中的threshold值翠霍,也叫做臨界值)的時(shí)候锭吨,就把數(shù)組的大小擴(kuò)展為2*16=32,即擴(kuò)大一倍寒匙,然后重新計(jì)算每個(gè)元素在數(shù)組中的位置零如,而這是一個(gè)非常消耗性能的操作,所以如果我們已經(jīng)預(yù)知HashMap中元素的個(gè)數(shù)锄弱,那么預(yù)設(shè)元素的個(gè)數(shù)能夠有效的提高HashMap的性能埠况。

簡(jiǎn)述HashMap map = new HashMap();的過程:

實(shí)例化后,底層創(chuàng)建了長(zhǎng)度是16的一維數(shù)組Entry[] table棵癣。

調(diào)用map.put(key1, value1)存放元素時(shí):首先辕翰,調(diào)用key1所在類的hashCode()計(jì)算key1的哈希值,此哈希值經(jīng)過某種算法計(jì)算以后狈谊,得到在Entry數(shù)組中的存放位置喜命。

  • 如果此位置上的數(shù)據(jù)為空,此時(shí)key1-value1添加成功
  • 如果此位置上的數(shù)據(jù)不為空(意味著此位置上存在一個(gè)或多個(gè)數(shù)據(jù)(以鏈表形式存在))河劝,比較key1和已經(jīng)存在的一個(gè)或多個(gè)數(shù)據(jù)的哈希值:
    • 如果key1的哈希值與已經(jīng)存在的數(shù)據(jù)的哈希值都不相同壁榕,此時(shí)key1-value1添加成功。
    • 如果key1的哈希值和已經(jīng)存在的某一個(gè)數(shù)據(jù)(key2-value2)的哈希值相同赎瞎,繼續(xù)比較:調(diào)用key1所在類的equals()方法牌里,進(jìn)行比較:
      • 如果equals()返回false:此時(shí)key1-value1添加成功。
      • 如果equals()返回true:使用value1替換value2值务甥。

擴(kuò)容方式:擴(kuò)容為原來容量的2倍牡辽,并將原有的數(shù)據(jù)復(fù)制過來。

JDK 8版本發(fā)布以后:HashMap是數(shù)組+鏈表+紅黑樹實(shí)現(xiàn)敞临。

HashMap的內(nèi)部存儲(chǔ)結(jié)構(gòu)其實(shí)是數(shù)組+鏈表+樹的結(jié)合态辛。當(dāng)實(shí)例化一個(gè)HashMap時(shí),會(huì)初始化initialCapacityloadFactor挺尿,在put第一對(duì)映射關(guān)系時(shí)奏黑,系統(tǒng)會(huì)創(chuàng)建一個(gè)長(zhǎng)度為initialCapacityNode數(shù)組炊邦,這個(gè)長(zhǎng)度在哈希表
中被稱為容量(Capacity),在這個(gè)數(shù)組中可以存放元素的位置我們稱之為“桶”(bucket)熟史,每個(gè)bucket都有自己的索引馁害,系統(tǒng)可以根據(jù)索引快速的查找bucket中的元素。

每個(gè)bucket中存儲(chǔ)一個(gè)元素蹂匹,即一個(gè)Node對(duì)象碘菜,但每一個(gè)Node對(duì)象可以帶一個(gè)引用變量next,用于指向下一個(gè)元素怒详,因此炉媒,在一個(gè)桶中,就有可能生成一個(gè)Node鏈昆烁。也可能是一個(gè)一個(gè)TreeNode對(duì)象吊骤,每一個(gè)TreeNode對(duì)象可以有兩個(gè)葉子結(jié)點(diǎn)leftright,因此静尼,在一個(gè)桶中白粉,就有可能生成一個(gè)TreeNode樹。而新添加的元素作為鏈表的last鼠渺,或樹的葉子結(jié)點(diǎn)鸭巴。

HashMap進(jìn)行擴(kuò)容和樹形化的時(shí)機(jī)

當(dāng)HashMap中的元素個(gè)數(shù)超過數(shù)組大小(數(shù)組總大小length,不是數(shù)組中個(gè)數(shù)size)loadFactor*時(shí),就會(huì)進(jìn)行數(shù)組擴(kuò)容拦盹,loadFactor的默認(rèn)值(DEFAULT_LOAD_FACTOR)為0.75鹃祖,這是一個(gè)折中的取值。也就是說普舆,默認(rèn)情況下恬口,數(shù)組大小(DEFAULT_INITIAL_CAPACITY)為16,那么當(dāng)HashMap中元素個(gè)數(shù)超過16*0.75=12(這個(gè)值就是代碼中的threshold值沼侣,也叫做臨界值)的時(shí)候祖能,就把數(shù)組的大小擴(kuò)展為2*16=32,即擴(kuò)大一倍蛾洛,然后重新計(jì)算每個(gè)元素在數(shù)組中的位置养铸,而這是一個(gè)非常消耗性能的操作,所以如果我們已經(jīng)預(yù)知HashMap中元素的個(gè)數(shù)轧膘,那么預(yù)設(shè)元素的個(gè)數(shù)能夠有效的提高HashMap的性能钞螟。

當(dāng)HashMap中的其中一個(gè)鏈的對(duì)象個(gè)數(shù)如果達(dá)到了8個(gè),此時(shí)如果capacity沒有達(dá)到64扶供,那么HashMap會(huì)先擴(kuò)容解決筛圆,如果已經(jīng)達(dá)到了64,那么這個(gè)鏈會(huì)變成樹椿浓,結(jié)點(diǎn)類型由Node變成TreeNode類型太援。當(dāng)然,如果當(dāng)映射關(guān)系被移除后扳碍,下次resize方法時(shí)判斷樹的結(jié)點(diǎn)個(gè)數(shù)低于6個(gè)提岔,也會(huì)把樹再轉(zhuǎn)為鏈表。

對(duì)比JDK 7和JDK 8
  1. HashMap map = new HashMap();//默認(rèn)情況下笋敞,先不創(chuàng)建長(zhǎng)度為16的數(shù)組
  2. 當(dāng)首次調(diào)用map.put()時(shí)碱蒙,再創(chuàng)建長(zhǎng)度為16的數(shù)組
  3. 數(shù)組為Node類型,在jdk7中稱為Entry類型
  4. 形成鏈表結(jié)構(gòu)時(shí)夯巷,新添加的key-value對(duì)在鏈表的尾部(七上八下)
  5. 當(dāng)數(shù)組指定索引位置的鏈表長(zhǎng)度>8時(shí)赛惩,且map中的數(shù)組的長(zhǎng)度>64時(shí),此索引位置上的所有key-value對(duì)使用紅黑樹進(jìn)行存儲(chǔ)

LinkedHashMap實(shí)現(xiàn)類

  • LinkedHashMap是HashMap的子類

  • HashMap存儲(chǔ)結(jié)構(gòu)的基礎(chǔ)上趁餐,使用了一對(duì)雙向鏈表來記錄添加元素的順序

  • LinkedHashSet類似喷兼,LinkedHashMap可以維護(hù)Map的迭代順序:迭代順序與Key-Value對(duì)的插入順序一致

HashMap中的內(nèi)部類:Node

static class Node<K,V> implements Map.Entry<K,V> {
  final int hash;
  final K key;
  V value;
  Node<K,V> next;
}

LinkedHashMap中的內(nèi)部類:Entry

static class Entry<K,V> extends HashMap.Node<K,V> {
  Entry<K,V> before, after;
  Entry(int hash, K key, V value, Node<K,V> next) {
    super(hash, key, value, next);
  }
}

TreeMap實(shí)現(xiàn)類

  • TreeMap存儲(chǔ)Key-Value對(duì)時(shí),需要根據(jù)key-value對(duì)進(jìn)行排序后雷。TreeMap可以保證所有的Key-Value對(duì)處于有序狀態(tài)季惯。
  • TreeSet底層使用紅黑樹結(jié)構(gòu)存儲(chǔ)數(shù)據(jù)
  • TreeMapKey的排序:
    • 自然排序:TreeMap的所有的Key必須實(shí)現(xiàn)Comparable接口,而且所有的Key應(yīng)該是同一個(gè)類的對(duì)象臀突,否則將會(huì)拋出ClasssCastException
    • 定制排序:創(chuàng)建TreeMap時(shí)勉抓,傳入一個(gè)Comparator對(duì)象,該對(duì)象負(fù)責(zé)對(duì)TreeMap中的所有key進(jìn)行排序候学。此時(shí)不需要MapKey實(shí)現(xiàn)Comparable接口
  • TreeMap判斷兩個(gè)key相等的標(biāo)準(zhǔn):兩個(gè)key通過compareTo()方法或者compare()方法返回0藕筋。

Hashtable實(shí)現(xiàn)類(古老)

  • Hashtable是個(gè)古老的Map實(shí)現(xiàn)類,JDK1.0就提供了梳码。不同于HashMap隐圾,Hashtable是線程安全的。
  • Hashtable實(shí)現(xiàn)原理和HashMap相同边翁,功能相同翎承。底層都使用哈希表結(jié)構(gòu),查詢速度快符匾,很多情況下可以互用叨咖。
  • HashMap不同,Hashtable不允許使用null作為keyvalue
  • HashMap一樣啊胶,Hashtable也不能保證其中Key-Value對(duì)的順序
  • Hashtable判斷兩個(gè)key相等甸各、兩個(gè)value相等的標(biāo)準(zhǔn),與HashMap一致焰坪。

Properties實(shí)現(xiàn)類

  • Properties類是Hashtable的子類趣倾,該對(duì)象用于處理屬性文件
  • 由于屬性文件里的keyvalue都是字符串類型某饰,所以Properties里的keyvalue都是字符串類型
  • 存取數(shù)據(jù)時(shí)儒恋,建議使用setProperty(String key,String value)方法和getProperty(String key)方法

例:

Properties pros = new Properties();
pros.load(new FileInputStream("jdbc.properties"));
String user = pros.getProperty("user");
System.out.println(user);

Collections工具類

  • Collections是一個(gè)操作Set善绎、ListMap等集合的工具類

  • Collections中提供了一系列靜態(tài)的方法對(duì)集合元素進(jìn)行排序、查詢和修改等操作诫尽,還提供了對(duì)集合對(duì)象設(shè)置不可變禀酱、對(duì)集合對(duì)象實(shí)現(xiàn)同步控制等方法

  • 排序操作:為(均為static方法)

    • reverse(List):反轉(zhuǎn)List中元素的順序
    • shuffle(List):對(duì)List集合元素進(jìn)行隨機(jī)排序
    • sort(List):根據(jù)元素的自然順序?qū)χ付?code>List集合元素按升序排序
    • sort(List,Comparator):根據(jù)指定的Comparator產(chǎn)生的順序?qū)?code>List集合元素進(jìn)行排序
    • swap(List牧嫉,int剂跟,int):將指定list集合中的i處元素和j處元素進(jìn)行交換
  • 查找、替換:

    • Object max(Collection):根據(jù)元素的自然順序酣藻,返回給定集合中的最大元素
    • Object max(Collection曹洽,Comparator):根據(jù)Comparator指定的順序,返回給定集合中的最大元素
    • Object min(Collection)
    • Object min(Collection辽剧,Comparator)
    • int frequency(Collection送淆,Object):返回指定集合中指定元素的出現(xiàn)次數(shù)
    • void copy(List dest,List src):將src中的內(nèi)容復(fù)制到dest
    • boolean replaceAll(List list,Object oldVal抖仅,Object newVal):使用新值替換List對(duì)象的所有舊值
  • 同步控制:Collections類中提供了多個(gè)synchronizedXxx()方法坊夫,該方法可使將指定集合包裝成線程同步的集合,從而可以解決多線程并發(fā)訪問集合時(shí)的線程安全問題

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末撤卢,一起剝皮案震驚了整個(gè)濱河市环凿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌放吩,老刑警劉巖智听,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異渡紫,居然都是意外死亡到推,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門惕澎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來莉测,“玉大人,你說我怎么就攤上這事唧喉〉仿保” “怎么了?”我有些...
    開封第一講書人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵八孝,是天一觀的道長(zhǎng)董朝。 經(jīng)常有香客問我,道長(zhǎng)干跛,這世上最難降的妖魔是什么子姜? 我笑而不...
    開封第一講書人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮楼入,結(jié)果婚禮上哥捕,老公的妹妹穿的比我還像新娘牧抽。我一直安慰自己,他們只是感情好扭弧,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開白布阎姥。 她就那樣靜靜地躺著记舆,像睡著了一般鸽捻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上泽腮,一...
    開封第一講書人閱讀 49,185評(píng)論 1 284
  • 那天御蒲,我揣著相機(jī)與錄音,去河邊找鬼诊赊。 笑死厚满,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的碧磅。 我是一名探鬼主播碘箍,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼鲸郊!你這毒婦竟也來了丰榴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤秆撮,失蹤者是張志新(化名)和其女友劉穎四濒,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體职辨,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡盗蟆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了舒裤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片喳资。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖腾供,靈堂內(nèi)的尸體忽然破棺而出仆邓,到底是詐尸還是另有隱情,我是刑警寧澤台腥,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布宏赘,位于F島的核電站,受9級(jí)特大地震影響黎侈,放射性物質(zhì)發(fā)生泄漏察署。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一峻汉、第九天 我趴在偏房一處隱蔽的房頂上張望贴汪。 院中可真熱鬧脐往,春花似錦、人聲如沸扳埂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽阳懂。三九已至梅尤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間岩调,已是汗流浹背巷燥。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留号枕,地道東北人缰揪。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像葱淳,于是被迫代替她去往敵國(guó)和親钝腺。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

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

  • 認(rèn)識(shí)Collection接口 Collection接口是單值保存的最大父類接口赞厕。Collection中的常用方法如...
    漁樵店閱讀 413評(píng)論 0 2
  • Collection Collection:Collection接口是集合類的根接口艳狐,它有兩個(gè)接口,List是一個(gè)...
    Active_Loser閱讀 381評(píng)論 0 0
  • 集合概述 什么是集合 集合框架:用于存儲(chǔ)數(shù)據(jù)的容器坑傅。 集合框架是為表示和操作集合而規(guī)定的一種統(tǒng)一的標(biāo)準(zhǔn)的體系結(jié)構(gòu)僵驰。...
  • Java集合分為四類分別為 Map:無序,具有key-value映射的集合唁毒,里面有一個(gè)entry類蒜茴,里面有key和...
    小李同學(xué)今天博學(xué)了嗎閱讀 255評(píng)論 0 3
  • 這周的學(xué)習(xí)還是比較認(rèn)真的。 以下是目前收集整理的一些筆記浆西, 還有Map接口沒學(xué)粉私, 下次再補(bǔ)。 (word文檔復(fù)制過...
    _秋褲閱讀 863評(píng)論 0 0