Java:集合

1. Java集合框架概述

1.1 集合定義

集合涤久、數(shù)組都是對(duì)多個(gè)數(shù)據(jù)進(jìn)行存儲(chǔ)操作的結(jié)構(gòu),簡(jiǎn)稱Java容器费韭。

面向?qū)ο笳Z(yǔ)言對(duì)事物的體現(xiàn)都是以對(duì)象的形式盗舰,為了方便對(duì)多個(gè)對(duì)象的操作便监,就要對(duì)對(duì)象進(jìn)行存儲(chǔ)扎谎。

而使用Array存儲(chǔ)對(duì)象方面具有一些弊端。

數(shù)組的弊端

  • 數(shù)組初始化以后烧董,長(zhǎng)度就不可變了毁靶,不便于擴(kuò)展
  • 數(shù)組中提供的屬性和方法少,不便于進(jìn)行添加逊移、刪除预吆、插入等操作,且效率不高胳泉。
  • 存儲(chǔ)數(shù)據(jù)的特點(diǎn)單一拐叉,存儲(chǔ)的數(shù)據(jù)是有序的、可以重復(fù)的扇商。

Java 集合類可以用于存儲(chǔ)數(shù)量不等的多個(gè)對(duì)象凤瘦,還可用于保存具有映射關(guān)系的關(guān)聯(lián)數(shù)組。

1.2 集合概述

Java集合可分為Collection和Map兩種體系:

  1. Collection接口:?jiǎn)瘟袛?shù)據(jù)案铺,定義了存取一組對(duì)象的方法的集合

    • List:元素有序蔬芥、可重復(fù)的集合,實(shí)現(xiàn)類:ArrayList、LinkedList笔诵、Vector
    • Set:元素?zé)o序返吻、不可重復(fù)的集合,實(shí)現(xiàn)類:HashSet乎婿、LinkedHashSet测僵、TreeSet
  1. Map接口:雙列數(shù)據(jù),保存具有映射關(guān)系“key-value對(duì)”的集合次酌,實(shí)現(xiàn)類:HashMap恨课、LinkedHashMap、TreeMap岳服、Hashtable剂公、Properties

2. Collection接口方法

2.1 Collection接口常用方法1

add()、addAll()吊宋、size()纲辽、clear()、isEmpty()

向Collection接口的實(shí)現(xiàn)類的對(duì)象中添加數(shù)據(jù)Obj時(shí)璃搜,要求Obj所在類要重寫equals()拖吼。

//導(dǎo)入的包有:import org.junit.Test;import java.util.ArrayList;import java.util.Collection;

public class CollectionTest {

    @Test
    public void test1(){
        Collection coll = new ArrayList();

        //add(Object e):將元素e添加到集合coll中
        coll.add("AA");
        coll.add("bb");
        coll.add(123);//自動(dòng)裝箱
        coll.add(new Object());

        //size():獲取添加的元素個(gè)數(shù)
        System.out.println(coll.size());//4

        //addAll(Collection coll1):將coll1集合中的元素添加到當(dāng)前集合中
        Collection coll1 = new ArrayList();
        coll1.add(456);
        coll1.add("CC");
        coll.addAll(coll1);

        System.out.println(coll.size());//6
        System.out.println(coll);//[AA, bb, 123, java.lang.Object@78e03bb5, 456, CC]

        //clear():清空集合元素
        coll.clear();

        //isEmpty():判斷當(dāng)前嗎集合是否為空
        System.out.println(coll.isEmpty());//true
    }
}

2.2 Collection接口常用方法2

contains()、containsAll()

//導(dǎo)入的包有:import org.junit.Test;import java.util.ArrayList;import java.util.Arrays;import java.util.Collection;

public class CollectionTest {

    @Test
    public void test2(){
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
        coll.add(new String("Tom"));
        coll.add(false);

        //contains(Object obj):判斷當(dāng)前集合是否包含obj
        //判斷時(shí)會(huì)調(diào)用obj對(duì)象所在類的equals(),若重寫則判斷內(nèi)容这吻,沒有則判斷地址
        System.out.println(coll.contains(123));//true
        System.out.println(coll.contains(new String("Tom")));//true

        //containsAll(Collection coll1):判斷形參中所有元素是否在當(dāng)前集合中
        Collection coll1 = Arrays.asList(123,456);
        System.out.println(coll.containsAll(coll1));//true
    }
}

