程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> 容器--EnumMap,enummap

容器--EnumMap,enummap

編輯:JAVA綜合教程

容器--EnumMap,enummap


一、概述

     EnumMap是一類特殊的Map, 其特殊之處在於KEY需要是枚舉類型,由於枚舉類型的特點是值的個數是固定的,所以,對於EnumMap來說,其所能存儲的個數也就是固定的了。這種類型的Map相對來說是比較簡單的。

 

二、主要實現介紹

  1. 初始化

  由於EnumMap的enum特點,決定了其容器的容量是不變的,所以,在創建一個EnumMap的時候,我們就需要指定其大小,目前創建一個EnumMap主要有以下幾種方式:

     public EnumMap(Class<K> keyType) : 根據鍵的class類型,通過反射的方式得到該枚舉的所有可能值,進而生成一個鍵數組及值數組。

     public EnumMap(EnumMap<K, ? extends V> m) :從另一個EnumMap去初始化,本質上是生成一個副本。

     public EnumMap(Map<K, ? extends V> m):根據另一個Map初始化,和第二個方法相比,多了個對Map的轉化的過程 

 

     以上三種初始化方式之後,在內部都會創建一個key數組和value數組,它們的大小是相同的。特別的,由於對同一類enum來說,其key是固定的,所以key數組是可以復用的。

 

     2. 存儲

     我們來看一下對於put操作的實現     

public V put(K key, V value) {
        typeCheck(key);//類型檢查

        int index = key.ordinal();
        Object oldValue = vals[index];
        vals[index] = maskNull(value);//null值處理
        if (oldValue == null)
            size++;
        return unmaskNull(oldValue);
    }

      可以看到整個實現非常簡單,key對應的value被存儲在vals數組中,key的ordinal對應的下標的位置。

      需要注意的是,在存儲時,系統對於值進行了maskNull的處理,在返回時做了unmaskNull處理,我們接著看下相關的代碼:

    private static final Object NULL = new Object() {
        public int hashCode() {
            return 0;
        }

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

    private Object maskNull(Object value) {
        return (value == null ? NULL : value);
    }

    private V unmaskNull(Object value) {
        return (V) (value == NULL ? null : value);
    }

 

       可以看到這個方法的作用是,如果目標value為null,則用NULL對象來替換,那麼為什麼要這樣做呢?

       這是因為,vals數組中,默認是沒有值的,而這個用null來表示。那麼,EnumMap本身是支持值為null的,如果不做任何處理將vals設置為null,則無法和沒有值的情況進行區分,所以借助於這種方式來實現對於null值的表示。

 

      3. 取值

      和存值一樣,取值也是比較簡單的,如下:

public V get(Object key) {
        return (isValidKey(key) ?
                unmaskNull(vals[((Enum)key).ordinal()]) : null);
    }

      可見相比較於HashMap,這個取值操作是直接定位的,非常快速。

 

      4. key存在判斷

  前面說到,初始化時實際上就已經確定了key的數組,那麼,是否表示所有的key都存在呢?參見實現:

public boolean containsKey(Object key) {
        return isValidKey(key) && vals[((Enum)key).ordinal()] != null;
    }

      可見,如果某個key對應的下標沒有設置值,系統認為這個key是未被包含的。

 

三、總結

 

     從前面的分析我們可以看到,EnumMap的實現非常簡單,而且存取都非常高效,如果我們的業務場景是可以設置幾個固定的key的值的話,那麼用這類key將是非常高效的。

       

    

 

     

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved