Java集合Map常用子類簡介

Map(映射,存儲的是“鍵-值”映射表昂拂,“鍵”是不能重復的)

如果鍵重復激蹲,則相當于修改對應鍵的值安岂。

Map接口定義方法

    int size();//獲取map大小

    boolean isEmpty();//size==0?

    boolean containsKey(Object var1);//查看是否包含某個鍵

    boolean containsValue(Object var1);//查看是否包含某個值

    V get(Object var1);//跟據(jù)key獲取值

    V put(K var1, V var2);//Map接口有兩個類型參數(shù)对室,K和V,分別表示鍵(Key)和值(Value)的類型,按Key值var1保存值var2,如果鍵重復,則相當于修改對應鍵的值。

    V remove(Object var1);//移除鍵對應的值

    void putAll(Map<? extends K, ? extends V> var1);//批量保存

    void clear();//清空map

    Set<K> keySet();//獲取Map中鍵的集合

    Collection<V> values();//獲取Map中值的集合

    Set<Map.Entry<K, V>> entrySet();//獲取Map中值的鍵值對(遍歷)

    public interface Entry<K, V> {
            K getKey();//鍵

            V getValue();//值

            V setValue(V var1);//修改鍵

            boolean equals(Object var1);

            int hashCode();

        }

方法使用簡介(以HashMap實現(xiàn)類為例)

HashMap 存儲的數(shù)據(jù)是沒有順序的,鍵或值可以為null

    /**
     * Map
     */
    public class Demo {

        public static void main(String[] args) {
            //key   //value//Map<K,V>
            Map<Integer, String> map = new HashMap<>();
            map.put(1, "aaa");//添加元素
            map.put(2, "www");
            map.put(3, "assaa");
            map.put(4, "qqq");
            map.put(5, "ggg");
            map.put(1, "nnn");//修改元素
            map.put(6, "ooo");
            map.put(7, "232");
            map.put(12, "ffds");
            System.out.println(map.size() + "");//獲取大小//8
            //////////////////////
            System.out.println(map.isEmpty());//size==0?//false
            //////////////////////
            System.out.println(map.containsKey(10));//查看是否包含某個鍵//false
            /////////////////////
            System.out.println(map.containsValue("ooo"));//查看是否包含某個值//true
            /////////////////////
            System.out.println(map.get(3));//跟據(jù)key獲取值//assaa
            /////////////////////
            map.remove(12);//移除鍵對應的值
            System.out.println(map.containsKey(12));//false
            /////////////////////
            Map<Integer, String> map1 = new HashMap<>();
            map.put(100, "999");//添加元素
            map.put(110, "222");//添加元素
            map.put(120, "333");//添加元素
            map.putAll(map1);//批量保存
            Set<Integer> integers = map.keySet();//獲取Map中鍵的集合
            System.out.println(integers);//[1, 2, 3, 4, 100, 5, 6, 7, 120, 110]
            ////////////////////////
            Collection<String> values = map.values();//獲取Map中值的集合
            System.out.println(values);//[nnn, www, assaa, qqq, 999, ggg, ooo, 232, 333, 222]
            ////////////////////////
            Set<Map.Entry<Integer, String>> entries = map.entrySet();//迭代
            Iterator<Map.Entry<Integer, String>> iterator = entries.iterator();
            while (iterator.hasNext()) {
                Map.Entry<Integer, String> mapNext = iterator.next();
                System.out.print(mapNext.getKey() + "-->" + mapNext.getValue() + "\t");
                //1-->nnn   2-->www 3-->assaa   4-->qqq 100-->999   5-->ggg 6-->ooo 7-->232 120-->333   110-->222
            }

        }
    }
額外延伸SparseArray

Hashtable

Hashtable和HashMap的區(qū)別
  • Hashtable里面的方法幾乎都是同步的近她,線程安全,HashMap則沒有膳帕,但效率高粘捎。(同ArrAyList和Vector)
  • Hashtable不允許存放null值(鍵和值都不可以),而HashMap可以
相同點
  • 存放元素無序

LinkedHashMap繼承自HashMap

  • LinkedHashMap 實現(xiàn)與 HashMap 的不同之處在于危彩,LinkedHashMap 維護著一個運行于所有條目的雙重鏈接列表攒磨。此鏈接列表定義了迭代順序,
    該迭代順序可以是插入順序或者是訪問順序(參考以下代碼理解)
  • 不是線程安全

案例

      /**
       * LinkedHashMap
       * LinkedHashMap和HashMap區(qū)別
       * LinkedHashMap 保存了記錄的插入順序
       * HashMap 則無序存放
       */
      public class Demo {
          public static void main(String[] args) {
              //關注點一:看添加之后的輸出結果對比
              System.out.println("關注點一:LinkedHashMap輸出:");
              LinkedHashMap<Integer, String> linkedHashMap = new LinkedHashMap();
              linkedHashMap.put(1, "aaa");//添加元素
              linkedHashMap.put(7, "www");
              linkedHashMap.put(5, "ggg");
              linkedHashMap.put(1, "nnn");//修改元素
              linkedHashMap.put(6, "ooo");
              linkedHashMap.put(7, "232");
              linkedHashMap.put(12, "ffds");
              Set<Map.Entry<Integer, String>> entries = linkedHashMap.entrySet();
              Iterator<Map.Entry<Integer, String>> iterator = entries.iterator();
              while (iterator.hasNext()) {
                  Map.Entry<Integer, String> next = iterator.next();
                  System.out.print(next.getKey() + "-->" + next.getValue() + "\t");
                  //1-->nnn 7-->232 5-->ggg 6-->ooo 12-->ffds
              }
              System.out.println();
              System.out.println("關注點一:HashMap輸出:");
              Map<Integer, String> map = new HashMap<>();
              map.put(1, "aaa");//添加元素
              map.put(7, "www");
              map.put(5, "ggg");
              map.put(1, "nnn");//修改元素
              map.put(6, "ooo");
              map.put(7, "232");
              map.put(12, "ffds");
              Set<Map.Entry<Integer, String>> entries1 = map.entrySet();//迭代
              Iterator<Map.Entry<Integer, String>> iterator1 = entries1.iterator();
              while (iterator1.hasNext()) {
                  Map.Entry<Integer, String> mapNext = iterator1.next();
                  System.out.print(mapNext.getKey() + "-->" + mapNext.getValue() + "\t");
                  //1-->nnn 5-->ggg 6-->ooo 7-->232 12-->ffds
              }
              /////////////////////////////////////////////////////////////////
              //關注點二:換一個構造方法
              System.out.println();                                              //10 大小//0.75還不清楚//true代表使用訪問順序
              LinkedHashMap<Integer, String> linkedHashMap1 = new LinkedHashMap<>(10, 0.75f, true);
              linkedHashMap1.put(1, "aaa");//添加元素
              linkedHashMap1.put(7, "www");
              linkedHashMap1.put(5, "ggg");
              linkedHashMap1.put(1, "nnn");//修改元素
              linkedHashMap1.put(6, "ooo");
              linkedHashMap1.put(7, "232");
              linkedHashMap1.put(12, "ffds");
              System.out.println("=======================================================");
              System.out.println("更換構造方法后未使用元素之前輸出");
              Set<Map.Entry<Integer, String>> entries2 = linkedHashMap1.entrySet();
              Iterator<Map.Entry<Integer, String>> iterator2 = entries2.iterator();
              while (iterator2.hasNext()) {
                  Map.Entry<Integer, String> next = iterator2.next();
                  System.out.print(next.getKey() + "-->" + next.getValue() + "\t");
                  //5-->ggg 1-->nnn 6-->ooo 7-->232 12-->ffds
              }
              System.out.println();
              //關鍵點來了
              System.out.println(linkedHashMap1.get(6));//ooo
              System.out.println(linkedHashMap1.get(12));//ffds
              System.out.println("更換構造方法后未使用元素之后輸出");
              Set<Map.Entry<Integer, String>> entries3 = linkedHashMap1.entrySet();
              Iterator<Map.Entry<Integer, String>> iterator3 = entries3.iterator();
              while (iterator3.hasNext()) {
                  Map.Entry<Integer, String> next = iterator3.next();
                  System.out.print(next.getKey() + "-->" + next.getValue() + "\t");
                  //5-->ggg 1-->nnn 7-->232 6-->ooo 12-->ffds
              }
          }
      }

運行結果:

LinkedHashMap延伸(用途)