2.3 Collection接口常用方法3

remove()吊档、removeAll()、retainAll()唾糯、equals()

//導(dǎo)入的包有:import org.junit.Test;import java.util.ArrayList;import java.util.Arrays;import java.util.Collection;

public class CollectionTest {
    @Test
    public void test3(){
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
        coll.add(new String("Tom"));
        coll.add(false);

        //remove(Object obj):從當(dāng)前集合中移除obj元素
        //移除時(shí)也需要使用equals()判斷怠硼,返回布爾類型
        coll.remove(123);
        System.out.println(coll);//[456, Tom, false]
        coll.remove(new String("Tom"));
        System.out.println(coll);//[456, false]

        //removeAll(Collection coll1):從當(dāng)前集合中移除coll1中的所有元素,即兩者共同的元素
        Collection coll1 = Arrays.asList(123,456);
        coll.removeAll(coll1);
        System.out.println(coll);//[false]
    }
    
    @Test
    public void test4(){
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
        coll.add(new String("Tom"));
        coll.add(false);

        //retainAll(Collection coll1):獲取當(dāng)前集合和coll1集合的交集移怯,并返回給當(dāng)前集合
        Collection coll1 = Arrays.asList(123,456,789);
        coll.retainAll(coll1);
        System.out.println(coll);//[123, 456]
    }
    
    @Test
    public void test5(){
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
        coll.add(new String("Tom"));
        coll.add(false);

        Collection coll1 = new ArrayList();
        coll1.add(123);
        coll1.add(456);
        coll1.add(new String("Tom"));
        coll1.add(false);

        //equals(Object obj):要想返回true香璃,需要當(dāng)前集合和形參集合元素相同
        System.out.println(coll.equals(coll1));//true
    }
}

2.4 Collection接口常用方法4

hashCode()、toArray()

//導(dǎo)入的包有:import org.junit.Test;import java.util.ArrayList;import java.util.Arrays;import java.util.Collection;

public class CollectionTest {

    @Test
    public void test6(){
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
        coll.add(new String("Tom"));
        coll.add(false);

        //hashCode():返回當(dāng)前對(duì)象的哈希值
        System.out.println(coll.hashCode());

        //toArray():集合---->數(shù)組
        Object[] arr = coll.toArray();//7639761
        for(int i = 0;i<arr.length;i++){
            System.out.println(arr[i]);//123\n456\nTom\nfalse
        }
    }

3. Iterator迭代器接口

3.1 Iterator接口遍歷集合

Iterator對(duì)象稱為迭代器(設(shè)計(jì)模式的一種)舟误,主要用于遍歷Collection集合中的元素葡秒。

Collection接口繼承了java.lang.Iterable接口,該接口有一個(gè)iterator()方法嵌溢,那么所有實(shí)現(xiàn)了Collection接口的集合類都有一個(gè)iterator()方法眯牧,用以返回一個(gè)實(shí)現(xiàn)了Iterator接口的對(duì)象。

//導(dǎo)入的包有:import org.junit.Test;import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;

public class InteratorTest {

    @Test
    public void test1(){
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
        coll.add(new String("Tom"));
        coll.add(false);

        Iterator iterator = coll.iterator();

        //hasNext():判斷是否還有下一個(gè)元素
        while(iterator.hasNext()){
            //next():①指針下移赖草,②將下移后的集合位置上的元素返回
            System.out.println(iterator.next());
        }
        /*123
         456
         Tom
         false*/
    }
}

3.2 Iteratot接口移除元素

Iterator可以刪除集合的元素炸站,但是是遍歷過(guò)程中通過(guò)迭代器對(duì)象的remove()方法,不是集合對(duì)象的remove()方法疚顷。

//導(dǎo)入的包有:import org.junit.Test;import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;

public class InteratorTest {

