EnumMap 分析

本文介绍了EnumMap的线程不安全性质,并提及通过特定方式创建线程安全的EnumMap。EnumMap在性能上优于HashMap。

EnumMap(线程不安全):

   // 声明时首先会再内部根据传入的枚举类型的属性长度,创建等长的数组
   public EnumMap(Class<K> keyType) {
        this.keyType = keyType;
        keyUniverse = getKeyUniverse(keyType);
        vals = new Object[keyUniverse.length];
    }
    public V put(K key, V value) {
        typeCheck(key); // 首先进行类型检查

        int index = key.ordinal(); // 获取枚举类型的ordinal值,直接放到数组的对应index位置
        Object oldValue = vals[index];
        vals[index] = maskNull(value);
        if (oldValue == null)
            size++;
        return unmaskNull(oldValue);
    }
    
    /**
     * 进行类型检查,如果不是添加的key的类型和声明时的类型不一致,抛出类型不一致异常
     * 如果添加的key为null,则抛出NPE;
     */
    private void typeCheck(K key) {
        Class<?> keyClass = key.getClass();
        if (keyClass != keyType && keyClass.getSuperclass() != keyType)
            throw new ClassCastException(keyClass + " != " + keyType);
    }
    
    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);
    }

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

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

如果想创建线程安全的EnumMap类,则可以通过如下方式:

// EnumTest 为自己创建的枚举类
Map<EnumTest,String> em = Collections.synchronizedMap(new EnumMap<EnumTest,String>(EnumTest.class) );

 

 特性:

1.线程不安全

2.和HashMap相比,效率要比HashMap高

 

枚举(enum)是一种特殊的数据类型,用于定义一组常量,通常用于表示有限的一组固定值,如星期几、颜色、状态等。它不仅是常量的集合,还能包含字段、方法和构造函数,具有强大和灵活的特点[^1]。 ### 基本概念 在 Java 中,定义枚举类的关键字是 `enum`(全小写),枚举项是该类的实例。例如,定义一个表示方向的枚举类: ```java enum Direction { FRONT, BEHIND, LEFT, RIGHT; } ``` 这里 `FRONT`、`BEHIND`、`LEFT`、`RIGHT` 都是枚举项,该类仅有这四个实例对象。多个枚举项间用逗号分隔,若枚举类只有枚举项,分号可省略,但建议不省略[^3]。 ### 基本用法 在 C 语言里,枚举可直接使用。示例如下: ```c #include <stdio.h> #include <stdlib.h> enum { Q, W, E = 4, R }; int main() { printf("枚举值QWER分别是: %d , %d , %d , %d", Q, W, E, R); return 0; } ``` 在这个例子中,`Q` 默认从 0 开始,`W` 为 1,`E` 被显式赋值为 4,`R` 则为 5 [^2]。 ### 高级特性 #### 构造函数与字段 枚举可以有构造函数和字段。例如: ```java package org.test.algo; public class EnumTest { enum SEASON { SPRING("good"), SUMMER("better"), AUTUMN("best"), WINTER("bad"); String feel = ""; SEASON(String myfeel) { this.feel = myfeel; } } } ``` 这里 `SEASON` 枚举类有一个构造函数,接收一个字符串参数,并将其赋值给 `feel` 字段 [^5]。 #### 自定义方法 若打算自定义方法,需在 `enum` 实例后面添加分号,且 Java 要求先定义 `enum` 实例。示例如下: ```java enum Color { RED, GREEN, BLUE; public void printInfo() { System.out.println("This is " + this.name()); } } ``` 在这个例子中,`Color` 枚举类有一个自定义方法 `printInfo` [^4]。 ### 使用限制 不能使用 `new` 来创建枚举类的对象,在类外只能使用 `类名.枚举项` 的方式来访问枚举实例 [^3]。 ### 枚举与 `switch` 枚举常与 `switch` 语句结合使用,可增强代码的可读性和安全性。示例如下: ```java enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY } public class EnumSwitchExample { public static void main(String[] args) { Day day = Day.MONDAY; switch (day) { case MONDAY: System.out.println("It's Monday!"); break; case TUESDAY: System.out.println("It's Tuesday!"); break; // 其他情况 } } } ``` ### 与集合的结合使用 在 Java 中,`EnumSet` 和 `EnumMap` 是专门为枚举设计的集合类。`EnumSet` 用于存储枚举类型的元素,`EnumMap` 用于存储键为枚举类型的键值对。示例如下: ```java import java.util.EnumSet; import java.util.EnumMap; enum Size { SMALL, MEDIUM, LARGE } public class EnumCollectionExample { public static void main(String[] args) { // 使用 EnumSet EnumSet<Size> sizes = EnumSet.allOf(Size.class); for (Size size : sizes) { System.out.println(size); } // 使用 EnumMap EnumMap<Size, String> sizeMap = new EnumMap<>(Size.class); sizeMap.put(Size.SMALL, "Small size"); System.out.println(sizeMap.get(Size.SMALL)); } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值