Java 集合-Map接口和三個子類實現


2017-10-31 22:05:59

  • Map

將鍵映射到值的對象。一個映射不能包含重復的鍵;每個鍵最多只能映射到一個值。

HashMap是基於散列表實現的,插入、刪除和定位元素時間復雜度平均能達到O(1)。

TreeMap基於紅黑樹(一種自平衡二叉查找樹)實現的,時間復雜度平均能達到O(log n)。

Map的數據結構針對鍵值有效和值無關

*常用方法

   public static void main(String[] args) {
        Map<String, String> map = new HashMap<String,String>();

        //添加元素
        //如果鍵是第一次存儲,則返回null
        //如果鍵不是第一次了,則替換舊的值,並返回舊的值
        map.put("劉亦菲","20");
        map.put("章子怡", "22");
        map.put("田馥甄", "24");
        map.put("陳綺貞","22");

        //remove(key),根據鍵值進行刪除,返回值,如果不存在,返回null
        map.remove("章子怡");

        //containsKey()
        map.containsKey("劉亦菲");

        //get(key)根據鍵得到值,如果沒有返回null
        System.out.println(map.get("劉亦菲"));

        //keySet(),獲取所有鍵值組成的集合
        Set<String> set = map.keySet();
        for(String s:set)
        {
            System.out.println(s+" ");
        }

        //values,獲取所有值組成的集合
        Collection<String> collection= map.values();
        for(String s:collection) System.out.println(s);

        //輸出
        System.out.println(map);
    }

Map集合的遍歷:

A:首先獲得所有的鍵的集合,通過鍵的集合來獲取值;

B:直接獲得鍵值對的集合

public class MapDemo2 {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String,String>();

        //添加元素
        //如果鍵是第一次存儲,則返回null
        //如果鍵不是第一次了,則替換舊的值,並返回舊的值
        map.put("劉亦菲","20");
        map.put("章子怡", "22");
        map.put("田馥甄", "24");
        map.put("陳綺貞","22");

        //遍歷方法1:通過鍵來找值
        Set<String> set= map.keySet();
        for(String s:set) {
            String value= map.get(s);
            System.out.println(s+"="+value);
        }

        //遍歷方法2:直接得到鍵值對的集合
        Set<Map.Entry<String,String>> set2 = map.entrySet();
        for(Map.Entry<String,String> m:set2){
            System.out.println(m.getKey()+"="+m.getValue());
        }

    }
}

Map的三個子類實現:

          HashMap

          LinkedHashMap

          TreeMap

~ HashMap

HashMap:基於哈希表的 Map 接口的實現。此實現提供所有可選的映射操作,並允許使用 null 值和 null 鍵。(除了非同步和允許使用 null 之外,HashMap 類與 Hashtable 大致相同。)此類不保證映射的順序,特別是它不保證該順序恆久不變。

注意,此實現不是同步的。如果多個線程同時訪問一個哈希映射,而其中至少一個線程從結構上修改了該映射,則它必須 保持外部同步。

注意:HashMap底層依賴hashcode和equals,在鍵值為對象的時候需要重寫這兩個方法,這兩個方法都可以通過右鍵直接生成。

*構造方法

*常用方法

public class MapDemo2 {
    public static void main(String[] args) {
        HashMap<String, String> map = new HashMap<String,String>();

        //添加元素
        //如果鍵是第一次存儲,則返回null
        //如果鍵不是第一次了,則替換舊的值,並返回舊的值
        map.put("劉亦菲","20");
        map.put("章子怡", "22");
        map.put("田馥甄", "24");
        map.put("陳綺貞","22");

        //遍歷方法1:通過鍵來找值
        Set<String> set= map.keySet();
        for(String s:set) {
            String value= map.get(s);
            System.out.println(s+"="+value);
        }

        //遍歷方法2:直接得到鍵值對的集合
        Set<Map.Entry<String,String>> set2 = map.entrySet();
        for(Map.Entry<String,String> m:set2){
            System.out.println(m.getKey()+"="+m.getValue());
        }

    }
}

 

~ LinkedHashMap

LinkedHashMap:是Map接口的哈系表和鏈表的實現,具有可預知的迭代順序。

用法和HashMap完全一致。

public class MapDemo2 {
    public static void main(String[] args) {
        LinkedHashMap<String, String> map = new LinkedHashMap<String,String>();

        //添加元素
        //如果鍵是第一次存儲,則返回null
        //如果鍵不是第一次了,則替換舊的值,並返回舊的值
        map.put("劉亦菲","20");
        map.put("章子怡", "22");
        map.put("田馥甄", "24");
        map.put("陳綺貞","22");

        //遍歷方法1:通過鍵來找值
        Set<String> set= map.keySet();
        for(String s:set) {
            String value= map.get(s);
            System.out.println(s+"="+value);
        }

        //遍歷方法2:直接得到鍵值對的集合
        Set<Map.Entry<String,String>> set2 = map.entrySet();
        for(Map.Entry<String,String> m:set2){
            System.out.println(m.getKey()+"="+m.getValue());
        }

    }
}

 

~ TreeMap

TreeMap:基於紅黑樹(Red-Black tree)的 NavigableMap 實現。該映射根據其鍵的自然順序進行排序,或者根據創建映射時提供的 Comparator 進行排序,具體取決於使用的構造方法。

此實現為 containsKeygetputremove 操作提供受保證的 log(n) 時間開銷。這些算法是 Cormen、Leiserson 和 Rivest 的 Introduction to Algorithms 中的算法的改編。

注意,此實現不是同步的。如果多個線程同時訪問一個映射,並且其中至少一個線程從結構上修改了該映射,則其必須 外部同步。

注意:類為鍵值的話需要注意,如果是無參構造,則類需要實現Comparable接口;或者使用帶比較器的構造方法。

public class Demo3 {
    public static void main(String[] args) {
        TreeMap<Student,String> treeMap = new TreeMap<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                // 主要條件,這樣的話是遞增排序
                int num = o1.getAge() - o2.getAge();

                // 次要條件
                int num2 = num==0?o1.getName().compareTo(o2.getName()):num;
                return num2;

            }
        });

        Student s1 = new Student("劉亦菲", 29);
        Student s2 = new Student("章子怡", 25);
        Student s3 = new Student("劉亦菲", 28);

        treeMap.put(s1,"01");
        treeMap.put(s2,"02");
        treeMap.put(s3,"03");

        Set<Student> set= treeMap.keySet();
        for(Student s:set) {
            String value= treeMap.get(s);
            System.out.println(s+"="+value);
        }

    }
}

 

~ Hashtable 和 HashMap 的區別

Hashtable:線程安全,效率低。不允許null鍵和null值;(顯然這養的命名是不規范的,但是由於其出現太早,改的話很不方便,於是就沒有修改)

HashMap:線程不安全,效率高。允許null鍵和null值;(是用來替代Hashtable的)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM