EnumMap&EnumSet的用法

EnumMap 的用法

EnumMap 在使用上跟 HashMap 差不多,但是 EnumMap 的性能更好,所以,如果键为 Enum 类型时,建议使用 EnumMap 代替 HashMap

public enum Color {
    YELLOW, RED, BLUE, BLACK
}

public static void main(String[] args) {
    EnumMap<Color, Integer> colorMap = new EnumMap<>(Color.class);
    for (Color value : Color.values()) {
        colorMap.put(value, value.ordinal());
    }
    colorMap.forEach((k, v) -> System.out.println(k + " -> " + v));
}

输出结果如下

YELLOW -> 0
RED -> 1
BLUE -> 2
BLACK -> 3

使用上没什么可说的,关键从源码讲一下 EnumMap 为什么在性能上会更好。

看一下 EnumMap 的结构定义

  • keyType:记录枚举数据类型
  • keyUniverse:存储所有的枚举实例,
  • vals:存储值,与 keyUniverse 数组等长,存储的值与 keyUniverse 的索引对应
public class EnumMap<K extends Enum<K>, V> 
        extends AbstractMap<K, V> implements Serializable, Cloneable {
    private final Class<K> keyType;
    private transient K[] keyUniverse;
    private transient Object[] vals;
    private transient int size = 0;
}

EnumMap 在初始化时就会将枚举的所有实例存储到 keyUniverse 数组,vals 则初始化为与 keyUniverse 等长的数组,每个元素填充为 null

新增数据时,获取枚举实例的 ordinal 作为索引,然后直接赋值到 vals 相应的索引即可,时间复杂度为 O1

public V put(K var1, V var2) {
    this.typeCheck(var1);
    int var3 = var1.ordinal();
    Object var4 = this.vals[var3];
    this.vals[var3] = this.maskNull(var2);
    if (var4 == null) {
        ++this.size;
    }
    return this.unmaskNull(var4);
}

获取数据时,获取枚举实例的 ordinal 作为索引,直接从 vals 数组获取相应索引位置的值即可,时间复杂度为 O1

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

EnumMap 之所以可以这么操作,是因为枚举的实例是有限的,而每个实例通过 ordinal() 方法可以确定其索引位置,这样 Map 的操作就转化成了对 vals 数组的操作,所以效率非常高。

EnumSet 的用法

创建空集合

EnumSet.noneOf(Color.class);

创建包含所有元素的集合

EnumSet.allOf(Color.class);

创建包含指定元素的集合

EnumSet.of(Color.YELLOW, Color.RED);

创建范围集合

第一个枚举值的索引位置必须大于第二个枚举值,不然会导致异常。

public static void main(String[] args) {
    EnumSet<Color> rangeColorSet = EnumSet.range(Color.YELLOW, Color.BLUE);
    // 输出 [YELLOW, RED, BLUE]
    System.out.println(rangeColorSet);
}

补集

public static void main(String[] args) {
    EnumSet<Color> partColorSet = EnumSet.of(Color.YELLOW, Color.RED);
    EnumSet<Color> remainderColorSet = EnumSet.complementOf(partColorSet);
    // 输出 [BLUE, BLACK]
    System.out.println(remainderColorSet);
}

复制创建集合

public static void main(String[] args) {
    List<Color> colorList = new ArrayList<>();
    Collections.addAll(colorList, Color.YELLOW, Color.RED, Color.RED);
    // 输出 [YELLOW, RED, RED]
    System.out.println(colorList);
    EnumSet<Color> colorSet = EnumSet.copyOf(colorList);
    // 输出 [YELLOW, RED]
    System.out.println(colorSet);
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值