EnumSet真正意味着什么?

时间:2012-08-06 08:44:11

标签: java object enums 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创建了Enum类型的大小。

我的问题是:largeSize是EnumSet类型的对象吗?它到底意味着什么?我真的想更好地理解它。

9 个答案:

答案 0 :(得分:41)

对于任何变量,其类型可在其声明中找到:

EnumSet largeSize

是的,largeSize(由于它是一个集合,应该命名为largeSizes)属于EnumSet类型。它也应该是一般化的,因此被声明为

EnumSet<Size> largeSizes

这意味着largeSizes属于EnumSet类型。 EnumSetSet,其中包含特定枚举类型的枚举实例,其效果比其他Set实施(如HashSetTreeSet更有效,等等。)。要了解EnumSet是什么,请阅读API

答案 1 :(得分:38)

简化您的代码

EnumSet<Size> largeSize = EnumSet.of(Size.XXXL, Size.XXL, Size.XL, Size.L);
for(Size size: largeSize)
    System.out.print(size+" ");

您可以看到largeSize是一个常规Set,除了它用于存储枚举。那有什么不同?首先,JVM知道集合的所有可能值,这意味着不是存储所有对象,而是可以使用位图,其中1表示项目存在,0表示不存在。这也意味着集合的顺序是序数值的顺序,即它们被定义的顺序。这就是打印

的原因
L XL XXL XXXL

如果您想了解更多细节,我建议您阅读本课程的来源。

答案 2 :(得分:36)

简单的Enum是一个值列表,您一次只能选择一个。使用您的示例,对于任何给定的布料,尺寸只能是S,M,L等中的一个。您可以使用简单常量而不是Enum,但这具有可读性,易于维护和严格类型检查的优点。

当您需要变量同时承担多个EnumSet值时,将使用Enum。例如,您写入屏幕的字体可以同时为粗体斜体EnumSet将允许您添加各种值并测试其中一个值是否在任何给定时间实际设置。如果你从其他编程语言来到Java,这就是通常称为 flags 的功能。

比较两者:

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值,然后检查其中一个是否实际设置。

答案 3 :(得分:7)

EnumSet专门用于存储枚举类型元素并快速迭代它。 例如。

for (Day d : EnumSet.range(Day.MONDAY, Day.FRIDAY))
        System.out.println(d);

上面的代码段会显示星期一到星期五的星期几。

答案 4 :(得分:4)

根据Oracle doc

  

枚举集在内部表示为位向量。这种表现非常紧凑和高效。

可读,类型安全,内存占用少......你还想要什么?

答案 5 :(得分:3)

给出以下示例:

....
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实现,它与enum类型一起使用并进行了优化,这就是全部。

答案 6 :(得分:3)

EnumSet largeSize

EnumSet largeSize是一组Enum值,包含XL,XXL和XXXL。

Size 

大小是一类具有常数值S,M,L,XL,XXL,XXXL的枚举类型。

largeSize.iterator()

EnumSet的迭代器按自然顺序排列,即枚举值最初声明的顺序。

  • EnumSet类是Java Collections Framework&amp;没有同步。
  • 它是一个高性能的设置实现,它们比它快得多 HashSet的。
  • 每个EnumSet实例的所有元素都必须是a的元素 单枚举类型。

要了解更多信息,请阅读api doc:http://docs.oracle.com/javase/8/docs/api/java/util/EnumSet.html

答案 7 :(得分:0)

EnumSet是专门用于处理枚举类的 Set集合。它实现了Set接口,并从AbstractSet扩展了:

enter image description here

当您计划使用EnumSet时,必须考虑以下几点:

  1. 它只能包含枚举值,并且所有值都必须属于 相同的枚举
  2. 不允许添加空值,并尝试抛出NullPointerException
  3. 它不是线程安全的,因此 我们需要在外部对其进行同步
  4. 元素是 按照它们在枚举中声明的顺序
  5. 进行存储
  6. 它使用可在副本上使用的故障安全迭代器,因此不会抛出 ConcurrentModificationException如果在以下情况下修改了集合 遍历

现在,EnumSet largeSize部分是变量声明,所以是的,它的类型为EnumSet。请注意,您可以在集合中添加元素的类型以获得更好的类型安全性:EnumSet<Size>

learn more about EnumSet上查看这篇文章。

答案 8 :(得分:-2)

它快速将任何枚举元素转换为集合,EnumSet是另一种类型的集合。

public enum Style { BOLD, ITALIC, UNDERLINE, STRIKETHROUGH }

EnumSet.of(Style.BOLD, Style.ITALIC);