    @Test
    public void test2(){
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
        coll.add(new String("Tom"));
        coll.add(false);

        Iterator iterator = coll.iterator();

        //刪除集合中“Tom”
        while(iterator.hasNext()){
            Object obj = iterator.next();
            if("Tom".equals(obj)){
                iterator.remove();
            }
        }
        iterator = coll.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
        /*123
        456
        false*/
    }
}

3.3 foreach遍歷集合

Java 5.0 提供了 foreach 循環(huán)迭代訪問(wèn)集合和數(shù)組旱易。

遍歷操作不需獲取Collection或數(shù)組的長(zhǎng)度禁偎,無(wú)需使用索引訪問(wèn)元素。

//導(dǎo)入的包有:import org.junit.Test;import java.util.ArrayList;import java.util.Collection;

public class ForTest {
    @Test
    public void test1(){
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
        coll.add(new String("Tom"));
        coll.add(false);

        //for(集合元素類型 局部變量 : 集合對(duì)象)
        //內(nèi)部使用的還是迭代器
        for(Object obj : coll){
            System.out.println(obj);
        }
        /*123
        456
        Tom
        false*/
    }

    @Test
    public void test2(){
        int[] arr = new int[]{1,2,3,4,5,6};
        //for(數(shù)組元素類型 局部變量 : 數(shù)組對(duì)象)
        for(int i : arr){
            System.out.println(i);
        }
    }
}

4. Collection子接口一:List

4.1 List接口概述

鑒于Java中數(shù)組用來(lái)存儲(chǔ)數(shù)據(jù)的局限性阀坏,我們通常使用List替代數(shù)組

List集合類中元素有序如暖、且可重復(fù),集合中的每個(gè)元素都有其對(duì)應(yīng)的順序索引忌堂。

List容器中的元素都對(duì)應(yīng)一個(gè)整數(shù)型的序號(hào)記載其在容器中的位置盒至,可以根據(jù)序號(hào)存取容器中的元素。

JDK API中List接口的實(shí)現(xiàn)類常用的有:ArrayList士修、LinkedList和Vector枷遂。

4.2 ArrayList、LinkedList和Vector的異同

相同之處

三個(gè)類都是實(shí)現(xiàn)了List接口棋嘲,存儲(chǔ)數(shù)據(jù)的特點(diǎn)相同:存儲(chǔ)有序的酒唉、可重復(fù)的數(shù)據(jù)

不同之處

  • ArrayList:作為L(zhǎng)ist接口的主要實(shí)現(xiàn)類;線程不安全沸移,效率高痪伦;底層使用Object[]存儲(chǔ)。
  • LinkedList:對(duì)于頻繁的插入雹锣、刪除操作网沾,使用此類效率比ArrayList高;底層使用雙向鏈表存儲(chǔ)蕊爵。
  • Vector:作為L(zhǎng)ist接口的古老實(shí)現(xiàn)類辉哥;線程安全的丧荐,效率低踊餐;底層使用Object[]存儲(chǔ)朗和。

4.3 ArrayList鸟蟹、LinkedList和Vector的源碼分析

ArrayList源碼分析

JDK7中源碼分析:

  1. 使用空參構(gòu)造器創(chuàng)建對(duì)象時(shí),在底層創(chuàng)建了長(zhǎng)度時(shí)10的Object[]數(shù)組elementData惨奕。
  2. 如果在集合在添加元素過(guò)程中,導(dǎo)致底層elementData數(shù)組容量不夠,則擴(kuò)容鸦概。
  3. 默認(rèn)情況下,擴(kuò)容為原來(lái)的容量的1.5倍甩骏,同時(shí)需要將原有數(shù)組中的數(shù)據(jù)復(fù)制到新的數(shù)組中窗市。
  4. 建議開發(fā)中使用帶參構(gòu)造器,參數(shù)為容量饮笛,可以不用反復(fù)創(chuàng)建新的數(shù)組咨察。

JDK8中源碼分析:

