Java_集合_EnumSet(3)

1,储存方式

public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
    implements Cloneable, java.io.Serializable{
	
    final Class<E> elementType;
    final Enum[] universe;
    private static Enum[] ZERO_LENGTH_ENUM_ARRAY = new Enum[0];
	
    EnumSet(Class<E>elementType, Enum[] universe) {
        this.elementType = elementType;
        this.universe    = universe;
    }
	
    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);
    }
	
    private static <E extends Enum<E>> E[] getUniverse(Class<E> elementType) {
        return java.lang.JavaLangAccess.getEnumConstantsShared(elementType);
    }
}

// RegularEnumSet

class RegularEnumSet<E extends Enum<E>> extends EnumSet<E> {
    private long elements = 0L;
	
    RegularEnumSet(Class<E>elementType, Enum[] universe) {
        super(elementType, universe);
    }
}

// JumboEnumSet

class JumboEnumSet<E extends Enum<E>> extends EnumSet<E> {
    private long elements[];
    private int size = 0;
	
    JumboEnumSet(Class<E>elementType, Enum[] universe) {
        super(elementType, universe);
        elements = new long[(universe.length + 63) >>> 6];
    }
}

1)从noneOf()出发可以看到,储存数据的结构为:final Enum[] universe,而且,全局中仅有构造函数对该数据赋值了,因此:储存数据在构造函数就初始化完成

2)它依据初始化的Enum的大小,分别实现了两个实现类,本文仅分析RegularEnumSet,读者可以自己分析另一个


2,自增方式

    public boolean add(E e) {
        typeCheck(e);

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

1)位运算,(1L << ((Enum)e).ordinal())” 作用:获取一个 000..010..00的二进制,1的位置就是位移的数量

elements |=” 作用:对所有位数进行或运算,因此,整个位运算就是将 指定位数的数据变成 1

2)通过1)的分析,可以看出它增加了一个数,就是将指定位数添加1。也就是说,它是使用0和1来表示,某个元素是否存在。

以上便是,EnumSet使用“位向量”来标识数据的实现方式。而Long的位数为64,因此它最多表示64个。


3,查询数据

仅提供遍历获取的方式


4,获取整体大小

    public int size() {
        return Long.bitCount(elements);
    }

EnumSet使用“位向量”储存数据,因此只需要统计它"1"的个数,也就是它的size


EnumSet在构造函数就获取了所有数据,并储存在一个定长数组中,这很适合储存Enum的数据。

同样使用定长数组储存数据的还有:EnumMap






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值