和枚舉有關(guān)的那些事

本文是希望在閱讀<Effective Java>這本書(shū)中的精華部分都留下來(lái)一個(gè)記號(hào),前面幾章學(xué)習(xí)到的內(nèi)容以后會(huì)慢慢補(bǔ)上,現(xiàn)在先來(lái)把枚舉這部分的內(nèi)容添加上來(lái),博客好像太多了,現(xiàn)在主要就以簡(jiǎn)述為主吧,之前還買(mǎi)了域名搭建了一個(gè)私人博客號(hào)呢,哈哈

一.使用EnumSet代替位域

在做項(xiàng)目的過(guò)程中,我們可能會(huì)遇到一個(gè)情況,比如一個(gè)用戶,它一個(gè)人擁有多種狀態(tài):是否填寫(xiě)郵箱,是否填寫(xiě)手機(jī)號(hào)碼,是否驗(yàn)證身份證號(hào)碼,是否填寫(xiě)了學(xué)校信息等等,信息量比較少的時(shí)候還好,但是如果信息量一旦多起來(lái)的話,就沒(méi)有那么容易維護(hù)了,總不可能使用一個(gè)表來(lái)記錄每一種狀態(tài)吧,這個(gè)時(shí)候,我們的位域就可以發(fā)揮較大的作用了:
比如有這樣的二進(jìn)制數(shù)字:

00001111

我們可以計(jì)算出來(lái),這個(gè)數(shù)字的十進(jìn)制值是16,位域的意思是可以利用位域的值的不同,來(lái)記錄一個(gè)用戶的狀態(tài),比如第一個(gè)數(shù)字是代表是否填寫(xiě)了手機(jī)號(hào)碼,第二個(gè)是代表了是否填寫(xiě)了郵箱,第三個(gè)是代表了是否驗(yàn)證了身份證號(hào)碼,第四個(gè)是代表了是否填寫(xiě)了學(xué)校信息,如果用對(duì)應(yīng)的位置來(lái)表達(dá),應(yīng)該是

是否是是
1011
否是是否
0110

存儲(chǔ)的時(shí)候可以直接記錄二進(jìn)制轉(zhuǎn)化為十進(jìn)制的值,其實(shí)就是可以用一個(gè)值來(lái)代表用戶的幾個(gè)狀態(tài)了,一般在代碼上我們,可以用這種形式來(lái)表示

   public static final int USER_PHONE = 1 << 0;//1
   public static final int USER_MAIL = 1 << 1;//2
   public static final int USER_ID = 1 << 2;//2
   public static final int USER_STUDEND_MESSAGE= 1 << 3;//2

   public static void main(String[] args) {

       applyStyle(USER_PHONE|USER_MAIL);
       
   }
   
   public static void applyStyle(int styles) {
       //...
   }


位域利用了位操作符的時(shí)候,可以有效的執(zhí)行像union和intersection這樣的位操作,但是如果要打印出來(lái)的時(shí)候就要翻轉(zhuǎn)解析才可以了:

/**
     * @param states 所有狀態(tài)值
     * @param value  需要判斷狀態(tài)值
     * @return 是否存在
     */
    public static boolean hasState(long states, long value) {
        return (states & value) != 0;
    }

    /**
     * @param states 已有狀態(tài)值
     * @param value  需要添加狀態(tài)值
     * @return 新的狀態(tài)值
     */
    public static long addState(long states, long value) {
        if (hasState(states, value)) {
            return states;
        }
        return (states | value);
    }

    /**
     * @param states 已有狀態(tài)值
     * @param value  需要?jiǎng)h除狀態(tài)值
     * @return 新的狀態(tài)值
     */
    public static long removeState(long states, long value) {
        if (!hasState(states, value)) {
            return states;
        }
        return states ^ value;
    }

既然這一章節(jié)是講枚舉的話,那我們當(dāng)然可以有效的利用枚舉來(lái)解決這個(gè)問(wèn)題,因?yàn)镴ava.util包提供了EnumSet類來(lái)有效的標(biāo)識(shí)從單個(gè)枚舉類型中提取的多個(gè)值的多個(gè)集合.

        public enum Style{USER_PHONE,USER_MAIL,USER_ID,USER_STUDEND_MESSAGE}
    public static void userStutas(Set<Style> styles){
        
        for (Style style : styles) {
            System.out.println(style);
        }
    }

EnumSet類集位域的簡(jiǎn)潔和性能的優(yōu)勢(shì)及枚舉類型的所有優(yōu)點(diǎn)與一身.實(shí)際上EnumSet也有個(gè)缺點(diǎn),即它無(wú)法創(chuàng)建不可變的EnumSet(Java1.6為止沒(méi)有解決).同時(shí),可以用Collections.unmodifiable將EnumSet封裝起來(lái),但是間接性和性能會(huì)受到影響.

二,使用EnumMap代替序數(shù)索引

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容