java集合(四)---EnumSet源码解析

一、关于EnumSet的图如下图所示:

在这里插入图片描述
(1)EnumSet是一个专门为枚举类设计的集合类,EnumSet中的所有元素都必须是指定枚举类型的枚举值,该枚举类型在创建EnumSet时显式或隐式地指定。
(2)EnumSet的集合元素也是有序的,EnumSet以枚举值在Enum类内的定义顺序来决定集合元素的顺序。
(3)EnumSet在内部以位向量的形式存储,这种存储形式非常紧凑,高效。因此EnumSet对象占用内存很小,而且运行效率很好,尤其是进行批量操作(如调用containsAll()和retainAll()方法时),如果其参数也是EnumSet集合,则该批量操作的执行速度也非常快。
(4)EnumSet集合不允许加入null元素,如果试图插入null元素,EnumSet将抛出NullPointerException异常。如果想判断EnumSet是否包括含null元素或者null元素都不会抛出异常,只是删除操作会返回false,因为没有任何null元素被删除。
(5)注意一个点:就是当复制Collection集合中的所有元素来创建新的EnumSet集合时,要去Collection集合中的所有元素必须是同一个枚举类的枚举值。

**

二,有关源码:

**
1. EnumSet(ClasselementType, Enum<?>[] universe)方法

    EnumSet(Class<E>elementType, Enum<?>[] universe) {
        this.elementType = elementType;
        this.universe    = universe;
    }

源码解析:

  • 功能:构造函数

2. public static <E extends Enum> EnumSet noneOf(Class elementType)方法

    public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> 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集合,其中集合中元素的类型被定义好了,类型为:elementType

3. public static <E extends Enum> EnumSet allOf(Class elementType)方法

    public static <E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType) {
        EnumSet<E> result = noneOf(elementType);
        result.addAll();
        return result;
    }

源码解析:

  • 功能:创建一个包含指定枚举类里所有枚举值的EnumSet集合

4. public static <E extends Enum> EnumSet copyOf(EnumSet s)方法

    public static <E extends Enum<E>> EnumSet<E> copyOf(EnumSet<E> s) {
        return s.clone();
    }

源码解析:

  • 功能:创建一个指定EnumSet具有相同元素类型、相同集合元素的EnumSet集合

5. public static <E extends Enum> EnumSet copyOf(Collection c)方法

    public static <E extends Enum<E>> EnumSet<E> copyOf(Collection<E> c) {
        if (c instanceof EnumSet) {
            return ((EnumSet<E>)c).clone();
        } else {
            if (c.isEmpty())
                throw new IllegalArgumentException("Collection is empty");
            Iterator<E> i = c.iterator();
            E first = i.next();
            EnumSet<E> result = EnumSet.of(first);
            while (i.hasNext())
                result.add(i.next());
            return result;
        }
    }

源码解析:

  • 功能:使用Collection类型的元素创建Enum集合
  • 源码思路:
    • (1)首先判断集合c是否是EnumSet类型,如果是,直接调用clone方法,将集合c中的元素克隆出来即可
    • (2)如果不是EnumSet类型,那首先判断集合c是否为空,如果为空,则抛出异常;如果不为空则使用iterator迭代器,将集合c中的元素依次迭代出来,每遍历一个元素就通过add方法添加到result中

6. public static <E extends Enum> EnumSet complementOf(EnumSet s)方法

    public static <E extends Enum<E>> EnumSet<E> complementOf(EnumSet<E> s) {
        EnumSet<E> result = copyOf(s);
        result.complement();
        return result;
    }

源码解析:

  • 功能:创建一个新的EnumSet集合,该集合中包含的枚举值是s所在的类的枚举值,并且不包括s现有的枚举值
  • 源码思路:
    • (1)首先通过调用copyOf方法,将结果赋值给result
    • (2)其次调用complement方法来实现该操作,其中complement方法在EnumSet中是抽象方法

7. public static <E extends Enum> EnumSet of(E e)方法

    public static <E extends Enum<E>> EnumSet<E> of(E e) {
        EnumSet<E> result = noneOf(e.getDeclaringClass());
        result.add(e);
        return result;
    }

源码解析:

  • 功能:创建一个EnumSet类型的对象,该对象中的枚举类型应该与e所在的类的枚举类型一致,并且该对象初始元素有e

8. public static <E extends Enum> EnumSet of(E e1, E e2)方法

    public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2) {
        EnumSet<E> result = noneOf(e1.getDeclaringClass());
        result.add(e1);
        result.add(e2);
        return result;
    }

源码解析:

  • 功能:创建一个EnumSet类型的对象,该对象中的枚举类型应该与e所在的类的枚举类型一致,并且该对象初始元素有e1和e2

9. public static <E extends Enum> EnumSet of(E e1, E e2, E e3)方法

    public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3) {
        EnumSet<E> result = noneOf(e1.getDeclaringClass());
        result.add(e1);
        result.add(e2);
        result.add(e3);
        return result;
    }

源码解析:

  • 功能:创建一个EnumSet类型的对象,该对象中的枚举类型应该与e所在的类的枚举类型一致,并且该对象初始元素有e1、e2和e3

