8-集合

1.集合的理解和好處

  1. 可以動態(tài)保存任意多個對象
  2. 提供了一系列方便的操作對象的方法:add灌砖、remove、set傀蚌、get等
  3. 使用集合添加和刪除新元素方便簡潔

2.集合的框架體系

3.Collection接口和常用方法

3.1常用方法

  1. collection實現(xiàn)子類可以存放多個元素基显,每個元素可以是Object
  2. 有些Collection的實現(xiàn)類,可以存放重復的元素善炫,有些不可以
  3. 有些Collection的實現(xiàn)類撩幽,有些是有序的(List),有些不是有序(Set)
  4. Collection接口沒有直接的實現(xiàn)子類箩艺,是通過它的子接口Set和List來實現(xiàn)的
//Collection 接口常用方法,以實現(xiàn)子類 ArrayList 來演示. CollectionMethod.java
import java.util.ArrayList;
import java.util.List;

public class CollectionMethod {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        List list = new ArrayList();
        // add:添加單個元素
        list.add("jack");
        list.add(10);//list.add(new Integer(10))
        list.add(true);
        System.out.println("list=" + list);
        // remove:刪除指定元素
        //list.remove(0);//刪除第一個元素
        list.remove(true);//指定刪除某個元素
        System.out.println("list=" + list);
        // contains:查找元素是否存在
        System.out.println(list.contains("jack"));//T
        // size:獲取元素個數(shù)
        System.out.println(list.size());//2
        // isEmpty:判斷是否為空
        System.out.println(list.isEmpty());//F
        // clear:清空
        list.clear();
        System.out.println("list=" + list);
        // addAll:添加多個元素
        ArrayList list2 = new ArrayList();
        list2.add("紅樓夢");
        list2.add("三國演義");
        list.addAll(list2);
        System.out.println("list=" + list);
        // containsAll:查找多個元素是否都存在
        System.out.println(list.containsAll(list2));//T
        // removeAll:刪除多個元素
        list.add("聊齋");
        list.removeAll(list2);
        System.out.println("list=" + list);//[聊齋]
         }
    }

3.2Collection接口遍歷元素方式

3.2.1 使用Iterator(迭代器)

  1. Iterator對象稱為迭代器窜醉,主要用于遍歷Collection集合中的元素
  2. 所有實現(xiàn)了Collection接口的集合類都有一個iterator()方法,用以返回一個實現(xiàn)了Iterator接口的對象艺谆,既可以返回一個迭代器榨惰。
  3. 演示:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class CollectionIterator {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        Collection col = new ArrayList();
        col.add(new Book("三國演義", "羅貫中", 10.1));
        col.add(new Book("小李飛刀", "古龍", 5.1));
        col.add(new Book("紅樓夢", "曹雪芹", 34.6));
        
        //遍歷 col 集合
        //1. 先得到 col 對應的 迭代器
        Iterator iterator = col.iterator();
        //2. 使用 while 循環(huán)遍歷
         while (iterator.hasNext()) {//判斷是否還有數(shù)據(jù)
        //返回下一個元素,類型是 Object
            Object obj = iterator.next();
            System.out.println("obj=" + obj);
         }
        //快捷鍵静汤,快速生成 while => itit
        //顯示所有的快捷鍵的的快捷鍵 ctrl + j
        //3. 當退出 while 循環(huán)后 , 這時 iterator 迭代器琅催,指向最后的元素
        // iterator.next();//NoSuchElementException
        //4. 如果希望再次遍歷,需要重置我們的迭代器
        iterator = col.iterator();
        System.out.println("===第二次遍歷===");
        while (iterator.hasNext()) {
            Object obj = iterator.next();
            System.out.println("obj=" + obj);
        }
    }
}
class Book {略}

3.2.2 for循環(huán)增強

增強for循環(huán)虫给,可以代替iterator迭代器藤抡,特點:增強for就是簡化版的iterator,本質是一樣的抹估,只能用于遍歷集合或數(shù)組缠黍。

