枚举详解之EnumSet、EnumMap用法

枚举简单例子
/**
 * @author shuliangzhao
 * @Title: Color
 * @ProjectName design-parent
 * @Description: TODO * @date 2019/6/12 22:35 */ public enum Color { YELLOW, RED, BLUE, PURPLE, BLACK; } 
/**
 * @author shuliangzhao
 * @Title: ColorEnumTest
 * @ProjectName design-parent
 * @Description: TODO * @date 2019/6/12 22:37 */ public class ColorEnumTest { public static void main(String[] args) { Color color = Color.BLUE; switch (color) { case RED: System.out.println("红色"); break; case BLUE: System.out.println("蓝色"); break; case PURPLE: System.out.println("紫色"); break; case BLACK: System.out.println("黑色"); break; case YELLOW: System.out.println("黄色"); break; default: System.out.println("蓝色"); break; } } } 

测试结果

 
image.png

Color枚举的本质就是一个类,编译器会自动为我们生成Color类,通过反编译得到该类如下:

final class Color extends Enum { //编译器为我们添加的静态的values()方法 public static Color[] values() { return (Color[])$VALUES.clone(); } //编译器为我们添加的静态的valueOf()方法,注意间接调用了Enum也类的valueOf方法 public static Color valueOf(String s) { return (Color)Enum.valueOf(com/sl/emun/Color, s); } //私有构造函数 private Color(String s, int i) { super(s, i); } //前面定义的7种枚举实例 public static final Color YELLOW; public static final Color RED; public static final Color BLUE; public static final Color PURPLE; public static final Color BLACK; private static final Color $VALUES[]; static { //实例化枚举实例 YELLOW = new Color("YELLOW", 0); RED = new Color("RED", 1); BLUE = new Color("BLUE", 2); PURPLE = new Color("PURPLE", 3); BLACK = new Color("BLACK", 4); $VALUES = (new Color[] { YELLOW, RED, BLUE, PURPLE, BLACK }); } } 

可以看出每个枚举类型颜色是该Color类的一个实例对象,该构成方式和单例模式有些类似,故可以用只有一个枚举类型的枚举作为单例模式,而且枚举的构造器由编译器管理安全性十分高,既可以防止反射破解也可以防止反序列破解。

EnumMap用法
/**
 * @author shuliangzhao
 * @Title: EnumMapTest
 * @ProjectName design-parent
 * @Description: TODO * @date 2019/6/12 22:49 */ public class EnumMapTest { public static void main(String[] args) { EnumMap<Color,String> enumMap = new EnumMap(Color.class); enumMap.put(Color.BLACK,"黑色"); enumMap.put(Color.BLUE,"蓝色"); System.out.println(enumMap); System.out.println(enumMap.get(Color.BLUE)); } } 

运行结果

 
image.png

EnumMap put方法

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); } 

首先调用typeCheck检查键的类型,如果类型不对,会抛出异常。类型正确的话,调用ordinal获取索引index,并将值value放入值数组vals[index]中。EnumMap允许值为null,为了区别null值与没有值,EnumMap将null值包装成了一个特殊的对象,有两个辅助方法用于null的打包和解包,打包方法为maskNull,解包方法为unmaskNull。

get方法

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

键有效的话,通过ordinal方法取索引,然后直接在值数组vals里找。isValidKey的代码与typeCheck类似,但是返回boolean值而不是抛出异常。

以上就是EnumMap的基本实现原理,内部有两个数组,长度相同,一个表示所有的键,一个表示对应的值,值为null表示没有该键值对,键都有一个对应的索引,根据索引可直接访问和操作其键和值,效率很高。

EnumSet

EnumSet这是一个用来操作Enum的集合,是一个抽象类,它有两个继承类:JumboEnumSet和RegularEnumSet。在使用的时候,需要确定枚举类型。它的特点也是速度非常快,为什么速度很快呢?因为每次add的时候,每个枚举值只占一个长整型的一位。
EnumSet.noneOf()方法创建一个空的set

public class EnumSetTest {

    public static void main(String[] args) { EnumSet<Color> enumSet = EnumSet.noneOf(Color.class); System.out.println(enumSet); enumSet.add(Color.BLUE); enumSet.add(Color.PURPLE); System.out.println(enumSet); } } 

