EnuMap源碼

1、EnuMap介紹

鍵的值爲枚舉類型

主要因爲枚舉類型有兩個特徵:一個是他的值是有限的且預先定義的;而是枚舉值都有一個順序,這兩個特徵使得可以更高效的實現Map接口

內部基於數組實現

2、實現原理

內部有以下實例變量:

 //表示類型信息
    private final Class<K> keyType;

 //表示鍵,是所有可能的枚舉值
    private transient K[] keyUniverse;

//表示對應的值,對應Enum的順序所對應的值
    private transient Object[] vals;

//表示鍵值對的個數
    private transient int size = 0;

//EnumMap中可以存放NUll值
 private static final Object NULL = new Object() {
        public int hashCode() {
            return 0;
        }

        public String toString() {
            return "java.util.EnumMap.NULL";
        }
    };



3、構造方法

  public EnumMap(Class<K> keyType) {
        this.keyType = keyType;
        //以初始化鍵數組
        //原理是最終調用枚舉類型的values方法,
        // 返回所有可能的枚舉值
        keyUniverse = getKeyUniverse(keyType);
      //vals爲鍵對應的值存儲的數組;根據鍵的個數確定其所對應數組的大小
        vals = new Object[keyUniverse.length];
    }

4、put方法

 public V put(K key, V value) {

        //檢查鍵的類型
        typeCheck(key);

        //如果類型正確,調用ordinal獲取索引index
        int index = key.ordinal();
        //並將值value放入數組vals[index]中
        Object oldValue = vals[index];
        //EnuMap允許值爲null,爲了區別null值與沒有null值,
        //EnuMap將null值包裝成一個特殊的對象
        //有兩個輔助放大用於null的打包和解包
        vals[index] = maskNull(value);
        if (oldValue == null)
            size++;
        return unmaskNull(oldValue);
    }

//如果鍵類型不對,則會拋出異常
    private void typeCheck(K key) {
        Class<?> keyClass = key.getClass();
        if (keyClass != keyType && keyClass.getSuperclass() != keyType)
            throw new ClassCastException(keyClass + " != " + keyType);
    }



  /* @return the ordinal of this enumeration constant
    
    返回鍵在枚舉類中的順序
    */
    public final int ordinal() {
        return ordinal;
    }

5、get方法

  public V get(Object key) {
        //如果鍵有效,通過ordinal方法獲取索引
        //然後直接在值數組vals裏找
        return (isValidKey(key) ?
                unmaskNull(vals[((Enum<?>)key).ordinal()]) : null);
    }

6、containsValue

  public boolean containsValue(Object value) {
        //打包
        value = maskNull(value);
        //遍歷數組進行比較
        for (Object val : vals)
            if (value.equals(val))
                return true;

        return false;
    }

7、remove方法

 public V remove(Object key) {
     //對鍵進行檢查:類型檢查
        if (!isValidKey(key))
            return null;
     //獲取待刪除鍵的索引
        int index = ((Enum<?>)key).ordinal();
        Object oldValue = vals[index];
        vals[index] = null;
        if (oldValue != null)
            size--;
        return unmaskNull(oldValue);
    }

8、小結

在這裏插入圖片描述

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