基本語法:

for(元素類型 元素名:集合名或數(shù)組名){
    訪問元素
}

演示:

public class ListExercise {
    public static void main(String[] args) {
        List list = new ArrayList();
        for (int i = 0; i < 12; i++) {
            list.add("hello"+i);
        }
        list.add(2,"zmm");
        list.get(5);
        list.remove(6);
        list.set(7,"zmm_1");
        
        System.out.println("*********使用增強for遍歷集合********");
        for (Object o :list) {
            System.out.println(o);
        }


    }
}

4.List接口和常用方法

4.1 List接口的基本介紹

  1. List集合類中元素有序(即添加順序和取出順序一致),且可重復
  2. List集合中的每個元素都有其對應的順序索引棋蚌,即支持索引
  3. 常用的實現(xiàn)類ArrayList嫁佳、LinkedList挨队、Vector

4.2 List接口的常用方法

4.3 List的三種遍歷方式

  1. 使用iterator
  2. 使用增強for
  3. 使用普通for

5.ArrayLIst底層結構

5.1 ArrayList的注意事項:

  1. ArrayList可以加入一個或多個null
  2. ArrayList是由數(shù)組來實現(xiàn)數(shù)據(jù)存儲的
  3. ArrayList基本等同于Vector,在多線程情況下蒿往,不建議使用ArrayList

5.2 ArrayList的底層操作機制

  1. 當創(chuàng)建ArrayList對象時盛垦,如果使用的是無參構造器,則初始elementData容量為0瓤漏,第一次添加腾夯,則擴容elementData為10,如需再次擴容蔬充,則擴容elementsData為1.5倍
  2. 如果使用的是指定大小的構造器蝶俱,則初始elementData容量為指定大小,如果需要擴容饥漫。則直接擴容elementData為1.5倍

6.Vector底層結構

6.1 Vector介紹

  1. 底層也是一個對象數(shù)組
  2. Vector是線程同步的榨呆,即線程安全,在開發(fā)中庸队,需要線程同步安全時积蜻,考慮使用Vector

6.2 ArrayList和Vector的比較

底層結構都是可變數(shù)組,線程安全ArrayLIst不安全彻消,但是效率高竿拆;Vector安全,但是效率不高宾尚。在擴容倍數(shù)方面丙笋,ArrayLIst如果使用的是有參構造器,需要擴容的時候直接擴充原來的1.5倍煌贴,如果使用的是無參構造器御板,則第一次擴容為10,第二次開始按1.5倍擴充崔步。Vector如果是無參稳吮,默認10,滿后按2倍擴容井濒;如果指定大小灶似,則每次按3倍擴容。

7.LinkedList底層結構

7.1 LinkedList的基本介紹

  1. LinkedList底層實現(xiàn)了雙向鏈表和雙端隊列特點
  2. 可以添加任意元素(元素可以重復)瑞你,包括null
  3. 線程不安全酪惭,沒有實現(xiàn)同步
  4. LinkedList中維護了兩個屬性first和last分別指向首節(jié)點和尾節(jié)點
  5. 每個節(jié)點(Node對象),里面又維護了prev者甲、next春感、item三個屬性,其中通過prev指向前一個,通過next指向后一個節(jié)點鲫懒。最終實現(xiàn)雙向鏈表嫩实。
  6. LinkedList的元素添加和刪除不是通過數(shù)組完成的,相對來說效率較高
package com.zmm.list_;

/**
 * @author zmm
 * 雙向鏈表的簡單演示
 */