运行结果

 
image.png

EnumSet.allOf()方法创建一个满的set

/**
 * @author shuliangzhao
 * @Title: EnumSetTest
 * @ProjectName design-parent
 * @Description: TODO * @date 2019/6/12 23:24 */ public class EnumSetTest { public static void main(String[] args) { /*EnumSet<Color> enumSet = EnumSet.noneOf(Color.class); System.out.println(enumSet); enumSet.add(Color.BLUE); enumSet.add(Color.PURPLE); System.out.println(enumSet);*/ EnumSet<Color> enumSet = EnumSet.allOf(Color.class); System.out.println(enumSet); } } 

运行结果

 
image.png

EnumSet.range创建指定范围set

public class EnumSetTest {

    public static void main(String[] args) { /*EnumSet<Color> enumSet = EnumSet.noneOf(Color.class); System.out.println(enumSet); enumSet.add(Color.BLUE); enumSet.add(Color.PURPLE); System.out.println(enumSet); EnumSet<Color> enumSet = EnumSet.allOf(Color.class); System.out.println(enumSet);*/ EnumSet<Color> enumSet = EnumSet.range(Color.YELLOW,Color.BLUE); System.out.println(enumSet); } } 
 
image.png

EnumSet.complementOf补集创建set

public class EnumSetTest {

    public static void main(String[] args) { /*EnumSet<Color> enumSet = EnumSet.noneOf(Color.class); System.out.println(enumSet); enumSet.add(Color.BLUE); enumSet.add(Color.PURPLE); System.out.println(enumSet); EnumSet<Color> enumSet = EnumSet.allOf(Color.class); System.out.println(enumSet);*/ EnumSet<Color> enumSet = EnumSet.range(Color.YELLOW,Color.BLUE); System.out.println(enumSet); EnumSet<Color> enumSet1 = EnumSet.complementOf(enumSet); System.out.println(enumSet1); } } 

运行结果

 
image.png

EnumSet.copyOf复制创建set

public class EnumSetTest {

    public static void main(String[] args) { /*EnumSet<Color> enumSet = EnumSet.noneOf(Color.class); System.out.println(enumSet); enumSet.add(Color.BLUE); enumSet.add(Color.PURPLE); System.out.println(enumSet); EnumSet<Color> enumSet = EnumSet.allOf(Color.class); System.out.println(enumSet); EnumSet<Color> enumSet = EnumSet.range(Color.YELLOW,Color.BLUE); System.out.println(enumSet); EnumSet<Color> enumSet1 = EnumSet.complementOf(enumSet); System.out.println(enumSet1);*/ EnumSet<Color> enumSet = EnumSet.range(Color.YELLOW,Color.BLUE); System.out.println(enumSet); EnumSet<Color> enumSet1 = EnumSet.copyOf(enumSet); System.out.println(enumSet1); } } 

运行结果

 
image.png

EnumSet.copyOf复制创建集合

public class EnumSetTest {

    public static void main(String[] args) { /*EnumSet<Color> enumSet = EnumSet.noneOf(Color.class); System.out.println(enumSet); enumSet.add(Color.BLUE); enumSet.add(Color.PURPLE); System.out.println(enumSet); EnumSet<Color> enumSet = EnumSet.allOf(Color.class); System.out.println(enumSet); EnumSet<Color> enumSet = EnumSet.range(Color.YELLOW,Color.BLUE); System.out.println(enumSet); EnumSet<Color> enumSet1 = EnumSet.complementOf(enumSet); System.out.println(enumSet1); EnumSet<Color> enumSet = EnumSet.range(Color.YELLOW,Color.BLUE); System.out.println(enumSet); EnumSet<Color> enumSet1 = EnumSet.copyOf(enumSet); System.out.println(enumSet1);*/ List<Color> colors = new ArrayList<>(); colors.add(Color.PURPLE); colors.add(Color.BLUE); colors.add(Color.BLUE); System.out.println(colors); EnumSet<Color> enumSet = EnumSet.copyOf(colors); System.out.println(enumSet); } } 

运行结果

 
image.png

注意:通过结果可以看出ArrayList内放置的元素可以重复,而EnumSet内放置的元素不重复。

猜你喜欢

转载自www.cnblogs.com/treeshu/p/11013511.html
今日推荐