枚举详解之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内放置的元素不重复。

posted @ 2019-06-12 23:39  爱在惜缘前  阅读(7648)  评论(0编辑  收藏  举报