public class LinkedList01 {
    public static void main(String[] args) {
        Node zmm = new Node("zmm");
        Node z1 = new Node("z1");
        Node z2 = new Node("z2");

        zmm.next=z1;
        z1.next=z2;

        z2.pre=z1;
        z1.pre=zmm;

        Node first=zmm;
        Node last=z2;
        //雙向鏈表循環(huán)
        while(true){
            if(first==null){
                break;
            }
            System.out.println(first);
            first=first.next;
        }
        System.out.println("--------------------------");
        //向鏈表插入節(jié)點
        Node mmz = new Node("mmz");
        mmz.next=z2;
        mmz.pre=z1;

        z1.next=mmz;
        z2.pre=mmz;

        first=zmm;
        while(true){
            if(first==null){
                break;
            }
            System.out.println(first);
            first=first.next;
        }
        System.out.println("--------------------------");
        //向鏈表刪除節(jié)點
        z1.next=z2;
        z2.pre=z1;

        mmz.next=null;
        mmz.pre=null;
        first=zmm;
        while(true){
            if(first==null){
                break;
            }
            System.out.println(first);
            first=first.next;
        }
    }

}
class Node{
    public Object item;
    public Node next;
    public Node pre;
    public Node(Object name){
        this.item=name;
    }

    @Override
    public String toString() {
        return "Node name="+item;
    }
}

7.2 ArrayList和LInkedList的比較

ArrayLIst的底層結構是可變數(shù)組窥岩,LInkedLIst是雙向鏈表甲献;在增刪效率上,ArrayList較低颂翼,LinkedList較高晃洒;改查效率的話,ArrayList較高朦乏,LinkedList較低球及。

如何選擇ArrayList和LinkedList:

如果改查的操作較多,使用ArrayList

如果刪增的操作較多呻疹,使用LinkedList

一般來說大部分業(yè)務是查詢吃引,因此大部分情況下會選擇ArrayList

8.Set接口和常用方法

8.1 Set接口基本介紹

1.無序(添加和取出順序不一致),沒有索引

2.不允許重復元素诲宇,所以最多包含一個null

8.2 Set接口的常用方法

Set接口也是Collection的子接口际歼,因此,常用方法和Collection接口一樣

8.3 Set接口的遍歷方式

  1. 可以使用迭代器-iterator
  2. 增強for
  3. 不能使用索引的方式來獲取