最近最少使用LRUcache
最近最少使用LRUcache
最近最少使用LRUcache
最近最少使用LRUcache

TreeMap

使用了二叉權的數(shù)據(jù)結構汤徽,key是有序娩缰,保存其唯一性用到了hashCode()、equals()以及比較器(唯一性判斷,鍵排序同TreeSet)
案例
    /**
     * TreeMap:
     * 使用了二叉權的數(shù)據(jù)結構谒府,key是有序拼坎,保存其唯一性用到了hashCode()、equals()以及比較器(唯一性判斷同HashSet)
     */
    public class Demo {
        public static void main(String[] args) {
            //來個稍微復雜點的:存放一個Student鏈表
            //TreeMap<K,V>K類必須實現(xiàn)Comparable<T>接口完疫,用于比較排序
            TreeMap<String, List<Student>> map = new TreeMap<>();
            List<Student> students1 = new ArrayList<>();
            students1.add(new Student("小花", 23));
            students1.add(new Student("小黑", 20));
            students1.add(new Student("小魚", 29));
            students1.add(new Student("小小", 23));
            map.put("小班", students1);
            List<Student> students2 = new ArrayList<>();
            students2.add(new Student("大花", 230));
            students2.add(new Student("大黑", 200));
            students2.add(new Student("大魚", 290));
            students2.add(new Student("大大", 230));
            map.put("大班", students2);
            Set<Map.Entry<String, List<Student>>> entries = map.entrySet();
            for (Map.Entry<String, List<Student>> entry : entries) {
                List<Student> s = entry.getValue();
                System.out.println(entry.getKey() + ":" + s);
            }
        }
    }
    class Student {
        private String name;
        private int age;
        public Student(String name, int age) {
            this.age = age;
            this.name = name;
        }
        @Override
        public String toString() {
            return "[" + this.name + ":\t" + this.age + "]";
        }
    }
運行結果

案例二

    /**
     * TreeMap自定義比較器
     * <p>
     * 案例:按地區(qū)存放學校
     * 建模
     * //School
     * //Area
     */
    public class Demo {
        public static void main(String[] args) {
            List<School> schools1 = new ArrayList<School>();
            schools1.add(new School("10", "火星1"));
            schools1.add(new School("11", "火星2"));
            schools1.add(new School("12", "火星3"));
            List<School> schools2 = new ArrayList<School>();
            schools2.add(new School("20", "北京1"));
            schools2.add(new School("21", "北京2"));
            schools2.add(new School("22", "北京3"));  
            //如果TreeMap<K,V>的K是自定義類型 泰鸡,則此類必須實現(xiàn)Comparable<T>接口,用于比較排序
            Map<Area, List<School>> clsMap = new TreeMap<Area, List<School>>();
            clsMap.put(new Area("1004", "火星"), schools1);
            clsMap.put(new Area("1002", "北京"), schools2);
            Set<Map.Entry<Area, List<School>>> entrySet = clsMap.entrySet();
            for (Map.Entry<Area, List<School>> cls : entrySet) {
                List<School> s = cls.getValue();
                System.out.println(cls.getKey().id+"\t" + cls.getKey().name + ":" + s);
            }
        }
    }
    //
    class Area implements Comparable<Area> {
        //名字
        String name;
        //編號
        String id;
        public Area(String id, String name) {
            this.id = id;
            this.name = name;
        }   
        @Override
        public int compareTo(Area o) {
            //先比較班級的名稱壳鹤,如果名稱相同盛龄,再比較id(也可以先比較id再比較name)
            int r = this.name.compareTo(o.name);
            return r == 0 ? this.id.compareTo(o.id) : r;
        }
        @Override
        public String toString() {
            return this.name + "\t";
        }
    }
    class School {
        private String id;
        private String name;
        public School(String id, String name) {
            this.id = id;
            this.name = name;
        }
        @Override
        public String toString() {
            return "School[id=" + id + ", name=" + name + "]";
        }
    }
運行結果

補充

List、Set器虾、Map是否繼承自Collection接口讯嫂?

List蹦锋、Set 是兆沙,Map 不是。Map是鍵值對映射容器莉掂,與List和Set有明顯的區(qū)別葛圃,而Set存儲的零散的元素且不允許有重復元素(數(shù)學中的集合也是如此),List是線性結構的容器憎妙,適用于按數(shù)值索引訪問元素的情形库正。

