【问题标题】:How does java.util.EnumSet<E> work?java.util.EnumSet<E> 是如何工作的?
【发布时间】:2015-08-20 08:24:55
【问题描述】:

EnumSet&lt;E&gt; 类定义为:

public abstract class EnumSet<E extends Enum<E>>
extends AbstractSet<E>
implements Cloneable, Serializable

在 JCF 中。 此外,类本身实现的大多数方法都是静态的。最后,该类似乎没有实现 add(),iterator(),remove(),size(),contains()isEmpty() 方法,只是从没有实现它们的 AbstractSet 继承它们。 我有两个问题:

  1. EnumSet 对象究竟是如何实例化和使用的?
  2. 为什么我可以对EnumSet 对象使用add() 方法?

【问题讨论】:

    标签: java inheritance collections enums


    【解决方案1】:

    您看到的大多数静态方法都是工厂方法(of()complementOf()allOf() 等)。

    这些方法返回一个 EnumSet 的实例。这些方法创建和返回的 EnumSet 的实际类型是 EnumSet 的子类(RegularEnumSetJumboEnumSet),它们不是公共 API 的一部分,但实现了所有必需的方法。您只需要知道它们实现了 EnumSet。

    【讨论】:

      【解决方案2】:

      EnumSet 本身就是一个抽象类,因此它不必实现它继承的任何抽象方法。它将责任传递给它的非抽象子类。

      您可以调用未实现的方法,因为您实际上是在 EnumSet 子类的实例上调用它们。 (由于 EnumSet 是抽象的,它本身不能直接实例化。)

      【讨论】:

      • 您应该包括 EnumSet 实现了 AbstractSet 实现的接口。这确保了 add(),iterator(),remove(),... 在 EnumSet 的合同中。
      【解决方案3】:
      import java.util.*;
      enum Foo {
        A, B
      }
      class a {
        public static void main(String[] args) {
          System.out.println(EnumSet.noneOf(Foo.class));
          System.out.println(EnumSet.of(Foo.A));
          System.out.println(EnumSet.of(Foo.A).getClass());
        }
      }
      

      打印出来:

      []
      [A]
      class java.util.RegularEnumSet 
      

      关于实现,this 链接提供了描述:

      EnumSet 是一个抽象类,它提供了两个具体的 实现,java.util.RegularEnumSetjava.util.JumboEnumSetRegularEnumSetJumboEnumSet 之间的主要区别在于前者 使用long 变量来存储元素,而稍后使用long[] 来存储元素 存储它的元素。由于RegularEnumSet 使用long 变量,这是一个 64位数据类型,它只能容纳那么多元素。这就是为什么 当使用EnumSet.noneOf() 方法创建一个空的EnumSet 时,它 选择RegularEnumSet if key Universe(Key中的枚举实例数 Enum) 小于或等于 64 和 JumboEnumSet 如果密钥全域是 超过 64 个。

      这意味着EnumSet 将为您选择正确的实现。

      【讨论】:

        【解决方案4】:
        1. EnumSet 对象是如何被实例化和使用的?

        EnumSet 是一个“抽象类”,当您有许多预先知道的“键”时,它比 HashSet 更受欢迎。例如,当您有配置密钥时。

        性能优于HashSet,因为“...因为枚举常量是唯一的并且具有预定义的长度,因为你不能定义一个新的运行时枚举常量;它允许 Java API 设计器高度优化 EnumSet ..."(阅读更多:http://javarevisited.blogspot.com/2014/03/how-to-use-enumset-in-java-with-example.html#ixzz3jNcyB8ve

        你可以用很多工厂方法来实例化,例如EnumSet.of(...)

        1. 为什么我可以对 EnumSet 对象使用 add() 方法?

        创建“EnumSet”对象后,您可以在运行时使用“add” 方法添加另一个元素。例如,如果您有一个配置键列表,您可以通过 EnumSet 表示“选定”键并在运行时添加它们。

        package sample.test;
        import java.util.EnumSet;
        
        public class Foo {
        
          public enum SimpleConfigEnum { KEY1, KEY2, KEY3};
        
        /**
         * Example of EnumSet with add
         */
        public static void main(String[] args) {
        
            //Create an enumSet with two elements: KEY1,KEY2
            EnumSet<SimpleConfigEnum> eSet = EnumSet.of(SimpleConfigEnum.KEY1, SimpleConfigEnum.KEY2);
            System.out.println(eSet);
        
            //... add another element --> KEY3
            eSet.add(SimpleConfigEnum.KEY3);
            System.out.println(eSet);
          }
        
         }
        

        输出是:

        [KEY1, KEY2]
        [KEY1, KEY2, KEY3]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-09-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-15
          • 2018-08-18
          相关资源
          最近更新 更多