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枚举类的大小,不需要增大。