欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java枚舉之EnumSet詳解

 更新時間:2023年12月20日 10:07:05   作者:Brain_L  
這篇文章主要介紹了Java枚舉之EnumSet詳解,使用時進行與或運算,但是定義多了之后,會很亂、臃腫,編寫容易出錯,EnumSet可以實現(xiàn)類似的功能,且使用起來很簡潔,需要的朋友可以參考下

EnumSet

當需要使用位運算時,可能你會如此定義

private final static int FIRST = 1;
private final static int SECOND = 1 << 1;
private final static int THIRD = 1 << 2;

使用時進行與或運算。但是定義多了之后,會很亂、臃腫,編寫容易出錯。EnumSet可以實現(xiàn)類似的功能,且使用起來很簡潔。

示例

public enum EnumTest {
    FIRST,
    SECOND;
    public static void main(String[] args) {
        EnumSet<EnumTest> enumTests = EnumSet.allOf(EnumTest.class);
        //輸出enumTests所有元素
        System.out.println(enumTests);//[FIRST, SECOND]
        //判斷集中中是否存在
        System.out.println(enumTests.contains(EnumTest.SECOND));//true
    }
}

屬性 

final Class<E> elementType;
final Enum<?>[] universe;

elementType為EnumSet存儲的元素類型,示例中為EnumTest。universe為存儲的所有枚舉實例數(shù)組。

noneOf

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)//判斷枚舉實例的數(shù)目
            return new RegularEnumSet<>(elementType, universe);
        else
            return new JumboEnumSet<>(elementType, universe);
    }

首先獲取枚舉的所有實例,具體過程參見上一篇博文。RegularEnumSet和JumboEnumSet為EnumSet的兩個實現(xiàn)類。

當枚舉中定義的實例數(shù)不大于64時,生成RegularEnumSet,否則生成JumboEnumSet。

allOf

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

在allOf先調(diào)用noneOf獲得EnumSet(RegularEnumSet或JumboEnumSet),allAll是個抽象方法,看下RegularEnumSet中是如何實現(xiàn)的

//RegularEnumSet.java
private long elements = 0L;
void addAll() {
        if (universe.length != 0)
            elements = -1L >>> -universe.length;
}

elements代表了EnumSet中存儲的所有枚舉實例所代表的bit數(shù)。示例中存儲了FIRST和SECOND,分別代表了1和2,所以allAll之后,elements為3。

of

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

of方法有好幾個,參數(shù)不同罷了。這里指只說單元素的情況。getDeclaringClass獲取e的枚舉類型。這里有個問題,為什么不用getClass。在示例中,這兩種返回的都是EnumTest。再看另一種情況

public enum EnumTest {
    FIRST {
        @Override
        void doSometing() {
        }
    },
    SECOND {
        @Override
        void doSometing() {
        }
    };
    abstract void doSometing();
    public static void main(String[] args) {
        System.out.println(EnumTest.SECOND.getClass());//EnumTest$2
        System.out.println(EnumTest.SECOND.getDeclaringClass());//EnumTest
    }
}

當枚舉有方法實現(xiàn)時,此時相當于內(nèi)部類,getClass和getDeclaringClass返回的結果就不一樣了。

public final Class<E> getDeclaringClass() {
        Class<?> clazz = getClass();//獲取自己的Class
        Class<?> zuper = clazz.getSuperclass();//獲取父類的Class
        return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;//兩者不等時取父類
    }

說回來,獲取類型之后,調(diào)用noneOf。調(diào)用add方法。

//RegularEnumSet.java
public boolean add(E e) {
        typeCheck(e);//校驗e的類型是否和生成elementType一致
        long oldElements = elements;
        elements |= (1L << ((Enum<?>)e).ordinal());
        return elements != oldElements;
    }
 

如果此時e為EnumTest.SECOND,ordinal為1,那么elements與運算后則為2。

contains

contains為AbstractCollection中的方法,EnumSet并沒有覆寫,而是交給兩個子類去實現(xiàn)的。

//RegularEnumSet.java
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;
    }

contains最終算的就是枚舉值對應的比特位是否被置位。

總結

枚舉自帶自增長的屬性ordinal,可以和位運算完美的結合在一起。

EnumSet的根本就是利用了這個特性,將ordinal和位運算封裝起來,用戶只需要像使用Set一樣使用它。

到此這篇關于Java枚舉之EnumSet詳解的文章就介紹到這了,更多相關Java枚舉EnumSet內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • java線程中斷?interrupt?和?LockSupport解析

    java線程中斷?interrupt?和?LockSupport解析

    這篇文章主要為大家介紹了java線程中斷?interrupt?和?LockSupport示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • springcloud?feign?接口指定接口服務ip方式

    springcloud?feign?接口指定接口服務ip方式

    這篇文章主要介紹了springcloud?feign?接口指定接口服務ip方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 淺談Java泛型讓聲明方法返回子類型的方法

    淺談Java泛型讓聲明方法返回子類型的方法

    下面小編就為大家?guī)硪黄獪\談Java泛型讓聲明方法返回子類型的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02
  • javaweb啟動時啟動socket服務端代碼實現(xiàn)

    javaweb啟動時啟動socket服務端代碼實現(xiàn)

    這篇文章主要介紹了javaweb啟動時啟動socket服務端代碼實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-11-11
  • Springboot實現(xiàn)高吞吐量異步處理詳解(適用于高并發(fā)場景)

    Springboot實現(xiàn)高吞吐量異步處理詳解(適用于高并發(fā)場景)

    這篇文章主要介紹了Springboot實現(xiàn)高吞吐量異步處理詳解(適用于高并發(fā)場景),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-11-11
  • SpringBoot實現(xiàn)導出復雜對象到Excel文件

    SpringBoot實現(xiàn)導出復雜對象到Excel文件

    這篇文章主要為大家詳細介紹了如何使用Hutool和EasyExcel兩種方式來實現(xiàn)在Spring Boot項目中導出復雜對象到Excel文件,需要的小伙伴可以參考下
    2025-03-03
  • java接口性能從20s優(yōu)化到500ms示例詳解

    java接口性能從20s優(yōu)化到500ms示例詳解

    這篇文章主要為大家介紹了java接口性能從20s優(yōu)化到500ms的操作技巧示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • OpenCV實現(xiàn)普通閾值

    OpenCV實現(xiàn)普通閾值

    這篇文章主要為大家詳細介紹了OpenCV實現(xiàn)普通閾值,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • SpringBoot整合Spring Batch示例代碼

    SpringBoot整合Spring Batch示例代碼

    這篇文章主要來和大家一起探討一下SpringBoot如何整合Spring Batch,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-10-10
  • springboot集成websocket的四種方式小結

    springboot集成websocket的四種方式小結

    本文主要介紹了springboot集成websocket的四種方式小結,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12

最新評論