EnumSet用法
public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E> implements Cloneable, java.io.Serializable
EnumSet 中所有元素都必须是枚举类型。
与其他Set接口的实现类HashSet/TreeSet(内部都是用对应的HashMap/TreeMap实现的)不同的是,EnumSet在内部实现是位向量(稍后分析),它是一种极为高效的位运算操作。
由于直接存储和操作都是bit,因此EnumSet空间和时间性能都十分可观,足以媲美传统上基于 int 的“位标志”的运算,重要的是我们可像操作set集合一般来操作位运算,这样使用代码更简单易懂同时又具备类型安全的优势。
创建EnumSet并不能使用new关键字,因为它是个抽象类,而应该使用其提供的静态工厂方法,EnumSet的静态工厂方法比较多,如下:
// 创建一个具有指定元素类型的空EnumSet。 EnumSet<E> noneOf(Class<E> elementType) //创建一个指定元素类型并包含所有枚举值的EnumSet <E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType) // 创建一个包括枚举值中指定范围元素的EnumSet <E extends Enum<E>> EnumSet<E> range(E from, E to) // 初始集合包括指定集合的补集 <E extends Enum<E>> EnumSet<E> complementOf(EnumSet<E> s) // 创建一个包括参数中所有元素的EnumSet <E extends Enum<E>> EnumSet<E> of(E e) <E extends Enum<E>> EnumSet<E> of(E e1, E e2) <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3) <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4) <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4, E e5) <E extends Enum<E>> EnumSet<E> of(E first, E... rest) //创建一个包含参数容器中的所有元素的EnumSet <E extends Enum<E>> EnumSet<E> copyOf(EnumSet<E> s) <E extends Enum<E>> EnumSet<E> copyOf(Collection<E> c)
使用示例:
enum Color { GREEN , RED , BLUE , BLACK , YELLOW } public static void main(String[] args){ //空集合 EnumSet<Color> enumSet= EnumSet.noneOf(Color.class); System.out.println("添加前:"+enumSet.toString()); enumSet.add(Color.GREEN); enumSet.add(Color.RED); enumSet.add(Color.BLACK); enumSet.add(Color.BLUE); enumSet.add(Color.YELLOW); System.out.println("添加后:"+enumSet.toString()); System.out.println("-----------------------------------"); //使用allOf创建包含所有枚举类型的enumSet,其内部根据Class对象初始化了所有枚举实例 EnumSet<Color> enumSet1= EnumSet.allOf(Color.class); System.out.println("allOf直接填充:"+enumSet1.toString()); System.out.println("-----------------------------------"); //初始集合包括枚举值中指定范围的元素 EnumSet<Color> enumSet2= EnumSet.range(Color.BLACK,Color.YELLOW); System.out.println("指定初始化范围:"+enumSet2.toString()); System.out.println("-----------------------------------"); //指定补集,也就是从全部枚举类型中去除参数集合中的元素,如下去掉上述enumSet2的元素 EnumSet<Color> enumSet3= EnumSet.complementOf(enumSet2); System.out.println("指定补集:"+enumSet3.toString()); System.out.println("-----------------------------------"); //初始化时直接指定元素 EnumSet<Color> enumSet4= EnumSet.of(Color.BLACK); System.out.println("指定Color.BLACK元素:"+enumSet4.toString()); EnumSet<Color> enumSet5= EnumSet.of(Color.BLACK,Color.GREEN); System.out.println("指定Color.BLACK和Color.GREEN元素:"+enumSet5.toString()); System.out.println("-----------------------------------"); //复制enumSet5容器的数据作为初始化数据 EnumSet<Color> enumSet6= EnumSet.copyOf(enumSet5); System.out.println("enumSet6:"+enumSet6.toString()); System.out.println("-----------------------------------"); List<Color> list = new ArrayList<Color>(); list.add(Color.BLACK); list.add(Color.BLACK);//重复元素 list.add(Color.RED); list.add(Color.BLUE); System.out.println("list:"+list.toString()); //使用copyOf(Collection<E> c) EnumSet enumSet7=EnumSet.copyOf(list); System.out.println("enumSet7:"+enumSet7.toString()); /** 输出结果: 添加前:[] 添加后:[GREEN, RED, BLUE, BLACK, YELLOW] ----------------------------------- allOf直接填充:[GREEN, RED, BLUE, BLACK, YELLOW] ----------------------------------- 指定初始化范围:[BLACK, YELLOW] ----------------------------------- 指定补集:[GREEN, RED, BLUE] ----------------------------------- 指定Color.BLACK元素:[BLACK] 指定Color.BLACK和Color.GREEN元素:[GREEN, BLACK] ----------------------------------- enumSet6:[GREEN, BLACK] ----------------------------------- list:[BLACK, BLACK, RED, BLUE] //普通List没有去重 enumSet7:[RED, BLUE, BLACK] //运用此set可以方便的去重枚举 */ }
其实博主认为EnumSet最有价值的是其内部实现原理,采用的是位向量,它体现出来的是一种高效的数据处理方式,这点很值得我们去学习它。
因此EnumSet的内部实现原理还是值得好好学习的。但本文不做过多的讨论了。
总结:多使用枚举,枚举的好处
enum这个关键字,可以理解为跟class差不多,这也个单独的类。
一般的class可以自己new对象,想几个就几个,而这个enum关键字,他就不行,他的实例对象,只能在这个enum里面体现。也就是说,他对应的实例是有限的。这也就是枚举的好处了,限制了某些东西的范围,举个栗子:
一年四季,只能有春夏秋冬,你要是字符串表示的话,那就海了去了,但是,要用枚举类型的话,你在enum的大括号里面把所有的选项,全列出来,那么这个季节的属性,对应的值,只能在里面挑。不能有其他的。
使用枚举的一些规范推荐
1.枚举类名建议带上Enum后缀,枚举成员名称需要全部大写。单词间使用下划线分隔。
2.强制规范:所有的枚举类型成员必须要有注释,说明每个字段的用途。(一般可以使用接口进行强制规范)
枚举类型对象之间的值比较,是可以使用==,直接来比较值,是否相等的,不是必须使用equals方法的哟。 并且,强烈建议使用==,效率更高