  1. 底層Object[] elementData初始化為{},并沒有創(chuàng)建長(zhǎng)度為10的數(shù)組福青。
  2. 第一次調(diào)用add()時(shí)摄狱,底層才創(chuàng)建了長(zhǎng)度為10的數(shù)組。
  3. 后續(xù)的添加和擴(kuò)容與JDK7無(wú)異媒役。

LinkedList源碼分析

內(nèi)部聲明了Node類型的first和last屬性祝谚,默認(rèn)值為null。

將使用add()添加的元素封裝到Node中酣衷,創(chuàng)建了Node對(duì)象交惯。

Node定義為:體現(xiàn)了LinkedList的雙向鏈表的說(shuō)法。

Vector源碼分析

JDK7和JDK8中通過(guò)Vector()構(gòu)造器創(chuàng)建對(duì)象時(shí)穿仪,底層都創(chuàng)建了長(zhǎng)度為10的數(shù)組席爽。

在擴(kuò)容方面,默認(rèn)擴(kuò)容為原來(lái)的數(shù)組長(zhǎng)度的2倍啊片。

4.4 List中的常用方法

除了Collection接口中定義的一些方法只锻,List中還額外定義了一些方法。

  • void add(int index, Object ele):在index位置插入ele元素
  • boolean addAll(int index, Collection eles):從index位置開始將eles中的所有元素添加進(jìn)來(lái)
  • 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):返回從fromIndex到toIndex位置的子集合
//導(dǎo)入的包有:import org.junit.Test;import java.util.ArrayList;import java.util.Arrays;import java.util.List;

public class LinkTest {
    @Test
    public void test1(){
        ArrayList list = new ArrayList();
        list.add(123);
        list.add(456);
        list.add(new String("Tom"));
        list.add(false);

        //void add(int index, Object ele):在index位置插入ele元素
        list.add(1,"BB");
        System.out.println(list);//[123, BB, 456, Tom, false]

        //boolean addAll(int index, Collection eles):從index位置開始將eles中的所有元素添加進(jìn)來(lái)
        List list1 = Arrays.asList(1,2,3);
        list.addAll(list1);
        System.out.println(list.size());//8

        //Object get(int index):獲取指定index位置的元素
        System.out.println(list.get(0));//123

        //int indexOf(Object obj):返回obj在集合中首次出現(xiàn)的位置
        //如果不存在該元素炬藤,返回值為-1
        int index = list.indexOf(456);
        System.out.println(index);//2

        //int lastIndexOf(Object obj):返回obj在當(dāng)前集合中末次出現(xiàn)的位置
        //如果不存在該元素,返回值為-1
        System.out.println(list.lastIndexOf(456));//2

        //Object remove(int index):移除指定index位置的元素碴里,并返回此元素
        Object obj = list.remove(3);
        System.out.println(obj);//Tom
        System.out.println(list);//[123, BB, 456, false, 1, 2, 3]

        //Object set(int index, Object ele):設(shè)置指定index位置的元素為ele
        list.set(1,121388);
        System.out.println(list);//[123, 121388, 456, false, 1, 2, 3]

        //List subList(int fromIndex, int toIndex):返回從fromIndex到toIndex位置左閉右開的子集合
        List list2 = list.subList(2, 4);
        System.out.println(list2);//[456, false]
        System.out.println(list);//[123, 121388, 456, false, 1, 2, 3]
    }
}

5. Collection子接口二:Set

5.1 Set接口概述

Set接口是Collection的子接口沈矿,Set接口沒有提供額外的方法

Set 集合不允許包含相同的元素,如果試把兩個(gè)相同的元素加入同一個(gè)Set 集合中咬腋,則添加操作失敗羹膳。

Set判斷兩個(gè)對(duì)象是否相同不是使用 == 運(yùn)算符,而是根據(jù) equals() 方法根竿。

JDK API中Set接口的實(shí)現(xiàn)類常用的有:HashSet陵像、LinkedHashSet和TreeSet。

5.2 HashSet寇壳、LinkedHashSet和TreeSet的異同

相同之處

三個(gè)類都是實(shí)現(xiàn)了List接口醒颖,存儲(chǔ)數(shù)據(jù)的特點(diǎn)相同:存儲(chǔ)無(wú)序的、不可重復(fù)的數(shù)據(jù)

