<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    I want to fly higher
    programming Explorer
    posts - 114,comments - 263,trackbacks - 0
    1.EnumSet示例及核心源碼分析

    package com.landon.mavs.example.collection;

    import java.util.EnumSet;

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;

    import com.landon.mavs.example.collection.EnumMapExample.NBA;

    /**
     * 
     * EnumSet example
     * 
     * <pre>
     * 1.public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
     *     implements Cloneable, java.io.Serializable
     * 2.其內(nèi)部元素為枚舉,另外可以看到其是一個(gè)抽象類abstract
     * 3.其在內(nèi)部表示為位向量,足以用作傳統(tǒng)上基于 int 的“位標(biāo)志”的替換形式.(即類似0x1000000,按bit存儲(chǔ),用位運(yùn)算進(jìn)行相關(guān)操作)
     * 4. 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);
     *     }
     *     從源碼上看:即根據(jù)傳入的枚舉類型判斷組成長度,64以內(nèi)則返回RegularEnumSet,否則JumboEnumSet
     * 5.從其內(nèi)部API方法看,全部是靜態(tài)方法static.
     * 6.以RegularEnumSet內(nèi)部方法實(shí)現(xiàn):
     * public boolean add(E e) {
     *         typeCheck(e);
     *         // elements默認(rèn)為0
     *         long oldElements = elements;
     *         elements |= (1L << ((Enum)e).ordinal());
     *         return elements != oldElements;
     *     }
     *  從add源碼上看:1.取枚舉值的ordinal,初始為0. 2.1 << ordinal 3.與elements做|運(yùn)算
     *  舉例:a.添加ordinal為0,則計(jì)算后elements為1
     *     b.添加ordinal為1,則計(jì)算后elements為(10 | 01) = 11
     *     c.添加ordinal為2,則計(jì)算后elements為(011 | 100) = 111
     *   ->所以從源碼上看,其就是用一個(gè)long來存儲(chǔ)枚舉.你懂得(long是64位).
     *   
     *   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源碼上看:最重要的是最好一句:(elements & (1L << ((Enum)e).ordinal())) != 0
     *         1.1L << ((Enum)e).ordinal()
     *         2.與elements做&運(yùn)算
     *        舉例:如果ordinal為2,則通過第一步計(jì)算值為4(100) & 111(之前已經(jīng)添加過ordinal為2的元素,高位至1)
     *        ->則高位肯定為1,則表示有這個(gè)元素
     *         總結(jié):利用一個(gè)long和位運(yùn)算實(shí)現(xiàn)EnumSet的快速存儲(chǔ)和判斷.
     *  7.至于JumboEnumSet的內(nèi)部實(shí)現(xiàn):則是用一個(gè)long elements[]實(shí)現(xiàn),只是對(duì)long的擴(kuò)展,其實(shí)現(xiàn)細(xì)節(jié)差不太多,這里不詳述了
     * </pre>
     * 
     * @author landon
     * 
     
    */

    public class EnumSetExample {
        
    private static final Logger LOGGER = LoggerFactory
                .getLogger(EnumSetExample.class);

        
    public static void main(String[] args) {
            
    // allOf:一個(gè)包含指定元素類型的所有元素的枚舉 set
            EnumSet<NBA> allofEnumSet = EnumSet.allOf(NBA.class);
            
    // [allofEnumSet:[MAVS, LAKERS, PACERS]]
            LOGGER.debug("allofEnumSet:{}", allofEnumSet);

            
    // noneOf:創(chuàng)建一個(gè)具有指定元素類型的空枚舉 set
            EnumSet<NBA> noneofEnumSet = EnumSet.noneOf(NBA.class);
            
    // 添加一個(gè)元素
            noneofEnumSet.add(NBA.LAKERS);
            
    // [noneofEnumSet:[LAKERS]]
            LOGGER.debug("noneofEnumSet:{}", noneofEnumSet);

            
    // complementOf:取補(bǔ)
            EnumSet<NBA> complementOfEnumSet = EnumSet.complementOf(noneofEnumSet);
            
    // [[complementOfEnumSet:[MAVS, PACERS]]
            LOGGER.debug("complementOfEnumSet:{}", complementOfEnumSet);

            
    // copyof:拷貝
            EnumSet<NBA> copyofEnumSet = EnumSet.copyOf(complementOfEnumSet);
            
    // [copyofEnumSet:[MAVS, PACERS]]
            LOGGER.debug("copyofEnumSet:{}", copyofEnumSet);

            
    // of(E e):最初包含指定元素的枚舉 set
            EnumSet<NBA> ofEnumSet = EnumSet.of(NBA.PACERS);
            LOGGER.debug("ofEnumSet:{}", ofEnumSet);

            
    // of(E first,E rest)
            NBA[] nbas = new NBA[] { NBA.LAKERS, NBA.MAVS, NBA.PACERS };
            EnumSet<NBA> ofEnumSet2 = EnumSet.of(NBA.PACERS, nbas);
            
    // 從輸出可以可以看到:是按照枚舉的ordinal順序輸出的
            LOGGER.debug("ofEnumSet2:{}", ofEnumSet2);

            
    // range(E from, E to) [from,to]
            EnumSet<NBA> rangeEnumSet = EnumSet.range(NBA.MAVS, NBA.PACERS);
            LOGGER.debug("rangeEnumSet:{}", rangeEnumSet);

            
    // Exception in thread "main" java.lang.IllegalArgumentException: PACERS
            
    // > LAKERS
            
    // 拋出了異常,所以from和to的順序不能顛倒(按照枚舉的ordinal順序)
            EnumSet<NBA> rangeEnumSet2 = EnumSet.range(NBA.PACERS, NBA.LAKERS);
            LOGGER.debug("rangeEnumSet2:{}", rangeEnumSet2);
        }


    }



    2.EnumMap示例及核心源碼分析

    package com.landon.mavs.example.collection;

    import java.util.Collection;
    import java.util.EnumMap;

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;

    /**
     * 
     * EnumMap example
     * 
     * <pre>
     * 1.public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V>
     *     implements java.io.Serializable, Cloneable
     * 2.可見EnumMap的key是一個(gè)枚舉
     * 3.枚舉映射在內(nèi)部表示為數(shù)組 
     * 4. public V put(K key, V value) {
     *         typeCheck(key);
     * 
     *         int index = key.ordinal();
     *         Object oldValue = vals[index];
     *         vals[index] = maskNull(value);
     *         if (oldValue == null)
     *             size++;
     *         return unmaskNull(oldValue);
     *     }
     *     從put的源碼可以看到,是利用Enum的ordinal作為數(shù)組的索引.所以實(shí)現(xiàn)緊湊且高效
     * </pre>
     * 
     * @author landon
     * 
     
    */

    public class EnumMapExample {
        
    private static final Logger LOGGER = LoggerFactory
                .getLogger(EnumMapExample.class);

        
    /**
         * 
         * Nba球隊(duì)枚舉,分別是小牛,湖人,步行者
         * 
         * @author landon
         * 
         
    */

        
    static enum NBA {
            MAVS, LAKERS, PACERS,
        }


        
    public static void main(String[] args) {
            
    // 構(gòu)造函數(shù)public EnumMap(Class<K> keyType),參數(shù)表示key類型
            
    // 泛型只是編譯起作用
            EnumMap<NBA, String> em = new EnumMap<NBA, String>(NBA.class);

            
    // put順序不是根據(jù)枚舉的ordinal順序
            em.put(NBA.LAKERS, "kobe");
            em.put(NBA.MAVS, "dirk");
            em.put(NBA.PACERS, "miller");

            
    // get方法會(huì)首先檢查參數(shù)的class是否valid(與keyTypeClass對(duì)比)
            LOGGER.debug("mavs_player:{}", em.get(NBA.MAVS));
            
    // 類型檢查失敗則返回null
            LOGGER.debug("mavs_player:{}", em.get("mavs"));

            Collection
    <String> values = em.values();
            
    // 從輸出可以看到,視圖的內(nèi)部順序是枚舉定義的順序.
            
    // 輸出em.values:[dirk, kobe, miller]
            LOGGER.debug("em.values:{}", values.toString());

            
    // 拋出空指針異常Exception in thread "main" java.lang.NullPointerException
            
    // 所以key不允許為null
            em.put(null"tmac");
        }

    }


    posted on 2014-02-03 18:34 landon 閱讀(1645) 評(píng)論(0)  編輯  收藏 所屬分類: ProgramSources
    主站蜘蛛池模板: 一道本不卡免费视频| 91嫩草国产在线观看免费| 青青免费在线视频| 亚洲无码一区二区三区| youjizz亚洲| 国产精品亚洲精品青青青| 亚洲制服丝袜精品久久| 亚洲第一页中文字幕| 亚洲欧洲尹人香蕉综合| 亚洲天堂一区在线| 狠狠色香婷婷久久亚洲精品| 亚洲va乱码一区二区三区| 国产精品高清视亚洲一区二区| 亚洲va在线va天堂成人| 亚洲欧美成人综合久久久| www亚洲精品久久久乳| 黄页网址大全免费观看12网站| 人妻仑刮八A级毛片免费看| g0g0人体全免费高清大胆视频| 国产免费福利体检区久久| 你是我的城池营垒免费看| 亚洲一区二区在线免费观看| 96免费精品视频在线观看| 国产1024精品视频专区免费 | 久久久久se色偷偷亚洲精品av| 亚洲国产日产无码精品| 亚洲熟女精品中文字幕| 美女免费视频一区二区三区| 一个人看的免费高清视频日本| 国产午夜精品免费一区二区三区| 免费无码又爽又刺激高潮视频| av免费不卡国产观看| 国产成人免费a在线视频app| 亚洲国产精品自在拍在线播放| 亚洲中文字幕久久精品无码喷水 | 久久精品夜色噜噜亚洲A∨| 亚洲国产成人片在线观看| 亚洲成人网在线播放| 无码亚洲成a人在线观看| 黄色网页在线免费观看| 59pao成国产成视频永久免费|