java源码解读--enummap

EnumMap

  1. EnumMap要求key必须为枚举类,且创建EnumMap时必须指定key的类型
  2. key不能为null,但是value允许
  3. 底层为数组结构
  4. 元素顺序为Enum顺序,与插入顺序无关
  5. 非线程安全,不会抛出ConcurrentModificationException

类定义

继承AbstractMap

1
2
3

public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V>
implements java.io.Serializable, Cloneable

成员变量

1
2
3
4
5
6
7
8
//key的类型
private final Class<K> keyType;
//存放key值,该值在初始化时就已经从枚举类中读入
private transient K[] keyUniverse;
//存放value值
private transient Object[] vals;
//数组大小
private transient int size = 0;

put

1
2
3
4
5
6
7
8
9
10
11
12
13
14

public V put(K key, V value) {
//检查key必须是keyType或者其子类,否则报错
typeCheck(key);
//ordinal用于返回该枚举值在枚举类中的顺序,根据声明顺序而定,此处以该值作为下标
int index = key.ordinal();
//取出旧值
Object oldValue = vals[index];
//如果value为null,此处maskNull会返回一个固定的Object来代替
vals[index] = maskNull(value);
if (oldValue == null)
size++;
return unmaskNull(oldValue);
}

get

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//先判断是否合法,合法就通过ordinal访问下标,否则返回null
public V get(Object key) {
return (isValidKey(key) ?
unmaskNull(vals[((Enum<?>)key).ordinal()]) : null);
}
//判断key是否合法
private boolean isValidKey(Object key) {
if (key == null)
return false;

//判断类型是否合法
Class<?> keyClass = key.getClass();
return keyClass == keyType || keyClass.getSuperclass() == keyType;
}

remove

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

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);
}
-------------本文结束感谢您的阅读-------------

本文标题:java源码解读--enummap

文章作者:小建儿

发布时间:2018年06月13日 - 10:06

最后更新:2018年06月13日 - 10:06

原始链接:http://yajian.github.io/java源码解读-enummap/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。