不同之處

  • HashSet:作為Set接口的主要實(shí)現(xiàn)類壳炎;線程不安全的泞歉;可以存儲(chǔ)null值
  • LinkedHashSet:作為HashSet的子類;在添加數(shù)據(jù)的同時(shí)匿辩,每個(gè)數(shù)據(jù)還維護(hù)了兩個(gè)引用腰耙,記錄此數(shù)據(jù)的前一個(gè)數(shù)據(jù)和后一個(gè)數(shù)據(jù);因此遍歷其內(nèi)部數(shù)據(jù)時(shí)铲球,可以按照添加順序顯示
  • TreeSet:可以按照添加對(duì)象的制定屬性挺庞,進(jìn)行排序

5.3 無(wú)序性以及不可重復(fù)性

名詞解釋

無(wú)序性:不等于隨機(jī)性,存儲(chǔ)的數(shù)據(jù)在底層數(shù)組中并非按照數(shù)組索引的順序添加稼病,而是根據(jù)數(shù)據(jù)的哈希值決定选侨。

不可重復(fù)性:保證添加元素按照equals()判斷時(shí)掖鱼,不能返回true,相同元素只能添加一個(gè)援制。

添加元素過(guò)程锨用,以HashSet為例

  1. 我們向HashSet中添加元素a,首先調(diào)用元素a所在類的hashCode()方法隘谣,計(jì)算元素a的哈希值

  2. 次哈希值接著通過(guò)某種算法計(jì)算出在HashSet底層數(shù)組中的存放位置(即為:索引位置)

  3. 判斷此位置上是否已經(jīng)有元素:

    • 如果此位置上沒有其它元素增拥,則元素a添加成功 --------------> 情況1

    • 如果此位置上有其它元素b(或以鏈表形式存在的多個(gè)元素),則比較a與b的哈希值:

      • 如果哈希值不相同寻歧,則元素a添加成功 ---------------> 情況2

      • 如果哈希值相同掌栅,進(jìn)而需要調(diào)用元素a所在類的equals()方法:

        • equals()返回true,元素a添加失敗
        • equals()返回false码泛,則元素a添加成功 ----------------> 情況3

對(duì)于添加成功的情況2和情況3而言:元素a猾封,與已經(jīng)存在指定索引位置上數(shù)據(jù)以鏈表的方式存儲(chǔ):

  • JDK7:元素a放到數(shù)組中,指向原來(lái)的元素
  • JDK8:原來(lái)的元素在數(shù)組中噪珊,指向元素a

根據(jù)上述添加元素的過(guò)程晌缘,則必須有兩個(gè)要求:

  • 向Set中添加的數(shù)據(jù),其所在的類一定要重寫hashCode()和equal()
  • 重寫的hashCode()和equal()盡可能保持一致性:相等的對(duì)象必須具有相等的哈希值

5.4 TreeSet的排序

自然排序(實(shí)現(xiàn)Comparable接口)

向TreeSet中添加的數(shù)據(jù)痢站,要求是相同類的對(duì)象磷箕,否則報(bào)錯(cuò)

自然排序中,若比較的是兩個(gè)對(duì)象阵难,則使用compareTo()岳枷,而不是equal()

//導(dǎo)入的包有:import org.junit.Test;import java.util.Iterator;import java.util.TreeSet;

public class TreeSetTest {
    @Test
    public void test1(){
        TreeSet set = new TreeSet();

        set.add(-1);
        set.add(-5);
        set.add(11);
        set.add(10);
        set.add(35);

        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());//-5,-1,10,11,35
        }

    }
}

定制排序(實(shí)現(xiàn)Comparator接口)

自然排序中,若比較的是兩個(gè)對(duì)象呜叫,則使用compare()空繁,而不是equal()

6. Map接口

6.1 Map接口概述

Map接口:雙列數(shù)據(jù),存儲(chǔ)key-value對(duì)的數(shù)據(jù)朱庆,類似函數(shù)盛泡。其實(shí)現(xiàn)類有:

  1. HashMap:作為Map的主要實(shí)現(xiàn)類;線程不安全的娱颊,效率高傲诵;可存儲(chǔ)null的key和value
    • LinkedHashMap:保證在遍歷map元素時(shí),可以按照添加的順序?qū)崿F(xiàn)遍歷维蒙,對(duì)于頻繁的遍歷操作掰吕,效率高于HashMap
  2. TreeMap:保證按照添加的key-value對(duì)進(jìn)行排序果覆,實(shí)現(xiàn)排序遍歷颅痊,此時(shí)考慮key的自然排序或定制排序,底層使用紅黑樹
  3. Hashtable:作為古老的實(shí)現(xiàn)類局待;線程安全的斑响,效率低菱属;不能存儲(chǔ)null的key和value
    • Properties:常用來(lái)處理配置文件。key和value都是String類型

