# Java `EnumSet`

> 原文： [https://www.programiz.com/java-programming/enumset](https://www.programiz.com/java-programming/enumset)

#### 在本教程中，我们将借助示例学习 Java `EnumSet`类及其各种方法。

Java 集合框架的`EnumSet`类提供了单个枚举的元素的一组实现。

在学习`EnumSet`之前，请确保了解 [Java 枚举](/java-programming/enums "Java enum")。

它实现了[`Set`接口](/java-programming/set "Java Set Interface")。

![Java EnumSet class implements the Java Set interface.](img/83d143005739356ad4c5426b8859bacf.png)

* * *

## 创建`EnumSet`

为了创建一个枚举集，我们必须首先导入`java.util.EnumSet`包。

与其他集合实现不同，枚举集合没有公共构造器。 我们必须使用预定义的方法来创建一个枚举集。

### 1.使用`allOf(Size)`

`allof()`方法创建一个枚举集，其中包含指定枚举类型`size`的所有值。 例如，

```java
import java.util.EnumSet;

class Main {
    // an enum named Size
    enum Size {
        SMALL, MEDIUM, LARGE, EXTRALARGE
    }

    public static void main(String[] args) {

        // Creating an EnumSet using allOf()
        EnumSet<Size> sizes = EnumSet.allOf(Size.class);

        System.out.println("EnumSet: " + sizes);
    }

} 
```

**输出**

```java
EnumSet: [SMALL, MEDIUM, LARGE, EXTRALARGE] 
```

注意声明，

```java
EnumSet<Size> sizes = EnumSet.allOf(Size.class); 
```

在这里，`Size.class`表示我们创建的`Size`枚举。

* * *

### 2.使用`noneOf(Size)`

`noneOf()`方法创建一个空的枚举集。 例如，

```java
import java.util.EnumSet;

class Main {

     // an enum type Size
    enum Size {
        SMALL, MEDIUM, LARGE, EXTRALARGE
    }

    public static void main(String[] args) {

        // Creating an EnumSet using noneOf()
        EnumSet<Size> sizes = EnumSet.noneOf(Size.class);

        System.out.println("Empty EnumSet: " + sizes);
    }
} 
```

**输出**：

```java
Empty EnumSet : [] 
```

在这里，我们创建了一个空的枚举，名称为`sizes`。

**注意**：在上述程序中，我们只能插入枚举类型为`sizes`的元素。 这是因为我们使用`size`枚举创建了空的枚举集。

* * *

### 3.使用`range(e1, e2)`方法

`range()`方法创建一个枚举集，其中包含`e1`和`e2`之间的枚举的所有值，包括两个值。 例如，

```java
import java.util.EnumSet;

class Main {

    enum Size {
        SMALL, MEDIUM, LARGE, EXTRALARGE
    }

    public static void main(String[] args) {

        // Creating an EnumSet using range()
        EnumSet<Size> sizes = EnumSet.range(Size.MEDIUM, Size.EXTRALARGE);

        System.out.println("EnumSet: " + sizes);
    }
} 
```

**输出**：

```java
EnumSet: [MEDIUM, LARGE, EXTRALARGE] 
```

* * *

### 4.使用`of()`方法

`of()`方法创建一个包含指定元素的枚举集。 例如，

```java
import java.util.EnumSet;

class Main {

    enum Size {
        SMALL, MEDIUM, LARGE, EXTRALARGE
    }

    public static void main(String[] args) {

        // Using of() with a single parameter
        EnumSet<Size> sizes1 = EnumSet.of(Size.MEDIUM);
        System.out.println("EnumSet1: " + sizes1);

        EnumSet<Size> sizes2 = EnumSet.of(Size.SMALL, Size.LARGE);
        System.out.println("EnumSet2: " + sizes2);
    }
} 
```

**输出**：

```java
EnumSet1: [MEDIUM]
EnumSet2: [SMALL, LARGE] 
```

* * *

## `EnumSet`的方法

`EnumSet`类提供了使我们能够对枚举集执行各种元素的方法。

* * *

## 将元素插入`EnumSet`

*   `add()` - 将指定的枚举值插入到枚举集中
*   `addAll()`将指定集合的​​所有元素插入集合

例如，

```java
import java.util.EnumSet;

class Main {

    enum Size {
        SMALL, MEDIUM, LARGE, EXTRALARGE
    }

    public static void main(String[] args) {

        // Creating an EnumSet using allOf()
        EnumSet<Size> sizes1 = EnumSet.allOf(Size.class);

        // Creating an EnumSet using noneOf()
        EnumSet<Size> sizes2 = EnumSet.noneOf(Size.class);

        // Using add method
        sizes2.add(Size.MEDIUM);
        System.out.println("EnumSet Using add(): " + sizes2);

        // Using addAll() method
        sizes2.addAll(sizes1);
        System.out.println("EnumSet Using addAll(): " + sizes2);
    }
} 
```

**输出**：

```java
EnumSet using add(): [MEDIUM]
EnumSet using addAll(): [SMALL, MEDIUM, LARGE, EXTRALARGE] 
```

在上面的示例中，我们使用`addAll()`方法将枚举集`size1`的所有元素插入到枚举集`size2`中。

还可以使用`addAll()`将其他集合中的元素（例如`ArrayList`，`LinkedList`等）插入到枚举集中。 但是，所有集合都应具有相同的枚举类型。

* * *

## 访问`EnumSet`元素

要访问枚举集的元素，我们可以使用`iterator()`方法。 为了使用此方法，我们必须导入`java.util.Iterator`包。 例如，

```java
import java.util.EnumSet;
import java.util.Iterator;

class Main {

    enum Size {
        SMALL, MEDIUM, LARGE, EXTRALARGE
    }

    public static void main(String[] args) {

        // Creating an EnumSet using allOf()
        EnumSet<Size> sizes = EnumSet.allOf(Size.class);

        Iterator<Size> iterate = sizes.iterator();

        System.out.print("EnumSet: ");
        while(iterate.hasNext()) {
            System.out.print(iterate.next());
            System.out.print(", ");
        }
    }
} 
```

**输出**：

```java
EnumSet: SMALL, MEDIUM, LARGE, EXTRALARGE, 
```

**注意**：

*   如果枚举集中存在下一个元素，则`hasNext()`返回`true`
*   `next()`返回枚举集中的下一个元素

* * *

## 删除`EnumSet`元素

*   `remove()` - 从枚举集中删除指定的元素
*   `removeAll()` - 从枚举集中删除所有元素

例如：

```java
import java.util.EnumSet;

class Main {

    enum Size {
        SMALL, MEDIUM, LARGE, EXTRALARGE
    }

    public static void main(String[] args) {

        // Creating EnumSet using allOf()
        EnumSet<Size> sizes = EnumSet.allOf(Size.class);
        System.out.println("EnumSet: " + sizes);

        // Using remove()
        boolean value1 = sizes.remove(Size.MEDIUM);
        System.out.println("Is MEDIUM removed? " + value1);

        // Using removeAll()
        boolean value2 = sizes.removeAll(sizes);
        System.out.println("Are all elements removed? " + value2);
    }
} 
```

**输出**：

```java
EnumSet: [SMALL, MEDIUM, LARGE, EXTRALARGE]
Is MEDIUM removed? true
Are all elements removed? true 
```

* * *

## 其他方法

| 方法 | 描述 |
| --- | --- |
| `copyOf()` | 创建`EnumSet`的副本 |
| `contains()` | 在`EnumSet`中搜索指定的元素，并返回布尔结果 |
| `isEmpty()` | 检查`EnumSet`是否为空 |
| `size()` | 返回`EnumSet`的大小 |
| `clear()` | 从`EnumSet`中删除所有元素 |

* * *

## `Cloneable`和`Serializable`接口

`EnumSet`类还实现`Cloneable`和`Serializable`接口。

**`Cloneable`的接口**

它允许`EnumSet`类制作该类实例的副本。

**`Serializable`接口**

每当需要通过网络传输 Java 对象时，就需要将对象转换为位或字节。 这是因为 Java 对象无法通过网络传输。

`Serializable`接口允许对类进行序列化。 这意味着可以将实现`Serializable`的类的对象转换为位或字节。

* * *

## 为什么选择`EnumSet`？

与其他集合实现（例如`HashSet`，`TreeSet`）相比，`EnumSet`提供了一种存储枚举值的有效方法。

枚举集仅存储特定枚举的枚举值。 因此，JVM 已经知道该集合的所有可能值。

这就是为什么枚举集在内部被实现为一系列位的原因。 位指定元素是否存在于枚举集中。

如果集合中存在该元素，则将其对应的位打开。