EnumMap的实现原理
EnumMap底层是通过数组实现的,他是通过Enum的ordinal实现对数组的索引,当我们要使用get方法,实际上是对数组vals[index]做索引操作,而相比于hashMap实际上是先进行hash,然后针对entry做next遍历,因此比较下来EnumMap的get方法的效率相对HashMap等要高一些。
重要方法的实现
1.get方法
/**
* Returns the value to which the specified key is mapped,
* or {@code null} if this map contains no mapping for the key.
*
* <p>More formally, if this map contains a mapping from a key
* {@code k} to a value {@code v} such that {@code (key == k)},
* then this method returns {@code v}; otherwise it returns
* {@code null}. (There can be at most one such mapping.)
*
* <p>A return value of {@code null} does not <i>necessarily</i>
* indicate that the map contains no mapping for the key; it's also
* possible that the map explicitly maps the key to {@code null}.
* The {@link #containsKey containsKey} operation may be used to
* distinguish these two cases.
*/
public V get(Object key) {
return (isValidKey(key) ?
unmaskNull(vals[((Enum)key).ordinal()]) : null);
}
从源码中我们可以看出,get方法是通过对数组取值,时间复杂度为O(1)。
2.put方法
/**
* Associates the specified value with the specified key in this map.
* If the map previously contained a mapping for this key, the old
* value is replaced.
*
* @param key the key with which the specified value is to be associated
* @param value the value to be associated with the specified key
*
* @return the previous value associated with specified key, or
* <tt>null</tt> if there was no mapping for key. (A <tt>null</tt>
* return can also indicate that the map previously associated
* <tt>null</tt> with the specified key.)
* @throws NullPointerException if the specified key is null
*/
public V put(K key, V value) {
typeCheck(key);
int index = key.ordinal();
Object oldValue = vals[index];
vals[index] = maskNull(value);
if (oldValue == null)
size++;
return unmaskNull(oldValue);
}
put方法的关键就是key.ordinal(),可以看出EnumMap依赖其key是Enum这一属性,通过Enum的序列取到响应的值。
3.初始化
/**
* Creates an empty enum map with the specified key type.
*
* @param keyType the class object of the key type for this enum map
* @throws NullPointerException if <tt>keyType</tt> is null
*/
public EnumMap(Class<K> keyType) {
this.keyType = keyType;
keyUniverse = getKeyUniverse(keyType);
vals = new Object[keyUniverse.length];
}
EnumMap数组初始化大小为Enum枚举类的大小,不需要增大。