资讯专栏INFORMATION COLUMN

java EnumSet源码学习

Achilles / 2940人阅读

摘要:它不对外提供构造函数,只能通过一系列静态方法,如来获取对象实例。当要添加元素或者删除元素时,也只需要改变的值即可。后面可能会再研究如有不正确或者想交流的地方,欢迎指出

一、EnumSet 简单介绍
1、A specialized Set implementation for use with enum types. 
2、All of the elements in an enum set must come from a single enum type 
     that is specified, explicitly or implicitly, when the set is created.
EnumSet是Set的一种实现,它必须要配合枚举使用,并且EnumSet内部的元素只能是一种类型
二、EnumSet的内部设计思路

EnumSet是一个抽象类,内部多处采用静态工厂方法。它不对外提供构造函数,只能通过一系列静态方法,如of(...)、noneOf(...)、copyOf(...)、complementOf(...)来获取对象实例。这样做的好处是它对外封装了内部实现,如EnumSet返回的真正的类型是它的子类:RegularEnumSet或者JumboEnumSet,但外部使用者并不知道这些,当EnumSet API升级时,如添加一个子类实现,原先引用的地方不用发生改变。

//核心方法,其他获取EnumSet实例的方法都调用了这个方法
public static > EnumSet noneOf(Class elementType) {
        Enum[] universe = getUniverse(elementType);
        if (universe == null)
            throw new ClassCastException(elementType + " not an enum");

        if (universe.length <= 64)
            return new RegularEnumSet<>(elementType, universe);
        else
            return new JumboEnumSet<>(elementType, universe);
}
三、EnumSet之RegularEnumSet的高效之处

首先,在EnumSet内部,有一个成员变量final Enum[] universe;,它持有该EnumSet中的元素所对应的枚举类型的所有值(实例),当调用noneOf()方法时,都会调用getUniverse()获取到枚举类型的所有实例,并赋值给universe变量。然后在RegularEnumSet子类中,有一个成员变量private long elements,可以根据elements的值进行位运算得到的结果,到universe数组取得相应的元素。当要添加元素或者删除元素时,也只需要改变elements的值即可。

   /**
     * Returns all of the values comprising E.
     * The result is uncloned, cached, and shared by all callers.
     */
    private static > E[] getUniverse(Class elementType) {
        return SharedSecrets.getJavaLangAccess()
                                        .getEnumConstantsShared(elementType);
    }
   /**
     * Returns true if this set contains the specified element.
     */
    public boolean contains(Object e) {
        if (e == null)
            return false;
        Class eClass = e.getClass();
        if (eClass != elementType && eClass.getSuperclass() != elementType)
            return false;

        return (elements & (1L << ((Enum)e).ordinal())) != 0;
    }

   /**
     * Adds the specified element to this set if it is not already present.
     */
    public boolean add(E e) {
        typeCheck(e);

        long oldElements = elements;
        elements |= (1L << ((Enum)e).ordinal());
        return elements != oldElements;
    }

1、JumboEnumSet后面可能会再研究
2、如有不正确或者想交流的地方,欢迎指出

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/68575.html

相关文章

  • Java知识点总结(Java容器-EnumSet

    摘要:知识点总结容器知识点总结容器是一个专为枚举设计的集合类,中所有值都必须是指定枚举类型的枚举值,该枚举类型在创建时显式或隐性的指定。集合不容许加入元素。 Java知识点总结(Java容器-EnumSet) @(Java知识点总结)[Java, Java容器, JavaCollection, JavaSet] EnumSet EnumSet是一个专为枚举设计的集合类 ,EnumSet中...

    kycool 评论0 收藏0
  • Java 集合 Set

    摘要:当复制集合中的所有元素来创建新的集合时,要求集合中的所有元素必须是同一个枚举类的枚举值各实现类的性能分析的性能总比好,特别是最常用的添加查询元素等操作。因为需要额外的红黑树算法来维护集合元素的次序。在创建时进行,以防对集合的意外非同步访问 HashSet 大多时候使用Set集合时就是使用HashSet实现类。HashSet按Hash算法来存储集合中的元素,因此具有很好的存取和查找性能 ...

    verano 评论0 收藏0
  • java集合-Set

    摘要:集合判断两个元素的标准是两个对象通过方法比较相等,并且两个对象的方法返回值也相等。的集合元素也是有序的,以枚举值在类内的定义顺序来决定集合元素的顺序。是所有实现类中性能最好的,但它只能保存同一个枚举类的枚举值作为集合元素。 Set集合通常不能记住元素的添加顺序。Set不允许包含重复的元素。 Set集合不允许包含相同的元素,如果试图把两个相同的元素加入同一个Set集合中,则添加操作...

    xavier 评论0 收藏0
  • Java 基础 | Collection 集合概览

    摘要:说到复盘基础,并不是所有的都会复盘,没那个时间更没那个必要。比如,一些基础的语法以及条件语句,极度简单。思前想后,我觉得整个计划应该从集合开始,而复盘的方式就是读源码。通常,队列不允许随机访问队列中的元素。 ​showImg(https://segmentfault.com/img/remote/1460000020029737?w=1080&h=711); 老读者都知道,我是自学转行...

    codergarden 评论0 收藏0
  • java学习(七) —— API集合类

    摘要:集合类主要负责保存盛装其他数据,因此集合类也被称为容器类。所有的集合类都位于包下。表示一组对象,这些对象也称为的元素。成员方法把集合转成数组迭代器,集合的专用遍历方式之接口概述有序的,也称为序列。 前言 在编程中,常常需要集中存放多个数据。从传统意义上讲,数组是我们的一个很好的选择,前提是我们实现已经明确知道我们将要保存的对象的数量。 一旦在数组初始化时指定了数组长度,这个数组长度就...

    senntyou 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<