6.2 Map的底層實(shí)現(xiàn)原理

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

Map中的key:無(wú)序的舰罚、不可重復(fù)的纽门,使用Set存儲(chǔ)所有的key

Map中的value:無(wú)序的、可重復(fù)的营罢,使用Collection存儲(chǔ)所有的value

一個(gè)鍵值對(duì):key-value構(gòu)成了一個(gè)Entry對(duì)象

Map中的entry:無(wú)序的赏陵、不可重復(fù)的,使用Set存儲(chǔ)所有的entry

JDK7中HashMap的底層實(shí)現(xiàn)原理

  1. HashMap map=new HashMap():在實(shí)例化以后饲漾,底層創(chuàng)建了長(zhǎng)度是16的一維數(shù)組Entry[] table蝙搔。
  2. map.put(key1,value1):當(dāng)添加元素時(shí),調(diào)用key1所在類的hashCode()計(jì)算key1哈希值考传,此哈希值經(jīng)過(guò)某種算法計(jì)算以后吃型,得到在Entry數(shù)組中的存放位置。
    • 如果此位置上的數(shù)據(jù)為空僚楞,此時(shí)的key1-value1添加成功勤晚。--------------情況1
    • 如果此位置上的數(shù)據(jù)不為空,意味著此位置上存在一個(gè)或多個(gè)數(shù)據(jù)(以鏈表形式存在)泉褐,比較key1和已經(jīng)存在的一個(gè)或多個(gè)數(shù)據(jù)的哈希值:
      • 如果key1的哈希值與已經(jīng)存在的數(shù)據(jù)的哈希值都不相同赐写,此時(shí)key1-value1添加成功。----------------情況2
      • 如果key1的哈希值和已經(jīng)存在的某一個(gè)數(shù)據(jù)(key2-value2)的哈希值相同膜赃,繼續(xù)比較:調(diào)用key1所在類的equals(key2):
        • 如果equals()返回false:此時(shí)key1-value1添加成功血淌。-----------------情況3
        • 如果equals()返回true:使用value1替換value2

補(bǔ)充:關(guān)于情況2和情況3,此時(shí)key1-value1和原來(lái)的數(shù)幫以鏈表的方式存儲(chǔ)财剖。

擴(kuò)容問(wèn)題:在不斷的添加過(guò)程中悠夯,會(huì)涉及到擴(kuò)容問(wèn)題,默認(rèn)的擴(kuò)容方式:擴(kuò)容為原來(lái)容量的2倍躺坟,并將原有的數(shù)據(jù)復(fù)制過(guò)來(lái)沦补。

JDK8中HashMap的底層實(shí)現(xiàn)原理

JDK8相較于JDK7在底層方面有些不同:

  1. new HashMap():底層沒有創(chuàng)建一個(gè)長(zhǎng)度為16的數(shù)組
  2. JDK 8底層的數(shù)組是:Node[],而非Entry[]
  3. 首次調(diào)用put()方法時(shí)咪橙,底層創(chuàng)建長(zhǎng)度為6的數(shù)組
  4. JDK7底層結(jié)構(gòu)只有:教組+鏈表夕膀。JDK8中底層結(jié)構(gòu):數(shù)組+鏈表+紅黑樹。
    • 當(dāng)數(shù)組的某一個(gè)索引位置上的元素以鏈表形式存在的數(shù)據(jù)個(gè)數(shù)>8且當(dāng)前數(shù)組的長(zhǎng)度>64時(shí)美侦,此時(shí)此索引位置上的所有數(shù)據(jù)改為使用紅黑樹存儲(chǔ)产舞。

6.3 Map中的常用方法