9.Set接口實現(xiàn)類-HashSet

  1. HashSet實現(xiàn)了Set接口
  2. HashSet實際上是HashMap姑蓝,HaspMap底層是(數(shù)組+鏈表
  3. 可以存放null值,但是只能有一個null
  4. HashSet不保證元素是有序的吕粗,取決于hash后纺荧,在確定索引的結果(即,不保證存放元素的順序和取出的順序一致)
  5. 不能有重復的元素或對象

9.1 HashSet底層機制說明

結論:

  1. HashSet底層是HashMap
  2. 先獲取元素的哈希值(hashCode方法)
  3. 對哈希值進行運算颅筋,得出一個索引值即為要存放在哈希表中的位置號
  4. 如果該位置上沒有其他元素宙暇,則直接存放,如果該位置上已經有其他元素议泵,則需要進行equals(自定義)判斷占贫,如果相等,則不再添加先口,如果不相等型奥,則以鏈表的方式添加。

10. Set接口實現(xiàn)類-LinkedHashSet

  1. LinkedHashSet是HashSet的子類
  2. LinkedHashSet底層是一個LinkedHashMap碉京,底層維護了一個數(shù)組+雙向鏈表
  3. LinkedHashSet根據(jù)元素的hashCode值來決定元素的存儲位置厢汹,同時使用鏈表維護元素的次序,這使得元素看起來是以插入順序保存的
  4. LinkedHashSet不允許添加重復元素

11. Map接口和常用方法

11.1 Map接口實現(xiàn)類的特點

  1. Map與Collection并列存在谐宙。用于保存具有映射關系的數(shù)據(jù):Key-Value
  2. Map中的key和value可以是任何引用類型的數(shù)據(jù)
  3. Map中的key不允許重復
  4. Map中的value可以重復
  5. Map的key可以為null烫葬,value也可以為null,注意key為null,只能有一個搭综,value為null垢箕,可以多個
  6. 常用String類作為Map的key
  7. Key和value之間存在單向一對一關系,即通過指定的key總能找到對應的value

11.2Map接口常用方法

  1. put:添加
  2. remove:根據(jù)鍵刪除映射關系
  3. get:根據(jù)鍵獲取值
  4. size:獲取元素個數(shù)
  5. isEmpty:判斷個數(shù)是否為0
  6. clear:清除
  7. containsKey:查找鍵是否存在

11.3Map接口遍歷方法

  1. containsKey:查找鍵是否存在
  2. KeySet:獲取所有的鍵
  3. entrySet:獲取所有關系k-v
  4. values:獲取所有的值
package com.zmm.map_;

import java.util.*;

/**
 * @author zmm
 */
public class MapFor {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("鄧超", "孫儷");
        map.put("王寶強", "馬蓉");
        map.put("宋喆", "馬蓉");
        map.put("劉令博", null);
        map.put(null, "劉亦菲");
        map.put("鹿晗", "關曉彤");
        //第一組: 先取出 所有的 Key , 通過 Key 取出對應的 Value
        Set keySet = map.keySet();
        //(1) 增強 for
        System.out.println("-----第一種方式-------");
        for(Object key:keySet){
            System.out.println(key+"-"+map.get(key));
        }
        //(2) 迭代器
        System.out.println("----第二種方式--------");
        Iterator iterator = keySet.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.println(next+"-"+map.get(next));
        }
        //第二組: 把所有的 values 取出
        Collection values = map.values();
        System.out.println("---取出所有的 value 增強 for----");
        for(Object value:values){
            System.out.println(value);
        }
        //(2) 迭代器
        System.out.println("---取出所有的 value 迭代器----");
        Iterator iterator1 = values.iterator();
        while (iterator1.hasNext()) {
            Object value = iterator1.next();
            System.out.println(value);
        }
        //第三組: 通過 EntrySet 來獲取 k-v
        Set entrySet = map.entrySet();
        //(1) 增強 for
        System.out.println("----使用 EntrySet 的 for 增強(第 3 種)----");
        for(Object entry:entrySet){
            Map.Entry m=(Map.Entry)entry;
            System.out.println(m.getKey()+"-"+m.getValue());
        }
        //(2) 迭代器
        System.out.println("----使用 EntrySet 的 迭代器(第 4 種)----");
        Iterator iterator2 = entrySet.iterator();
        while (iterator2.hasNext()) {
            Object entry = iterator2.next();
            Map.Entry m = (Map.Entry) entry;
            System.out.println(m.getKey() + "-" + m.getValue());
        }
    }
}

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末兑巾,一起剝皮案震驚了整個濱河市条获,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌闪朱,老刑警劉巖月匣,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異奋姿,居然都是意外死亡锄开,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門称诗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來萍悴,“玉大人,你說我怎么就攤上這事寓免⊙⒂眨” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵袜香,是天一觀的道長撕予。 經常有香客問我,道長蜈首,這世上最難降的妖魔是什么实抡? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮欢策,結果婚禮上吆寨,老公的妹妹穿的比我還像新娘。我一直安慰自己踩寇,他們只是感情好啄清,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著俺孙,像睡著了一般辣卒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鼠冕,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天添寺,我揣著相機與錄音,去河邊找鬼懈费。 笑死计露,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播票罐,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼叉趣,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了该押?” 一聲冷哼從身側響起疗杉,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蚕礼,沒想到半個月后烟具,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡奠蹬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年朝聋,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片囤躁。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡冀痕,死狀恐怖,靈堂內的尸體忽然破棺而出狸演,到底是詐尸還是另有隱情言蛇,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布宵距,位于F島的核電站腊尚,受9級特大地震影響,放射性物質發(fā)生泄漏满哪。R本人自食惡果不足惜跟伏,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望翩瓜。 院中可真熱鬧,春花似錦携龟、人聲如沸兔跌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坟桅。三九已至,卻和暖如春蕊蝗,著一層夾襖步出監(jiān)牢的瞬間仅乓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工蓬戚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留夸楣,地道東北人。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像豫喧,于是被迫代替她去往敵國和親石洗。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內容