枚举详解之EnumSet、EnumMap用法

枚举详解之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 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 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 enumSet = EnumSet.noneOf(Color.class);

System.out.println(enumSet);

enumSet.add(Color.BLUE);

enumSet.add(Color.PURPLE);

System.out.println(enumSet);*/

EnumSet enumSet = EnumSet.allOf(Color.class);

System.out.println(enumSet);

}

}

运行结果

image.png

EnumSet.range创建指定范围set

public class EnumSetTest {

public static void main(String[] args) {

/*EnumSet enumSet = EnumSet.noneOf(Color.class);

System.out.println(enumSet);

enumSet.add(Color.BLUE);

enumSet.add(Color.PURPLE);

System.out.println(enumSet);

EnumSet enumSet = EnumSet.allOf(Color.class);

System.out.println(enumSet);*/

EnumSet 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 enumSet = EnumSet.noneOf(Color.class);

System.out.println(enumSet);

enumSet.add(Color.BLUE);

enumSet.add(Color.PURPLE);

System.out.println(enumSet);

EnumSet enumSet = EnumSet.allOf(Color.class);

System.out.println(enumSet);*/

EnumSet enumSet = EnumSet.range(Color.YELLOW,Color.BLUE);

System.out.println(enumSet);

EnumSet enumSet1 = EnumSet.complementOf(enumSet);

System.out.println(enumSet1);

}

}

运行结果

image.png

EnumSet.copyOf复制创建set

public class EnumSetTest {

public static void main(String[] args) {

/*EnumSet enumSet = EnumSet.noneOf(Color.class);

System.out.println(enumSet);

enumSet.add(Color.BLUE);

enumSet.add(Color.PURPLE);

System.out.println(enumSet);

EnumSet enumSet = EnumSet.allOf(Color.class);

System.out.println(enumSet);

EnumSet enumSet = EnumSet.range(Color.YELLOW,Color.BLUE);

System.out.println(enumSet);

EnumSet enumSet1 = EnumSet.complementOf(enumSet);

System.out.println(enumSet1);*/

EnumSet enumSet = EnumSet.range(Color.YELLOW,Color.BLUE);

System.out.println(enumSet);

EnumSet enumSet1 = EnumSet.copyOf(enumSet);

System.out.println(enumSet1);

}

}

运行结果

image.png

EnumSet.copyOf复制创建集合

public class EnumSetTest {

public static void main(String[] args) {

/*EnumSet enumSet = EnumSet.noneOf(Color.class);

System.out.println(enumSet);

enumSet.add(Color.BLUE);

enumSet.add(Color.PURPLE);

System.out.println(enumSet);

EnumSet enumSet = EnumSet.allOf(Color.class);

System.out.println(enumSet);

EnumSet enumSet = EnumSet.range(Color.YELLOW,Color.BLUE);

System.out.println(enumSet);

EnumSet enumSet1 = EnumSet.complementOf(enumSet);

System.out.println(enumSet1);

EnumSet enumSet = EnumSet.range(Color.YELLOW,Color.BLUE);

System.out.println(enumSet);

EnumSet enumSet1 = EnumSet.copyOf(enumSet);

System.out.println(enumSet1);*/

List colors = new ArrayList<>();

colors.add(Color.PURPLE);

colors.add(Color.BLUE);

colors.add(Color.BLUE);

System.out.println(colors);

EnumSet enumSet = EnumSet.copyOf(colors);

System.out.println(enumSet);

}

}

运行结果

image.png

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