put()、putAll()菠剩、remove()易猫、clear()

  1. Object put(Object key,Object value):將指定key-value添加到(或修改)當(dāng)前map對(duì)象中
  2. void putAll(Map m):將m中的所有key-value對(duì)存放到當(dāng)前map中
  3. Object remove(Object key):移除指定key的key-value對(duì),并返回value
  4. void clear():清空當(dāng)前map中的所有數(shù)據(jù)
//導(dǎo)入的包有:import org.junit.Test;import java.util.HashMap;import java.util.Map;

public class MapTest {
    @Test
    public void test1(){
        Map map = new HashMap();

        //put():添加
        map.put("AA",123);
        map.put("BB",123);
        map.put(45,123);

        //put():修改
        map.put("BB",0);

        System.out.println(map);//{AA=123, BB=0, 45=123}

        Map map1 = new HashMap();
        map1.put("DD",123);
        map1.put("EE",123);

        //putAll()
        map.putAll(map1);
        System.out.println(map);//{AA=123, BB=0, DD=123, EE=123, 45=123}

        //remove()
        Object value = map.remove("AA");
        System.out.println(value);//123
        System.out.println(map);//{BB=0, DD=123, EE=123, 45=123}

        //clear()
        map.clear();
        System.out.println(map.size());//0
        System.out.println(map);//{}
    }
}

get()具壮、containsKey()准颓、containsValue()哈蝇、size()、isEmpty()攘已、equals()

  1. Object get(Object key):獲取指定key對(duì)應(yīng)的value
  2. boolean containsKey(Object key):是否包含指定的key
  3. boolean containsValue(Object value):是否包含指定的value
  4. int size():返回map中key-value對(duì)的個(gè)數(shù)
  5. boolean isEmpty():判斷當(dāng)前map是否為空
  6. boolean equals(Object obj):判斷當(dāng)前map和參數(shù)對(duì)象obj是否相等
//導(dǎo)入的包有:import org.junit.Test;import java.util.HashMap;import java.util.Map;

public class MapTest {
    @Test
    public void test2(){
        Map map = new HashMap();
        map.put("AA",123);
        map.put("BB",123);
        map.put(45,123);

        //get()
        System.out.println(map.get(45));//123

        //containsKey()
        System.out.println(map.containsKey("AA"));//true

        //containsValue()
        System.out.println(map.containsValue(123));//true

        //size()
        System.out.println(map.size());//3

        Map map1 = new HashMap();
        map1.put("AA",123);
        map1.put("BB",123);
        map1.put(45,123);
        //equals()
        System.out.println(map.equals(map1));//true

        map.clear();
        //isEmpty()
        System.out.println(map.isEmpty());//true
    }
}

keySet()炮赦、values()、entrySet()

  1. Set keySet():返回所有key構(gòu)成的Set集合
  2. Collection values():返回所有value構(gòu)成的Collection集合
  3. Set entrySet():返回所有key-value對(duì)構(gòu)成的Set集合
//導(dǎo)入的包:import org.junit.Test;import java.util.*;

public class MapTest {
    @Test
    public void test3(){
        Map map = new HashMap();
        map.put("AA",1);
        map.put("BB",12);
        map.put(45,123);

        //遍歷所有的key集:keySet()
        Set set = map.keySet();
        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }

        //遍歷所有的value集:values()
        Collection values = map.values();
        for(Object obj : values){
            System.out.println(obj);
        }

        //遍歷所有的key-value:entrySet()
        Set entrySet = map.entrySet();
        Iterator iterator1 = entrySet.iterator();
        while(iterator1.hasNext()){
            Object obj = iterator1.next();
            //entrySet集合中的元素都是entry
            Map.Entry entry = (Map.Entry)obj;
            System.out.println(entry.getKey() + "---->" + entry.getValue());
        }
    }
}

6.4 TreeMap的排序

分為自然排序定制排序样勃,可參考【5.4 TreeSet的排序】

6.5 Properties處理屬性文件

//導(dǎo)入的包有:import java.io.FileInputStream;import java.util.Properties;

public class PropertiesTest {
    public static void main(String[] args) {
        Properties pros = new Properties();
        
        fis = new FileInputStream(jdbc.properties);
        pros.load(fis);//加載流對(duì)應(yīng)的文件
        
        String name = pros.getProperty("name");
        String password = pros.getProperty("password");

        System.out.println("name = " + name + ", password = " + password); 
    }
}

