天天看點

Java中的 Map集合 詳解一、雙列集合:二、Map的常用方法三、Map集合的周遊四、HashMap存儲自定義類型五、LinkedHashMap集合六、TreeMap集合

一、雙列集合:

        Map<K,V> 集合的特點:K用來限制鍵的類型,V用來限制值的類型

                1.Map集合存儲元素是以鍵值對的形式存儲的,每一個鍵值對都有鍵和值

                2.Map集合的鍵是唯一,值可以重複,如果鍵重複了,那麼值就會被覆寫

                3.根據鍵來取值

        Map集合子類:

                - HashMap<K,V> 存儲資料采用的哈希表結構,元素的存取順序不能保證一緻

                        由于要保證鍵的唯一,不重複,需要重寫鍵的hashCode方法,equals方法

                - LinkedHashMap<K,V> hashMap下的子類,存儲資料采用的是哈希表結構 + 連結清單結構

                        通過連結清單結構可以保證鍵值對的存取順序一緻

                        通過哈希表結構可以保證鍵的唯一,不重複,

                        需要重寫鍵的hashCode方法,equals方法

                - TreeMap<K,V>TreeMap集合和Map相比沒有特有的功能,底層的資料結構都是紅黑樹

                        可以對元素的鍵進行排序,排序方式由兩種:自然排序和比較器排序

二、Map的常用方法

        這些是Map集合常用的方法

- public V put(K key, V value)  把指定的鍵與指定的值添加到Map集合中
- public V remove(Object key)   把指定的鍵所對應的鍵值對元素 在Map集合中删除,傳回被删除的元素的值
- public V get(Object key)      根據指定的鍵,在Map集合中擷取對應的值
- public boolean containsKey(Object key)  判斷該集合中是否包含有此鍵
- public boolean containsValue(Object value) 判斷該集合中是否包含有此值
- public Set<K> keySet()  擷取Map集合中所有的鍵,存儲到Set集合中
- public Collection<V> values() 擷取Map集合中所有的值,存儲到Collection集合中
- public Set<Map.Entry<K,V>> entrySet()  擷取到Map集合中所有的鍵值對 對象的集合(Set集合)
- public static interface Map.Entry<K,V> 表示鍵值對對象 --- 把鍵值對包裝成一個對象,該對象類型就是Entry類型
           

        下面是對應方法的代碼示範

// 建立Map集合,限制鍵的類型為String,值的類型為String
        Map<String,String> map = new HashMap<>();

        // 往map集合中添加鍵值對
        map.put("老大","老二");
        map.put("大王","小王");
        map.put("張二","張三");
        System.out.println(map);

        // Map集合鍵唯一,如果鍵重複了,值會覆寫
        String s1 = map.put("老大","老三");
        System.out.println(s1);
        System.out.println(map);

        // Map集合值可以重複
        String s2 = map.put("張一", "張三");
        System.out.println(s2);// null
        System.out.println(map);

        // 删除文章鍵對應的這個鍵值對
        String s3 = map.remove("大王");
        System.out.println(s3);
        System.out.println(map);

        // 擷取黃曉明鍵對應的值
        String s4 = map.get("老大");
        System.out.println(s4);

        // 判斷是否包含指定的鍵
        boolean flag1 = map.containsKey("老大");
        System.out.println(flag1);// true
        // 判斷是否包含指定的值
        boolean flag2 = map.containsValue("老大");
        System.out.println(flag2);// false

        // 擷取所有的鍵
        Set<String> strings = map.keySet();
        System.out.println(strings);

        // 擷取所有的值
        Collection<String> values = map.values();
        System.out.println(values);

        // 擷取Map集合中所有的鍵值對對象
        Set<Map.Entry<String, String>> entries = map.entrySet();
        System.out.println(entries);

        輸出結果:
            {張二=張三, 老大=老二, 大王=小王}
            老二
            {張二=張三, 老大=老三, 大王=小王}
            null
            {張二=張三, 老大=老三, 張一=張三, 大王=小王}
            小王
            {張二=張三, 老大=老三, 張一=張三}
            老三
            true
            false
            [張二, 老大, 張一]
            [張三, 老三, 張三]
            [張二=張三, 老大=老三, 張一=張三]
           

三、Map集合的周遊

        1.方式一

                (1)、擷取Map集合所有的值

                (2)、循環周遊Map集合所有的鍵

                (3)、在循環中,根據鍵找值