10. public static <E extends Enum> EnumSet of(E e1, E e2, E e3, E e4)方法

    public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4) {
        EnumSet<E> result = noneOf(e1.getDeclaringClass());
        result.add(e1);
        result.add(e2);
        result.add(e3);
        result.add(e4);
        return result;
    }

源码解析:

  • 功能:创建一个EnumSet类型的对象,该对象中的枚举类型应该与e所在的类的枚举类型一致,并且该对象初始元素有e1、e2、e3和e4

11. public static <E extends Enum> EnumSet of(E e1, E e2, E e3, E e4, E e5)方法

    public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4,
                                                    E e5)
    {
        EnumSet<E> result = noneOf(e1.getDeclaringClass());
        result.add(e1);
        result.add(e2);
        result.add(e3);
        result.add(e4);
        result.add(e5);
        return result;
    }

源码解析:

  • 功能:创建一个EnumSet类型的对象,该对象中的枚举类型应该与e所在的类的枚举类型一致,并且该对象初始元素有e1、e2、e3、e4和e5

12. public static <E extends Enum> EnumSet of(E first, E… rest)方法

    @SafeVarargs
    public static <E extends Enum<E>> EnumSet<E> of(E first, E... rest) {
        EnumSet<E> result = noneOf(first.getDeclaringClass());
        result.add(first);
        for (E e : rest)
            result.add(e);
        return result;
    }

源码解析:

  • 功能:创建一个包含一个或多个枚举值的EnumSet集合,传入的多个枚举值必须属于同一个枚举类

13. public static <E extends Enum> EnumSet range(E from, E to)方法

    public static <E extends Enum<E>> EnumSet<E> range(E from, E to) {
        if (from.compareTo(to) > 0)
            throw new IllegalArgumentException(from + " > " + to);
        EnumSet<E> result = noneOf(from.getDeclaringClass());
        result.addRange(from, to);
        return result;
    }

源码解析:

  • 功能:创建一个EnumSet集合,集合中包含E类从from到to的所有枚举值
  • 源码思路:
    • (1)首先判断from和to的值,需要to的值大于from才能正确执行下面语句,否则抛出异常
    • (2)其次定义一个EnumSet类型的变量result,设定该变量中的枚举类型是from所在的枚举类型
    • (3)调用addRange方法,将枚举E中的元素放入result中,其中addRange在该EnumSet类中是抽象方法

三、鉴于以上举一下示例代码:

public class set {
    public static void main(String[] args) {
        //2. public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType)方法
        EnumSet es1 = EnumSet.noneOf(Dat.class);
        System.out.println(es1); //输出[]

        //3. public static <E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType)方法
        EnumSet es2 = EnumSet.allOf(Dat.class);
        System.out.println(es2); //输出:[YEAR, MONTH, DAY]

        //4. public static <E extends Enum<E>> EnumSet<E> copyOf(EnumSet<E> s)方法
        EnumSet es3 = EnumSet.copyOf(es2);
        System.out.println(es3); //输出:[YEAR, MONTH, DAY]

        //5. public static <E extends Enum<E>> EnumSet<E> copyOf(Collection<E> c)方法
        Set s = new HashSet();
        s.add(Session.SPRIGNG);
        s.add(Session.AUTUMN);
        EnumSet es4 = EnumSet.copyOf(s);
        System.out.println(es4);//输出:[SPRIGNG, AUTUMN]

        //6. public static <E extends Enum<E>> EnumSet<E> complementOf(EnumSet<E> s)方法
        EnumSet es5 = EnumSet.complementOf(es1);
        System.out.println(es5); //输出:[YEAR, MONTH, DAY]


        //7. public static <E extends Enum<E>> EnumSet<E> of(E e)方法
        EnumSet s1 = EnumSet.of(Session.SPRIGNG);
        System.out.println(s1);  //输出:[SPRING]


        //8. public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2)方法
        EnumSet s2 = EnumSet.of(Session.SPRIGNG, Session.SUMMER);
        System.out.println(s2); //输出:[SPRING,SUMMER]

        //9.public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3)方法
        EnumSet s3 = EnumSet.of(Session.SPRIGNG, Session.SUMMER,Session.AUTUMN);
        System.out.println(s3); //输出:[SPRING,SUMMER,AUTUMN]

        //10.public static <E extends Enum<E>> EnumSet<E> range(E from, E to)方法
        EnumSet s4 = EnumSet.range(Session.SUMMER, Session.WINTER);
        System.out.println(s4); //输出:[SUMMER, AUTUMN, WINTER]



    }


    enum Session {
        SPRIGNG,
        SUMMER,
        AUTUMN,
        WINTER
    }

    enum Dat {
        YEAR,
        MONTH,
        DAY
    }
}

注意这里面public static

        Set s = new HashSet();
        s.add(1);
        EnumSet es4 = EnumSet.copyOf(s);
        System.out.println(es4);

该代码会产生如下异常:

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Enum
    at java.util.RegularEnumSet.add(RegularEnumSet.java:18)
    at java.util.EnumSet.copyOf(EnumSet.java:154)
    at problems2018_3_23.set.main(set.java:27)

感谢:
参考:https://blog.csdn.net/xiaojie_570/article/details/79676550

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值