1. 程式人生 > 實用技巧 >java容器體系(五)----Map

java容器體系(五)----Map

  本來應該先講一下 Collection 的其他實現方式的,但相比於 Map 來說,Map 更為常用,先講一下Map好啦。

  java 中的 Map 是用儲存 key-value 形式的鍵值對的,Collection 屬於單列集合,而 Map 是雙列集合

  Map 中不允許有重複的 key 值,每一個 key 對映一個值。

  Map 的常用實現類的類圖如下所示:

  分析一下Map當中的宣告方法:

  (1)size()

int size(); // 該方法返回的是Map中鍵值對(key-value)的數量,當鍵值對的數量超過Integer.MAX_VALUE時,返回的是Integer.MAX_VALUE

  (2)isEmpty()

boolean isEmpty(); // 判斷Map中是否存在鍵值對,有的話返回false,沒有的話返回true

  (3)containsKey(Object key)

boolean containsValue(Object value); // 當Map中存在至少一個鍵值對的值為value時返回true,不存在時返回false

  (4)get(Object key)

V get(Object key); // 返回Map中鍵對應的值,不存在鍵時則返回null

  (5)put(K key, V value)

V put(K key, V value); //
往Map中存入鍵值對

  (6)remove(Object key)

V remove(Object key); // 根據鍵刪除鍵值對

  (7)putAll(Map<? extends K, ? extends V> m)

void putAll(Map<? extends K, ? extends V> m); // 將一個Map中的元素全部複製到另一個Map當中去

  (8)clear()

void clear(); // 清空Map中的鍵值對

  (9)keySet()

Set<K> keySet(); // 返回Map中鍵的集合,因為它內部的key是不重複的,因此返回Set

  (10)values()

Collection<V> values(); // 與keySet()不同的是,返回的是Map中value集合,元素是可能重複的

  (11)entrySet()

Set<Map.Entry<K, V>> entrySet(); // 返回的是Map中的鍵值對(Map.Entry)集合

  (12)getOrDefault(Object key, V defaultValue)

/**
     * @param key Map中將要尋找的鍵值
     * @param defaultValue 沒有找到鍵對應的值時,返回的defaultValue 
     * @return 返回key對應的value值,不存在對應的key時,則返回defaultValue 
     * 注意該方法體是存在已Map介面中的,使用了default進行修飾,在介面中存在方法體,這是java 1.8 所允許的,方法需要被 defalt 或者 static 進行修飾 
     * @since 1.8
     */

default V getOrDefault(Object key, V defaultValue) {
        V v;
        // 判斷containsKey(key)是因為在HahMap中允許鍵值對中的值為null
        return (((v = get(key)) != null) || containsKey(key))
            ? v
            : defaultValue;
}            

  (13)forEach(BiConsumer<? super K, ? super V> action)

   /**
     * 這是java 1.8 開始提供的方法,目的是遍歷Map中的鍵值對,可以看到該方法內部使用的是內部的entrySet()進行遍歷,在遍歷過程中將key與value傳入BiConsumer呼叫
     *
     * @param action The action to be performed for each entry
     * removed during iteration
     * @since 1.8
     */
default void forEach(BiConsumer<? super K, ? super V> action) {
        Objects.requireNonNull(action);
        for (Map.Entry<K, V> entry : entrySet()) {
            K k;
            V v;
            try {
                k = entry.getKey();
                v = entry.getValue();
            } catch(IllegalStateException ise) {
                // this usually means the entry is no longer in the map.
                throw new ConcurrentModificationException(ise);
            }
            action.accept(k, v);
        }
    }

  使用方法如下:

  (14)putIfAbsent(K key, V value)

/**
   * 先呼叫get(key) 方法
   * 存在幾種情況:
   * 1、Map中不存在對應的key, 呼叫put(key, value)存入鍵值對
   * 2、Map中存在對應的key,但是對應的值為null,呼叫put(key, value)存入鍵值對
   * 3、Map中存在對應的key,但是對應的值不為null,則值不會被更新
   * 最後返回先前通過 get(key)獲取到的返回值 
 **/
default V putIfAbsent(K key, V value) {
        V v = get(key);
        if (v == null) {
            v = put(key, value);
        }

        return v;
}            

 剩下的都是java 1.8開始才提供的方法內容,平時很少用到,先不講了。

 講一下Map.Entry,它是Map中的內部介面,Map中的每個元素都是一個Entry。interface Entry<K,V> {

/**
         * 返回元素的鍵(key)
         */
        K getKey();

        /**
         * 返回元素的值(value)
         */
        V getValue();

        /**
         * 設定當前元素的值(value)
         */
        V setValue(V value);

        /**
         * 判斷兩個元素是否相等,即同時判斷key和value
         */
        boolean equals(Object o);

        /**
         * 返回Hash碼,具體在實現中重寫*/
        int hashCode();

        /**
         * 返回一個根據key比較的Comparator
         *
         * @param  <K> the {@link Comparable} type of then map keys
         * @param  <V> the type of the map values
         * @return a comparator that compares {@link Map.Entry} in natural order on key.
         * @see Comparable
         * @since 1.8
         */
        public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey() {
            return (Comparator<Map.Entry<K, V>> & Serializable)
                (c1, c2) -> c1.getKey().compareTo(c2.getKey());
        }

        /**
         * 返回一個根據key比較的Comparator
* * @param <K> the type of the map keys * @param <V> the {@link Comparable} type of the map values * @return a comparator that compares {@link Map.Entry} in natural order on value. * @see Comparable * @since 1.8 */ public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> comparingByValue() { return (Comparator<Map.Entry<K, V>> & Serializable) (c1, c2) -> c1.getValue().compareTo(c2.getValue()); } /** * Returns a comparator that compares {@link Map.Entry} by key using the given * {@link Comparator}. * * <p>The returned comparator is serializable if the specified comparator * is also serializable. * * @param <K> the type of the map keys * @param <V> the type of the map values * @param cmp the key {@link Comparator} * @return a comparator that compares {@link Map.Entry} by the key. * @since 1.8 */ public static <K, V> Comparator<Map.Entry<K, V>> comparingByKey(Comparator<? super K> cmp) { Objects.requireNonNull(cmp); return (Comparator<Map.Entry<K, V>> & Serializable) (c1, c2) -> cmp.compare(c1.getKey(), c2.getKey()); } /** * Returns a comparator that compares {@link Map.Entry} by value using the given * {@link Comparator}. * * <p>The returned comparator is serializable if the specified comparator * is also serializable. * * @param <K> the type of the map keys * @param <V> the type of the map values * @param cmp the value {@link Comparator} * @return a comparator that compares {@link Map.Entry} by the value. * @since 1.8 */ public static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp) { Objects.requireNonNull(cmp); return (Comparator<Map.Entry<K, V>> & Serializable) (c1, c2) -> cmp.compare(c1.getValue(), c2.getValue()); } }

putIfAbsent(K key, V value)