Java中的EnumSet

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 是存储的元素类型。

Java中的EnumSet

语法: 声明

public abstract class EnumSet<E extends Enum<E>>

在这里, E 指定元素。E必须扩展Enum,这强制要求元素必须是指定的枚举类型。

使用EnumSet的好处

  • 由于它使用 RegularEnumSetJumboEnumSet, 所以EnumSet中的所有方法都使用位运算操作实现。
  • 使用EnumSet比HashSet更快,因为我们不需要计算任何hashCode来找到正确的桶。
  • 所需的计算在恒定时间内执行,所需的空间非常小。

EnumSet的方法

方法 执行的操作
allOf​(Class elementType) 创建包含指定元素类型中的所有元素的枚举集。
clone() 返回该集合的副本。
complementOf​(EnumSet s) 创建具有与指定枚举集相同的元素类型的枚举集,最初包含该类型中未包含在指定集合中的所有元素。
copyOf​(Collection c) 从指定集合初始化枚举集。
copyOf​(EnumSet s) 创建具有与指定枚举集相同的元素类型的枚举集,最初包含相同的元素(如果有)。
noneOf​(Class elementType) 创建具有指定元素类型的空枚举集。
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接口中声明的方法

方法 | 描述
—|—
parallelStream() | 返回具有此集合作为数据源的可能并行流。
removeIf​(Predicate filter) | 删除满足给定断言的此集合的所有元素。
stream() | 返回具有此集合作为数据源的顺序流。
toArray​(IntFunction generator) | 使用提供的生成函数分配返回的数组,返回包含此集合中所有元素的数组。

### 在 java.lang.Iterable 接口中声明的方法

方法 | 描述
—|—
forEach​(Consumer action) | 对可迭代对象的每个元素执行给定操作,直到所有元素都被处理或操作引发异常。

### 在 java.util.Set 接口中声明的方法

方法 | 描述
—|—
add​(E e) | 如果集合中没有指定的元素,则将其添加到该集合中(可选操作)。
addAll​(Collection c) | 将指定的元素添加到该集合中,如果它们尚未存在(可选操作)。
clear() | 从该集合中删除所有元素(可选操作)。
contains​(Object o) | 如果集合包含指定的元素,则返回 true。
containsAll​(Collection c)

如果集合包含指定的所有元素,则返回 true。
isEmpty() 如果此集合不包含任何元素,则返回 true。
iterator() 返回集合中元素的迭代器。
remove​(Object o) 如果存在,则从集合中删除指定元素(可选操作)。
retainAll​(Collection c) | 仅保留集合中包含在指定集合中的元素(可选操作)。
size() | 返回该集合中元素的数量(其基数)。
spliterator() | 在集合中的元素上创建一个 Spliterator。
toArray() | 返回包含该集合中所有元素的数组。
toArray​(T[] a) | 返回包含该集合中所有元素的数组;返回数组的运行时类型是指定数组的类型。

### 在 java.util.AbstractCollection 类中声明的方法

方法 | 描述
—|—
add​(E e) | 确保此集合包含指定的元素(可选操作)。
addAll​(Collection c) | 将指定集合中的所有元素添加到此集合中(可选操作)。
clear() | 从此集合中删除所有元素(可选操作)。
contains​(Object o) | 如果此集合包含指定的元素,则返回 true。
containsAll​(Collection c)

如果此集合包含指定集合中的所有元素,则返回 true。
isEmpty() 如果此集合不包含任何元素,则返回 true。
iterator() 返回一个迭代器,用于遍历此集合中包含的元素。
remove​(Object o) 如果存在,则从此集合中删除指定元素的单个实例(可选操作)。
retainAll​(Collection<?> c) 仅保留此集合中包含在指定集合中的元素(可选操作)。
toArray() 返回一个包含此集合中所有元素的数组。
toArray​(T[] a) 返回一个包含此集合中所有元素的数组;返回数组的运行时类型是指定数组的类型。
toString() 返回此集合的字符串表示形式。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程