7. Collections工具類

7.1 Collections概述

Collections是一個(gè)操作Set吠勘、List和Map等集合的工具類

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

7.2 Collections常用方法

  1. reverse(List):反轉(zhuǎn) List 中元素的順序
  2. shuffle(List):對(duì) List 集合元素進(jìn)行隨機(jī)排序
  3. sort(List):根據(jù)元素的自然順序?qū)χ付?List 集合元素按升序排序
  4. sort(List,Comparator):根據(jù)指定的 Comparator 產(chǎn)生的順序?qū)?List 集合元素進(jìn)行排序
  5. swap(List幌陕,int诵姜, int):將指定 list 集合中的 i 處元素和 j 處元素進(jìn)行交換
  6. Object max(Collection):根據(jù)元素的自然順序,返回給定集合中的最大元素
  7. Object max(Collection搏熄,Comparator):根據(jù) Comparator 指定的順序棚唆,返回給定集合中的最大元素
  8. Object min(Collection)
  9. Object min(Collection,Comparator)
  10. int frequency(Collection心例,Object):返回指定集合中指定元素的出現(xiàn)次數(shù)
  11. void copy(List dest,List src):將src中的內(nèi)容復(fù)制到dest中
  12. boolean replaceAll(List list宵凌,Object oldVal,Object newVal):使用新值替換List對(duì)象的所有舊值
  13. Collections 類中提供了多個(gè) synchronizedXxx() 方法止后,該方法可使將指定集合包裝成線程同步的集合瞎惫,從而可以解決多線程并發(fā)訪問(wèn)集合時(shí)的線程安全問(wèn)題
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市译株,隨后出現(xiàn)的幾起案子瓜喇,更是在濱河造成了極大的恐慌,老刑警劉巖歉糜,帶你破解...
    沈念sama閱讀 217,084評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乘寒,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡匪补,警方通過(guò)查閱死者的電腦和手機(jī)伞辛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)夯缺,“玉大人蚤氏,你說(shuō)我怎么就攤上這事∮欢担” “怎么了竿滨?”我有些...
    開封第一講書人閱讀 163,450評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我姐呐,道長(zhǎng),這世上最難降的妖魔是什么典蝌? 我笑而不...
    開封第一講書人閱讀 58,322評(píng)論 1 293
  • 正文 為了忘掉前任曙砂,我火速辦了婚禮,結(jié)果婚禮上骏掀,老公的妹妹穿的比我還像新娘鸠澈。我一直安慰自己,他們只是感情好截驮,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評(píng)論 6 390
  • 文/花漫 我一把揭開白布笑陈。 她就那樣靜靜地躺著,像睡著了一般葵袭。 火紅的嫁衣襯著肌膚如雪涵妥。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,274評(píng)論 1 300
  • 那天坡锡,我揣著相機(jī)與錄音蓬网,去河邊找鬼。 笑死鹉勒,一個(gè)胖子當(dāng)著我的面吹牛帆锋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播禽额,決...
    沈念sama閱讀 40,126評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼锯厢,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了脯倒?” 一聲冷哼從身側(cè)響起实辑,我...
    開封第一講書人閱讀 38,980評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎藻丢,沒想到半個(gè)月后徙菠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,414評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡郁岩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評(píng)論 3 334
  • 正文 我和宋清朗相戀三年婿奔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片问慎。...
    茶點(diǎn)故事閱讀 39,773評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡萍摊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出如叼,到底是詐尸還是另有隱情冰木,我是刑警寧澤,帶...
    沈念sama閱讀 35,470評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站踊沸,受9級(jí)特大地震影響歇终,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜逼龟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評(píng)論 3 327
  • 文/蒙蒙 一评凝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧腺律,春花似錦奕短、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至之斯,卻和暖如春日杈,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背佑刷。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工达椰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人项乒。 一個(gè)月前我還...
    沈念sama閱讀 47,865評(píng)論 2 370
  • 正文 我出身青樓啰劲,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親檀何。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蝇裤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評(píng)論 2 354