EnumSet是什么意思?
我有以下例子:
import java.util.EnumSet; import java.util.Iterator; public class SizeSet { public static void main(String[] args) { EnumSet largeSize = EnumSet.of(Size.XL,Size.XXL,Size.XXXL); for(Iterator it = largeSize.iterator();it.hasNext();){ Size size = (Size)it.next(); System.out.println(size); } } } enum Size { S, M, L, XL, XXL, XXXL; }
在这段代码中,我可以理解Enum创build了Enumtypes的Sizes。
我的问题是: largeSize
是EnumSettypes的一个对象? 这是什么意思? 我真的想更好地理解它。
至于任何variables,其types可以在其声明中find:
EnumSet largeSize
所以是的, largeSize
(应该命名为largeSizes
因为它是一个集合)是EnumSet
types的。 它也应该被基因化,因此被宣布为
EnumSet<Size> largeSizes
这意味着, largeSizes
的types是EnumSet
。 EnumSet
是一个包含特定枚举types的枚举实例的Set
,比其他Set
实现(如HashSet
, TreeSet
等)更有效。 要知道EnumSet
是什么,请阅读它的API 。
简化你的代码
EnumSet<Size> largeSize = EnumSet.of(Size.XXXL, Size.XXL, Size.XL, Size.L); for(Size size: largeSize) System.out.print(size+" ");
你可以看到largeSize是一个普通的Set,除了它被devise来存储枚举。 这有什么不同? 首先,JVM知道集合的所有可能的值,这意味着不用存储所有可以使用位图的对象,其中1表示项目存在,0表示不存在。 这也意味着该集合的顺序是顺序值的顺序,即它们被定义的顺序。 这就是为什么这个打印
L XL XXL XXXL
如果你想知道更多的细节,我build议你阅读这个课程的源代码。
一个简单的Enum
值是一次只能select一个值的列表。 使用你的例子,一个尺寸可以只是S,M,L等等之一。 你可以使用简单的常量而不是Enum
但是这样做有可读性,易维护和严格types检查的优点。
当需要一个variables同时假定多个Enum
值时,将使用EnumSet
。 例如,您写入的字体可以同时为粗体和斜体 。 EnumSet
将允许您添加各种值,并testing是否在给定时间内实际设置了其中一个值。 如果你从其他编程语言来到Java,这是通常称为标志的function。
比较两者:
enum Size { S, M, L, XL, XXL, XXXL } Size currentSize; ... currentSize = Size.S; ... if (currentSize == Size.S) ...
定义,赋值,然后检查一个Enum
值。
enum FontStyle { Bold, Italic, Underline, Strikethrough } EnumSet<FontStyle> currentStyle; ... currentStyle = EnumSet.of(FontStyle.Bold, FontStyle.Italic); ... if (currentStyle.contains(FontStyle.Italic)) ...
定义,同时分配两个Enum
值,然后检查其中的一个是否实际设置。
EnumSet专门用于存储枚举types元素并快速迭代它。 例如。
for (Day d : EnumSet.range(Day.MONDAY, Day.FRIDAY)) System.out.println(d);
以上片段将显示星期一至星期五的星期几。
来自Joshua Bloch的书本身和他自己的话:
java.util包提供了EnumSet类来高效地表示从单个枚举types中绘制的值集合。 这个类实现了Set接口,提供了所有其他Set实现的丰富性,types安全性和互操作性。 但是在内部,每个EnumSet被表示为一个位向量。 如果底层的枚举types有64个或更less的元素,而且大多数都是这样,那么整个EnumSet就是用一个单独的long来表示的,所以它的性能可以和位域的性能相媲美。 批量操作(如removeAll和retainAll)是使用按位算术来实现的,就像您手动执行位域一样。 但是,你已经与手动位混淆的丑陋和错误倾向性绝缘了。 EnumSet为你做了很多努力。
所以我们可以做这样的事情。
public class SizeSet { public enum Size {S, M, L, XL, XXL, XXXL} public void applySize(Set<Size> sizes){} }
客户端代码调用它可能会做类似的事情
SizeSet largeSizeSet = new SizeSet(); largeSizeSet.applySize(EnumSet.of(Size.L, Size.XXL, Size.XXL));
请注意,applySize方法采用Set<Size>
而不是EnumSet<Size>
。 虽然很明显,客户端可能会将EnumSet传递给方法,但接受接口而不是具体实现是一个好习惯。
给出以下示例:
.... public static final String S = "s"; public static final String M = "m"; public static final String L = "l"; .... Set<String> sizeSet = new HashSet<String>(); sizeSet.add(S); sizeSet.add(M);
那么,在上面的例子中sizeSet是什么?
EnumSet与上面的例子没有什么不同,只是EnumSet是一个特殊的Set实现,与枚举types一起使用并进行了优化,就这些了。
EnumSet largeSize
EnumSet largeSize是一组包含XL,XXL和XXXL的Enum值。
Size
大小是具有常数值S,M,L,XL,XXL,XXXL的一类Enumtypes。
largeSize.iterator()
EnumSet的迭代器按自然顺序排列,最初声明枚举值的顺序。
- EnumSet类是Java集合框架的成员,并未同步。
- 它是一个高性能的集合实现,它们比HashSet快得多。
- 每个EnumSet实例的所有元素必须是单个枚举types的元素。
了解更多阅读api文档: http : //docs.oracle.com/javase/8/docs/api/java/util/EnumSet.html
根据Oracle文档
枚举集在内部表示为位向量。 这种表示非常紧凑和高效。
可读,types安全,内存占用less…你还需要什么?
它迅速将任何枚举元素变成一个集合,枚举集合又是另一种types的集合。
public enum Style { BOLD, ITALIC, UNDERLINE, STRIKETHROUGH } EnumSet.of(Style.BOLD, Style.ITALIC);