重新開始學Java——集合框架之Map(24)

Map

官方聲明如下:

public interface Map<K,​V>

此時可以看到,Map是一個接口,其中有泛型K、V兩個。描述如下:

An object that maps keys to values. A map cannot contain duplicate keys; each key can map to at most one value.

將鍵映射到值的對象。映射不能包含重複的鍵;因此,Map不能包含重複的鍵。每個鍵最多隻能映射到一個值。

Map內部的方法

  • Put 與 Get 方法
/**
 * 研究 Map 中方法的使用
 * 1、 put 方法的作用 和 返回值的意義
 * 2、 get 方法的作用
 */
public class TestMap2 {
    public static void main(String[] args) {
        Map<String, Double> map = new HashMap<>();
        // put 將 key 和 value 放入到 map 集合中,並返回這個”鍵值對“的“值” 這句話不對
        // 將指定的值與此映射中的指定鍵關聯(可選操作)
        // put 將制定的值 8000.0 與此映射的制定的鍵"ThinkPadE530"關聯
        // 如果制定的鍵"ThinkPad E530" 曾經在當前的 map 中存在,則用新的值替換老的值
        // put 方法返回的是 指定的鍵對應的老值(前提是這個鍵在 map 中是存在的,否則返回 null)
        Double v = map.put("ThinkPad E530", 8000.0);
        System.out.println(v);
        System.out.println(map.toString());
        v = map.put("IdeaPad Yaga", 7000.0);
        System.out.println(v);
        System.out.println(map.toString());
        v = map.put("ThinkPad E530", 800.0);
        System.out.println("v = " + v);
        System.out.println(map.toString());
        // 根據 key 取出相應的 value
        Double value = map.get("ThinkPad E530");
        System.out.println(value);
        value = map.get("張無忌");
        System.out.println(value);
    }
}

  • ContainsKey 與 ContainsValue
/**
 * 研究 Map 中方法的使用
 * 1、 containsKey 的作用(內部採用 key 的 equals 比較)
 * 2、 containsValue 的作用(內部採用 value 的 equals 比較)
 */
public class TestMap3 {
    public static void main(String[] args) {
        Map<String, Double> map = new HashMap<>();
        map.put("ThinkPad E530", 8000.0);
        map.put("IdeaPad Yaga", 7000.0);
        System.out.println(map.containsKey("張無忌")); // 判斷時採用 key 對象的 equals 方法比較
        System.out.println(map.containsKey("ThinkPadE530"));// 判斷某個鍵存在於 map 中
        System.out.println(map.containsValue(9000.0)); // 判斷某個值存在於 map 中
        // 8000 自動包裝成 Integer 對象
        System.out.println(map.containsValue(8000)); // 判 斷時採用 value 對象的 equals 方法比較
    }
}

  • isEmpty、 remove、 clear
/**
 * 研究 Map 中方法的使用:
 * 1、 isEmpty
 * 2、 remove
 * 3、 clear
 */
public class TestMap4 {
    public static void main(String[] args) {
        Map<Integer,String> books = null;
        System.out.println(books == null) ; // 集合變量 books是空的(棧中 books 沒有存儲數據,存儲的是 null)
        books = new HashMap<>(); // 創建 HashMap 對象,並賦值給 books 變量,此時 books 一定不是 null,但是集合中什麼都沒有,因此是個空集
        System.out.println(books.isEmpty()) ; // 判斷 map 集合是否是空的
        books.put(0001, "Java 從入門到精通");
        books.put(0002, "Java 編程思想");
        books.put(0003, "java 數據結構與算法");
        books.put(0004, "深入 java 虛擬機(第二版) ");
        books.put(0005, "瘋狂 Java 講義(第三版) ");
        System.out.println(books.isEmpty()) ; // 判斷 map 集合是否是空的
        String value = books.get(1); // 獲得 key 是 1 的那個 value
        System.out.println(value);
        value = books.remove(1); // 根據制定的 key 刪除“鍵值對”,並且返回“值”
        System.out.println(value);
        System.out.println(books);
        books.clear(); // 清空集合
        System.out.println(books);
    }
}

迭代 map

/**
 * 研究 Map 中方法的使用
 * 1、 entrySet
 * 2、 keySet
 * 3、 values77
 */
public class TestMap5 {
    public static void main(String[] args) {
        Map<Integer, String> books = new HashMap<>();
        books.put(0001, "你不知道的 JavaScript");
        books.put(0002, "Java 編程思想");
        books.put(0003, "java 數據結構與算法");
        books.put(0004, "深入 java 虛擬機(第二版) ");
        books.put(0005, "瘋狂 Java 講義(第三版) ");
        /*
        Set<?> entries = books.entrySet();
        System.out.println(entries);
        // 用 foreach 或 iterator 來迭代 Set 集合
        for (Object object : entries) {
        System.out.println(object);
        }
        */
        // Set<Map.Entry<K, V>> entries = books.entrySet(); 確定 set 中存放 Entry
        Set<Map.Entry<Integer, String>> entries =
                books.entrySet(); // Integer String 確定 Entry 中存放的是什麼

        // 迭代時 每次循環都可以獲得一個 entry 對象,也就是一組鍵值對,因此可以直接得到 key,同時也可以得到 value
        for (Map.Entry<Integer, String> e : entries) {
            System.out.println(e.getKey() + " : " + e.getValue());
        }
        // 也可以用迭代器迭代(entries.iterator() )
        System.out.println("<---------------------------------------------------->");
        // 得到所有的 key 組成的 Set 集合
        Set<Integer> keys = books.keySet();
        for (Integer i : keys) {
            // 可以根據 key 取出 value
            System.out.println(books.get(i) + " : " + i);
        }
        System.out.println("<---------------------------------------------------->");
        Collection<String> c = books.values();
        for (String string : c) {
            System.out.println(string);
            // 能不能根據 Value 獲取的 key?
        }
        System.out.println(c instanceof Set); // false79
        System.out.println(c instanceof List); // false
        System.out.println(c.getClass()); // HashMap$Values
    }
}

