Java中的EnumSet
枚举或通常称为enum在编程语言中表示命名常量的一组,例如扑克牌的4个花色可以命名为Club、Diamond、Heart和Spade,它们属于名为Suit的枚举类型。
EnumSet 是用于枚举类型的Set接口的专门实现之一。 EnumSet的几个重要特点如下:
- 它扩展了Java中的 AbstractSet类 并实现了Set接口。
- EnumSet类是Java集合框架的成员,不是同步的。
- 它是一个高性能的Set实现,比HashSet快得多。
- EnumSet中的所有元素都必须来自一个指定的枚举类型,该类型在创建集合时被明确或隐式地指定。
- 它不允许使用 null对象 ,如果这样做,会抛出NullPointerException。
- 它使用一种 安全失败的 迭代器,因此,在迭代集合时,即使集合被修改,它也不会抛出ConcurrentModificationException。
EnumSet的层次结构如下:
java.lang.Object
↳ java.util.AbstractCollection<E>
↳ java.util.AbstractSet<E>
↳ java.util.EnumSet<E>
在这里, E 是存储的元素类型。

语法: 声明
public abstract class EnumSet<E extends Enum<E>>
在这里, E 指定元素。E必须扩展Enum,这强制要求元素必须是指定的枚举类型。
使用EnumSet的好处
- 由于它使用 RegularEnumSet 和 JumboEnumSet, 所以EnumSet中的所有方法都使用位运算操作实现。
- 使用EnumSet比HashSet更快,因为我们不需要计算任何hashCode来找到正确的桶。
- 所需的计算在恒定时间内执行,所需的空间非常小。
EnumSet的方法
| 方法 | 执行的操作 |
|---|---|
| allOf(Class |
创建包含指定元素类型中的所有元素的枚举集。 |
| clone() | 返回该集合的副本。 |
| complementOf(EnumSet |
创建具有与指定枚举集相同的元素类型的枚举集,最初包含该类型中未包含在指定集合中的所有元素。 |
| copyOf(Collection |
从指定集合初始化枚举集。 |
| copyOf(EnumSet |
创建具有与指定枚举集相同的元素类型的枚举集,最初包含相同的元素(如果有)。 |
| noneOf(Class |
创建具有指定元素类型的空枚举集。 |
| of(E e) | 创建最初包含指定元素的枚举集。 |
| of(E e1, E e2) | 创建最初包含指定元素的枚举集。 |
| of(E first, E… rest) | 创建最初包含指定元素的枚举集。 |
| of(E e1, E e2, E e3) | 创建最初包含指定元素的枚举集。 |
| of(E e1, E e2, E e3, E e4) | 创建最初包含指定元素的枚举集。 |
| of(E e1, E e2, E e3, E e4, E e5) | 创建最初包含指定元素的枚举集。 |
| range(E from, E to) | 创建最初包含由两个指定端点定义的范围内的所有元素的枚举集。 |
实现:
//Java程序,说明EnumSet及其功能的使用
//导入所需类
import java.util.EnumSet;
//枚举
enum Gfg {CODE, LEARN, CONTRIBUTE, QUIZ, MCQ};
//主类
//EnumSetExample
public class GFG {
//主方法
public static void main(String[] args) {
//创建一个集
EnumSet<Gfg> set1, set2, set3, set4;
//添加元素
set1 = EnumSet.of(Gfg.QUIZ, Gfg.CONTRIBUTE, Gfg.LEARN, Gfg.CODE);
set2 = EnumSet.complementOf(set1);
set3 = EnumSet.allOf(Gfg.class);
set4 = EnumSet.range(Gfg.CODE, Gfg.CONTRIBUTE);
//在集中打印对应的元素
System.out.println("Set 1: "+set1);
System.out.println("Set 2: "+set2);
System.out.println("Set 3: "+set3);
System.out.println("Set 4: "+set4);
}
}
输出:
Set 1: [CODE, LEARN, CONTRIBUTE, QUIZ]
Set 2: [MCQ]
Set 3: [CODE, LEARN, CONTRIBUTE, QUIZ, MCQ]
Set 4: [CODE, LEARN, CONTRIBUTE]
操作1: 创建EnumSet对象
由于EnumSet是抽象类,我们不能直接创建它的实例。它有许多静态工厂方法允许我们创建一个实例。JDK提供了 两种不同的EnumSet实现
- RegularEnumSet
- JumboEnumSet
注意: 它们是包私有的,并由一个位向量支持。
RegularEnumSet 使用单个long对象来存储EnumSet的元素。每个long元素的每一位表示一个枚举值。由于long的大小为64位,因此可以存储最多64个不同的元素。
JumboEnumSet 使用long数组来存储EnumSet的元素。与RegularEnumSet的唯一区别在于,JumboEnumSet使用long数组存储位向量,因此可以允许超过64个值。
工厂方法根据元素数量创建实例,EnumSet不提供任何公共构造函数,实例使用以下静态工厂方法创建:
- allOf(size)
- noneOf(size)
- range(e1, e2)
- of()
说明:
if (universe.length <= 64)
return new RegularEnumSet<>(elementType, universe);
else
return new JumboEnumSet<>(elementType, universe);
示例:
// Java Program to illustrate Creation an EnumSet
// Importing required classes
import java.util.*;
// Main class
// CreateEnumSet
class GFG {
// Enum
enum Game { CRICKET, HOCKEY, TENNIS }
// Main driver method
public static void main(String[] args)
{
// Creating an EnumSet using allOf()
EnumSet<Game> games = EnumSet.allOf(Game.class);
// Printing EnumSet elements to the console
System.out.println("EnumSet: " + games);
}
}
输出
EnumSet: [CRICKET, HOCKEY, TENNIS]
Operation 2: 添加元素
我们可以使用add()和addAll()方法向EnumSet添加元素。
示例:
// Java program to illustrate Addition of Elements
// to an EnumSet
// Importing required classes
import java.util.EnumSet;
// Main class
class AddElementsToEnumSet {
// Enum
enum Game { CRICKET, HOCKEY, TENNIS }
// Main driver method
public static void main(String[] args)
{
// Creating an EnumSet
// using allOf()
EnumSet<Game> games1 = EnumSet.allOf(Game.class);
// Creating an EnumSet
// using noneOf()
EnumSet<Game> games2 = EnumSet.noneOf(Game.class);
// Using add() method
games2.add(Game.HOCKEY);
// Printing the elements to the console
System.out.println("EnumSet Using add(): "
+ games2);
// Using addAll() method
games2.addAll(games1);
// Printing the elements to the console
System.out.println("EnumSet Using addAll(): "
+ games2);
}
}
输出
EnumSet Using add(): [HOCKEY]
EnumSet Using addAll(): [CRICKET, HOCKEY, TENNIS]
Operation 3: 访问元素
我们可以使用iterator()方法访问EnumSet元素。
示例:
// Java程序访问EnumSet元素
// 导入所需类
import java.util.EnumSet;
import java.util.Iterator;
// 主类
// AccessingElementsOfEnumSet
class GFG {
// 枚举
enum Game { CRICKET, HOCKEY, TENNIS }
// 主方法
public static void main(String[] args)
{
// 使用allOf()创建EnumSet
EnumSet<Game> games = EnumSet.allOf(Game.class);
// 在games上创建迭代器
Iterator<Game> iterate = games.iterator();
// 显示消息
System.out.print("EnumSet: ");
while (iterate.hasNext()) {
// 使用next()方法迭代并将元素打印到控制台
System.out.print(iterate.next());
System.out.print(", ");
}
}
}
输出
EnumSet: CRICKET, HOCKEY, TENNIS,
操作 4: 移除元素
可以使用remove()和removeAll()方法删除元素。
示例:
// Java程序移除EnumSet中的元素
// 导入所需类
import java.util.EnumSet;
// 主类
// RemovingElementsOfEnumSet
class GFG {
// 枚举
enum Game { CRICKET, HOCKEY, TENNIS }
// 主方法
public static void main(String[] args)
{
// 使用allOf()创建EnumSet
EnumSet<Game> games = EnumSet.allOf(Game.class);
// 打印EnumSet
System.out.println("EnumSet: " + games);
// 使用remove()
boolean value1 = games.remove(Game.CRICKET);
// 打印元素到控制台
System.out.println("Is CRICKET removed? " + value1);
// 使用removeAll()并存储布尔结果
boolean value2 = games.removeAll(games);
// 打印元素到控制台
System.out.println("Are all elements removed? "
+ value2);
}
}
输出
EnumSet: [CRICKET, HOCKEY, TENNIS]
Is CRICKET removed? true
Are all elements removed? true
有一些其他的类或接口方法在下面被定义,它们以某种方式帮助我们更好地理解AbstractSet类,如下所示:
在java.util.AbstractSet类中声明的方法
| 方法 | 描述 |
|---|---|
| equals(Object o) | 将指定对象与此集合进行比较以检查相等性。 |
| hashCode() | 返回此集合的哈希码值。 |
| removeAll(Collection> c) | 从此集合中移除包含在指定集合中的所有元素(可选操作)。
### 在java.util.Collection接口中声明的方法 方法 | 描述 ### 在 java.lang.Iterable 接口中声明的方法 方法 | 描述 ### 在 java.util.Set 接口中声明的方法 方法 | 描述 |
如果集合包含指定的所有元素,则返回 true。 |
| isEmpty() | 如果此集合不包含任何元素,则返回 true。 |
| iterator() | 返回集合中元素的迭代器。 |
| remove(Object o) | 如果存在,则从集合中删除指定元素(可选操作)。 |
| retainAll(Collection> c) | 仅保留集合中包含在指定集合中的元素(可选操作)。 size() | 返回该集合中元素的数量(其基数)。 spliterator() | 在集合中的元素上创建一个 Spliterator。 toArray() | 返回包含该集合中所有元素的数组。 toArray(T[] a) | 返回包含该集合中所有元素的数组;返回数组的运行时类型是指定数组的类型。 ### 在 java.util.AbstractCollection 类中声明的方法 方法 | 描述 |
如果此集合包含指定集合中的所有元素,则返回 true。 |
| isEmpty() | 如果此集合不包含任何元素,则返回 true。 |
| iterator() | 返回一个迭代器,用于遍历此集合中包含的元素。 |
| remove(Object o) | 如果存在,则从此集合中删除指定元素的单个实例(可选操作)。 |
| retainAll(Collection<?> c) | 仅保留此集合中包含在指定集合中的元素(可选操作)。 |
| toArray() | 返回一个包含此集合中所有元素的数组。 |
| toArray(T[] a) | 返回一个包含此集合中所有元素的数组;返回数组的运行时类型是指定数组的类型。 |
| toString() | 返回此集合的字符串表示形式。 |
极客教程