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、小结

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值