最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java枚舉之EnumSet詳解

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

EnumSet

當(dāng)需要使用位運(yùn)算時(shí),可能你會(huì)如此定義

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

使用時(shí)進(jìn)行與或運(yùn)算。但是定義多了之后,會(huì)很亂、臃腫,編寫容易出錯(cuò)。EnumSet可以實(shí)現(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存儲(chǔ)的元素類型,示例中為EnumTest。universe為存儲(chǔ)的所有枚舉實(shí)例數(shù)組。

noneOf

public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
        Enum<?>[] universe = getUniverse(elementType);//獲取枚舉類型的所有實(shí)例
        if (universe == null)
            throw new ClassCastException(elementType + " not an enum");
        if (universe.length <= 64)//判斷枚舉實(shí)例的數(shù)目
            return new RegularEnumSet<>(elementType, universe);
        else
            return new JumboEnumSet<>(elementType, universe);
    }

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

當(dāng)枚舉中定義的實(shí)例數(shù)不大于64時(shí),生成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是個(gè)抽象方法,看下RegularEnumSet中是如何實(shí)現(xiàn)的

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

elements代表了EnumSet中存儲(chǔ)的所有枚舉實(shí)例所代表的bit數(shù)。示例中存儲(chǔ)了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方法有好幾個(gè),參數(shù)不同罷了。這里指只說單元素的情況。getDeclaringClass獲取e的枚舉類型。這里有個(gè)問題,為什么不用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
    }
}

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

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

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

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

如果此時(shí)e為EnumTest.SECOND,ordinal為1,那么elements與運(yùn)算后則為2。

contains

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

//RegularEnumSet.java
public boolean contains(Object e) {
        if (e == null)//判空
            return false;
        Class<?> eClass = e.getClass();//校驗(yàn)類型
        if (eClass != elementType && eClass.getSuperclass() != elementType)
            return false;
        //比特位運(yùn)算
        return (elements & (1L << ((Enum<?>)e).ordinal())) != 0;
    }

contains最終算的就是枚舉值對應(yīng)的比特位是否被置位。

總結(jié)

枚舉自帶自增長的屬性ordinal,可以和位運(yùn)算完美的結(jié)合在一起。

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

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

相關(guān)文章

  • response對象的使用(實(shí)例講解)

    response對象的使用(實(shí)例講解)

    下面小編就為大家?guī)硪黄猺esponse對象的使用(實(shí)例講解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09
  • JavaFx 實(shí)現(xiàn)按鈕防抖功能

    JavaFx 實(shí)現(xiàn)按鈕防抖功能

    最近Sun公司推出了JavaFX框架,使用它可以利用JavaFX編程語言來開發(fā)富互聯(lián)網(wǎng)應(yīng)用程序(RIA),這篇文章主要介紹了JavaFx 實(shí)現(xiàn)按鈕防抖功能,需要的朋友可以參考下
    2022-01-01
  • Java?Swing實(shí)現(xiàn)自定義按鈕組件的完整代碼

    Java?Swing實(shí)現(xiàn)自定義按鈕組件的完整代碼

    本文介紹了Java?Swing按鈕工具類,用于簡化按鈕創(chuàng)建,它封裝了多種按鈕樣式、圖標(biāo)及事件處理,支持懸停效果,開發(fā)者僅需一行代碼即可創(chuàng)建規(guī)范按鈕,大幅提升開發(fā)效率,文中附有完整源碼
    2026-05-05
  • Java API如何實(shí)現(xiàn)向Hive批量導(dǎo)入數(shù)據(jù)

    Java API如何實(shí)現(xiàn)向Hive批量導(dǎo)入數(shù)據(jù)

    這篇文章主要介紹了Java API如何實(shí)現(xiàn)向Hive批量導(dǎo)入數(shù)據(jù)的操作,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 關(guān)于@Bean的使用方式

    關(guān)于@Bean的使用方式

    這篇文章主要介紹了關(guān)于@Bean的使用方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • 使用java的milo框架訪問OPCUA服務(wù)的過程

    使用java的milo框架訪問OPCUA服務(wù)的過程

    這篇文章主要介紹了使用java的milo框架訪問OPCUA服務(wù)的方法,本次采用KEPServerEX5模擬服務(wù)端,使用milo開發(fā)的程序作為客戶端,具體操作使用過程跟隨小編一起看看吧
    2022-01-01
  • SpringBoot啟動(dòng)時(shí)執(zhí)行特定代碼的10種方式

    SpringBoot啟動(dòng)時(shí)執(zhí)行特定代碼的10種方式

    在實(shí)際的 Spring Boot 項(xiàng)目開發(fā)中,我們經(jīng)常需要在應(yīng)用啟動(dòng)時(shí)執(zhí)行一些特定的初始化代碼,本文將全面深入地介紹 Spring Boot 中啟動(dòng)時(shí)執(zhí)行特定代碼的 10 種方式,需要的朋友可以參考下
    2025-10-10
  • Java注解Annotation解析

    Java注解Annotation解析

    這篇文章主要為大家詳細(xì)介紹了Java注解Annotation,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • Java中notify是順序喚醒還是隨機(jī)喚醒的

    Java中notify是順序喚醒還是隨機(jī)喚醒的

    這篇文章主要介紹了Java中notify是順序喚醒還是隨機(jī)喚醒的,有很多人會(huì)認(rèn)為?notify?是隨機(jī)喚醒的,但它真的是隨機(jī)喚醒的嗎?帶著疑問一起進(jìn)入文章了解具體的內(nèi)容吧
    2022-05-05
  • java實(shí)現(xiàn)解析Cron時(shí)間表達(dá)式為中文描述

    java實(shí)現(xiàn)解析Cron時(shí)間表達(dá)式為中文描述

    這篇文章主要為大家詳細(xì)介紹了java如何實(shí)現(xiàn)解析Cron時(shí)間表達(dá)式為中文描述,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解下
    2023-11-11

最新評論

宁陕县| 永州市| 名山县| 普兰店市| 东乡县| 安乡县| 淮阳县| 诸城市| 邹城市| 长顺县| 桑植县| 扬州市| 恩施市| 丰都县| 庆元县| 长子县| 大荔县| 宜阳县| 桂平市| 大姚县| 安丘市| 前郭尔| 康平县| 纳雍县| 溧水县| 吴忠市| 股票| 红河县| 英德市| 兰考县| 固原市| 休宁县| 天峻县| 砚山县| 涿州市| 夏津县| 文成县| 兴义市| 富川| 丰县| 巫溪县|