// 建立Map集合,限制鍵的類型為String,值的類型為String
        Map<String,String> map = new HashMap<>();

        // 往map集合中添加鍵值對
        map.put("老大","老二");
        map.put("大王","小王");
        map.put("張二","張三");

        // 方式一:根據鍵找值

        // 1.擷取Map集合所有的鍵
        Set<String> strings = map.keySet();
        // 2.循環周遊Map集合所有的鍵
        for (String key : strings) {
            // 3.在循環中,根據鍵找值
            String value = map.get(key);
            System.out.println(key +"=="+value);
        }

        輸出結果:
            張二==張三
            老大==老二
            大王==小王
           

        2.方式二、

                Entry<K,V>接口:簡稱Entry項,表示鍵值對對象,用來封裝Map集合中的鍵值對

                Entry<K,V>接口:Map解耦中的内部接口,在外部使用的時候是這樣表示的

                        Map.Entry<K,V>

                        Map.Entry<K,V>接口中的API:

                                - K getKey();擷取鍵值對對象包裝的鍵

                                - K getValue(); 擷取鍵值對對象包裝的值

                周遊步驟:

                        (1):擷取Map集合中所有的鍵值對  對應的  鍵值對對象 entrySet()方法

                        (2):循環周遊所有的鍵值對對象

                        (3):根據鍵值對對象擷取鍵和值

// 建立Map集合,限制鍵的類型為String,值的類型為String
        Map<String,String> map = new HashMap<>();

        // 往map集合中添加鍵值對
        map.put("老大","老二");
        map.put("大王","小王");
        map.put("張二","張三");

        // 方式二:鍵值對對象的形式

        // 1.擷取Map集合中所有的鍵值對 對應的 鍵值對對象 entrySet() 方法
        Set<Map.Entry<String, String>> entries = map.entrySet();

        // 2.循環周遊所有的鍵值對對象
        for (Map.Entry<String, String> entry : entries) {
            //3.根據鍵值對對象擷取鍵和值
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key +"==" + value);
        }

        輸出結果:
            張二==張三
            老大==老二
            大王==小王
           

四、HashMap存儲自定義類型

// 建立要給學生對象
public class Student {
    String name;
    int age;

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}
           
// 建立HashMap集合,限制鍵的類型為Student,值的類型為String
        Map<Student,String> map = new HashMap<>();

        // 往集合中添加鍵值對
        Student s1 = new Student("張三",15);
        Student s2 = new Student("李四",50);
        Student s3 = new Student("王五",17);
        Student s4 = new Student("趙六",41);
        Student s5 = new Student("劉七",19);
        Student s6 = new Student("張三",15);

        map.put(s1,"北京");
        map.put(s2,"上海");
        map.put(s3,"深圳");
        map.put(s4,"武漢");
        map.put(s5,"鄭州");
        map.put(s6,"白沙洲");

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

        輸出結果:     
            {Student{name='王五', age=17}=深圳, Student{name='劉七', age=19}=鄭州, Student{name='李四', age=50}=上海, Student{name='張三', age=15}=白沙洲, Student{name='趙六', age=41}=武漢}
            5
           

        這裡map集合的長度是5,因為Map集合要保證鍵的唯一,

        是以同時給Student存儲兩個張三的話,鍵值會被覆寫,就導緻給map存儲時s1和s6沖突,s6覆寫掉s1的現象

        最終結果也如代碼展示一樣,map的大小是5,北京被白沙洲覆寫

五、LinkedHashMap集合

        LinkedHashMap:元素存取有序,鍵唯一,值可重複

                - 通過連結清單結構保證元素存取有序,順序一緻

                - 通過哈希表結構可以保證鍵的唯一,不重複,需要複寫hashCode方法和equals方法

// 建立LinkedHashmap對象,限制鍵的類型為Integer,值的類型為String
        LinkedHashMap<Integer,String> map = new LinkedHashMap<>();

        // 給集合中存儲一些鍵值
        map.put(300,"北京");
        map.put(100,"上海");
        map.put(600,"太原");
        map.put(900,"西安");
        map.put(300,"臨汾");
        System.out.println(map);

        輸出結果:    
            {300=臨汾, 100=上海, 600=太原, 900=西安}
           

六、TreeMap集合

        TreeMap集合:鍵唯一,值可重複,如果鍵重複了,值會覆寫

                - public TreeMap() 根據鍵按照預設規則進行排序

                - public TreeMap(Comparator<? super K> comparator) 通過比較器指定規則排序

// 預設規則:升序
        TreeMap<Integer,String> map = new TreeMap<>();
        map.put(300,"北京");
        map.put(100,"上海");
        map.put(600,"太原");
        map.put(900,"西安");
        map.put(300,"臨汾");
        System.out.println(map);// {100=上海, 300=臨汾, 600=太原, 900=西安}

        // 指定規則:降序
        TreeMap<Integer,String> map2 = new TreeMap<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });
        map2.put(300,"北京");
        map2.put(100,"上海");
        map2.put(600,"太原");
        map2.put(900,"西安");
        map2.put(300,"臨汾");
        System.out.println(map2);// {900=西安, 600=太原, 300=臨汾, 100=上海}

        輸出結果:
            {100=上海, 300=臨汾, 600=太原, 900=西安}
            {900=西安, 600=太原, 300=臨汾, 100=上海}
            
           

繼續閱讀