java.util.HashMap

HashMap僅僅查看構造方法,不做過多的描述。

HashMap():Constructs an empty HashMap with the default initial capacity (16) and the default load factor (0.75).
HashMap​(int initialCapacity):Constructs an empty HashMap with the specified initial capacity and the default load factor (0.75).
HashMap​(int initialCapacity, float loadFactor):Constructs an empty HashMap with the specified initial capacity and load factor.
HashMap​(Map<? extends K,​? extends V> m):Constructs a new HashMap with the same mappings as the specified Map.

可以看到,HashMap具體的構造方法與HashSet的構造方法是差不多的,那麼在這裏就不進行具體的翻譯了。

示例如下:

/**
 * 1、 HashMap 內部採用哈希表來存儲“鍵值對”
 * HashMap 中提供了一個 hash 方法,用來根據 key 計算“鍵值對”的 hash 值
 * 2、創建 HashMap 實例是,並沒有直接創建數組對象
 * 3、在調用 put 方法時,如果是第一次調用,就創建內部的哈希 表,並將元素放入其中
 * 如果不是第一次,則需要考慮是否要擴大容量(根據加載 因子來確定)
 */
public class TestHashMap {
    public static void main(String[] args) {
        // HashMap 的 默 認 容 量 是 16(DEFAULT_INITIAL_CAPACITY)
        // 創建一個加載因子爲 0.75f 的 HashMap 實例
        HashMap<String , Integer > map = new HashMap<>(); // 容量是 16 加載因子是 0.75
        // 第一次向 map 中放入鍵值對時,才創建內部數組(即哈希表)
        map.put("男生", 20);
        map.put("女生", 15);
        map.put("老師", 6);
        // 創建 HashMap 實例時,並沒有直接創建內部的哈希表
        HashMap<String,Integer> books = new
                HashMap<>(10,0.5f); // 容量是 10,加載因子是 0.5
        // 第一次向 map 中放入鍵值對時,才創建內部數組(即哈希表)
        books.put("Java 編程思想", 10);
        books.put("深入 Java 虛擬機", 20);
    }
}

java.util.TreeMap

TreeMap與TreeSet 的使用基本是一樣的,因爲TreeSet內部是由TreeMap實現的。

【I】 java.util.SortedMap:表示根據 key 進行排序的”鍵值對(key-value) “集合
【C】 java.util.TreeMap : 基於紅黑樹(Red-Black tree)的NavigableMap 實現81
TreeMap 實現了 NavigableMap 接口; NavigableMap 繼承了SortedMap 接口

根據 key 進行排序:
	自然順序: Key 對應的那個類必須實現 java.lang.Comparable
	(compareTo)
	比較器順序:在 java.util.Comparator 中的 compare 方法實現比較

示例如下:

public class Bear {
	private Integer id;
	private String name;
	private char gender;
	public Bear() {
		super();
	}
	public Bear(Integer id, String name, char gender) {
		super();
		this.id = id;
		this.name = name;
		this.gender = gender;
	}
	// getter and setter
}

/**
 * 1、使用 TreeMap 的無參構造創建的對象是以 key 的自然順序
 爲排序依據
 * 2、如果 key 對應的類沒有實現自然排序,則需要在創建
 TreeMap 對象時,指定比較器
 * 3、 TreeMap 內部基於紅黑樹實現(自己挑戰)
 */
public class TestTreeMap {
    public static void main(String[] args) {
        Map<String,Double> tm = new TreeMap<>();
        tm.put("hello", 1.5);
        tm.put("ipad", 2.5);
        System.out.println(tm);
        tm.put("apple", 4.8);
        System.out.println(tm);
        Comparator<Bear> c = new Comparator<Bear>(){
            @Override
            public int compare(Bear o1, Bear o2) {
                int x = 0 ;
                if(o1!=null && o2!=null && o1.getId()!=null &&
                        o2.getId()!=null){
                    x = o1.getId() - o2.getId();83
                }
                return x;
            }
        };
        Map<Bear, Double> foods = new TreeMap<>(c);
        System.out.println(foods);
        Bear b1 = new Bear(1,"熊大",'男');
        foods.put(b1, 30.0);
        Bear b2 = new Bear(2,"熊二",'男');
        foods.put(b2, 300.0);
        Set<Map.Entry<Bear,Double>> entries =
                foods.entrySet();
        for (Map.Entry<Bear,Double> e : entries) {
            Bear bear = e.getKey();
            System.out.println(bear.getId()+":" +
                    bear.getName() + " : " + e.getValue());
        }
    }
}

總結

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章