闡述ArrayList、Vector厘唾、LinkedList的存儲性能和特性褥符。

ArrayList 和Vector都是使用數(shù)組方式存儲數(shù)據(jù),此數(shù)組元素數(shù)大于實際存儲的數(shù)據(jù)以便增加和插入元素抚垃,它們都允許直接按序號索引元素喷楣,但是插入元素要涉及數(shù)組元素移動等內存操作趟大,所以索引數(shù)據(jù)快而插入數(shù)據(jù)慢,Vector中的方法由于添加了synchronized修飾铣焊,因此Vector是線程安全的容器逊朽,但性能上較ArrayList差,因此已經是Java中的遺留容器曲伊。LinkedList使用雙向鏈表實現(xiàn)存儲(將內存中零散的內存單元通過附加的引用關聯(lián)起來叽讳,形成一個可以按序號索引的線性結構,這種鏈式存儲方式與數(shù)組的連續(xù)存儲方式相比坟募,內存的利用率更高)岛蚤,按序號索引數(shù)據(jù)需要進行前向或后向遍歷,但是插入數(shù)據(jù)時只需要記錄本項的前后項即可懈糯,所以插入速度較快灭美。Vector屬于遺留容器(Java早期的版本中提供的容器,除此之外昂利,Hashtable届腐、Dictionary、BitSet蜂奸、Stack犁苏、Properties都是遺留容器),已經不推薦使用扩所,但是由于ArrayList和LinkedListed都是非線程安全的围详,如果遇到多個線程操作同一個容器的場景,則可以通過工具類Collections中的synchronizedList方法將其轉換成線程安全的容器后再使用

Collection和Collections的區(qū)別祖屏?

Collection是一個接口助赞,它是Set、List等容器的父接口袁勺;Collections是個一個工具類雹食,提供了一系列的靜態(tài)方法來輔助容器操作,這些方法包括對容器的搜索期丰、排序群叶、線程安全化等等

List、Map钝荡、Set三個接口存取元素時街立,各有什么特點?

List以特定索引來存取元素埠通,可以有重復元素赎离。Set不能存放重復元素(用對象的equals()方法來區(qū)分元素是否重復)。Map保存鍵值對(key-value pair)映射端辱,映射關系可以是一對一或多對一梁剔。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末圾浅,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子憾朴,更是在濱河造成了極大的恐慌狸捕,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件众雷,死亡現(xiàn)場離奇詭異灸拍,居然都是意外死亡,警方通過查閱死者的電腦和手機砾省,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進店門鸡岗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人编兄,你說我怎么就攤上這事轩性。” “怎么了狠鸳?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵揣苏,是天一觀的道長。 經常有香客問我件舵,道長卸察,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任铅祸,我火速辦了婚禮坑质,結果婚禮上,老公的妹妹穿的比我還像新娘临梗。我一直安慰自己涡扼,他們只是感情好,可當我...
    茶點故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布盟庞。 她就那樣靜靜地躺著吃沪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪茫经。 梳的紋絲不亂的頭發(fā)上巷波,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天萎津,我揣著相機與錄音卸伞,去河邊找鬼。 笑死锉屈,一個胖子當著我的面吹牛荤傲,可吹牛的內容都是我干的。 我是一名探鬼主播颈渊,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼遂黍,長吁一口氣:“原來是場噩夢啊……” “哼终佛!你這毒婦竟也來了?” 一聲冷哼從身側響起雾家,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤铃彰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后芯咧,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體牙捉,經...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年敬飒,在試婚紗的時候發(fā)現(xiàn)自己被綠了邪铲。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,643評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡无拗,死狀恐怖带到,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情英染,我是刑警寧澤揽惹,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站四康,受9級特大地震影響永丝,放射性物質發(fā)生泄漏。R本人自食惡果不足惜箭养,卻給世界環(huán)境...
    茶點故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一慕嚷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧毕泌,春花似錦喝检、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至愿题,卻和暖如春损俭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背潘酗。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工杆兵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人仔夺。 一個月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓琐脏,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子日裙,可洞房花燭夜當晚...
    茶點故事閱讀 43,509評論 2 348

推薦閱讀更多精彩內容