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

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

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

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

            
    // complementOf:取補
            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是一個枚舉
     * 3.枚舉映射在內部表示為數組 
     * 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作為數組的索引.所以實現緊湊且高效
     * </pre>
     * 
     * @author landon
     * 
     
    */

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

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

        
    static enum NBA {
            MAVS, LAKERS, PACERS,
        }


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

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

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

            Collection
    <String> values = em.values();
            
    // 從輸出可以看到,視圖的內部順序是枚舉定義的順序.
            
    // 輸出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 閱讀(1654) 評論(0)  編輯  收藏 所屬分類: ProgramSources
    主站蜘蛛池模板: 亚洲精品少妇30p| 337p日本欧洲亚洲大胆裸体艺术| 18禁止看的免费污网站| **实干一级毛片aa免费| 亚洲中文字幕不卡无码| 国产精品免费久久久久影院| 日本免费一区二区久久人人澡| 国内精品乱码卡1卡2卡3免费| 国产又粗又长又硬免费视频| 亚洲激情在线观看| 无码一区二区三区亚洲人妻| 免费国产成人α片| 日本一道一区二区免费看 | 亚洲乱码中文字幕手机在线| 亚洲视频一区调教| 99精品视频免费观看| 精品国产日韩亚洲一区| 亚洲无吗在线视频| 国产免费网站看v片在线| 日韩免费高清视频网站| 国产精品成人亚洲| 成人毛片18女人毛片免费视频未| 最新亚洲成av人免费看| 日韩精品无码免费专区午夜| 久久夜色精品国产噜噜噜亚洲AV| 麻豆一区二区三区蜜桃免费| 国产精品成人免费视频网站京东| 亚洲成AV人片在线观看WWW| 羞羞视频在线免费观看| 国产亚洲美女精品久久久| 久久香蕉国产线看免费| 亚洲国产理论片在线播放| 最刺激黄a大片免费网站| 久久亚洲AV无码西西人体| 久久青草国产免费观看| 亚洲一级片在线播放| 精品福利一区二区三区免费视频| 亚洲AV日韩精品久久久久| 国产精品99精品久久免费| 波多野结衣亚洲一级| 久久久久亚洲AV成人网人人软件|