淺讀java.util.Map及其實現類(二)

Map已知實現類概述


本文概述以下Map實現類,其中ConcurrentHashMap請轉步到 淺讀java.util.Map及其實現類(三)
AbstractMap
Attributes
AuthProvider
ConcurrentHashMap
ConcurrentSkipListMap
EnumMap
HashMap
Hashtable
IdentityHashMap
LinkedHashMap
PrinterStateReasons
Properties

AbstractMap

標籤:抽象Map
概述:一個實現map的抽象類,提供各類一些基礎的實現
以下類都是他的子類
ConcurrentHashMap /  ConcurrentSkipListMap /  EnumMap /  HashMap /  IdentityHashMap /  TreeMap /  WeakHashMap 
從AbstractMap源碼中可以看到put及AbstractMap.SimpleImmutableEntry中setValue(V value)是不支持的method我們需要自己來實現這部分功能
entrySet是需要自己實現的,其中TreeMap等都對他進行了實現

Attributes

標籤:MANIFEST.MF讀取 非線程安全
概述: 用來讀取jar中MANIFEST.MF的文件,UTF-8輸出編碼
public static void main(String[] args) {
		String s = "e:\\commons-dbcp-1.3.jar"; 
		JarInputStream ji = null;
		try {
            //jarInputStream與attributes都是在java.util.jar包
			ji = new JarInputStream(new FileInputStream(s));
			Manifest mf = ji.getManifest();
			mf.getMainAttributes().forEach((k, v) -> System.out.println("[ k:" + k + "/" + "v:" + v + " ]"));
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (ji != null)
				try {
					ji.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
	}
[ k:Bundle-License/v:http://www.apache.org/licenses/LICENSE-2.0.txt ]
[ k:Bundle-SymbolicName/v:org.apache.commons.dbcp ]
[ k:Archiver-Version/v:Plexus Archiver ]
[ k:Built-By/v:philsteitz ]
[ k:Bnd-LastModified/v:1265564429985 ]
[ k:Implementation-Vendor-Id/v:org.apache ]
[ k:Specification-Title/v:Commons DBCP ]
[ k:Bundle-DocURL/v:http://commons.apache.org/dbcp/ ]
[ k:Import-Package/v:javax.naming,javax.naming.spi,javax.sql,javax.transaction,javax.transaction.xa,org.apache.commons.dbcp;version="1.3",org.apache.commons.dbcp.cpdsadapter;version="1.3",org.apache.commons.dbcp.datasources;version="1.3",org.apache.commons.dbcp.managed;version="1.3",org.apache.commons.jocl;version="1.3",org.apache.commons.pool,org.apache.commons.pool.impl,org.xml.sax,org.xml.sax.helpers ]
[ k:Export-Package/v:org.apache.commons.jocl;version="1.3",org.apache.commons.dbcp.datasources;version="1.3",org.apache.commons.dbcp.cpdsadapter;version="1.3",org.apache.commons.dbcp.managed;version="1.3",org.apache.commons.dbcp;version="1.3" ]
[ k:Bundle-Name/v:Commons DBCP ]
[ k:Implementation-Title/v:Commons DBCP ]
[ k:Bundle-Description/v:Commons Database Connection Pooling ]
[ k:Implementation-Version/v:1.3 ]
[ k:Specification-Vendor/v:The Apache Software Foundation ]
[ k:Bundle-ManifestVersion/v:2 ]
[ k:Bundle-Vendor/v:The Apache Software Foundation ]
[ k:Tool/v:Bnd-0.0.238 ]
[ k:Manifest-Version/v:1.0 ]
[ k:Implementation-Vendor/v:The Apache Software Foundation ]
[ k:Bundle-Version/v:1.3 ]
[ k:X-Compile-Target-JDK/v:1.4 ]
[ k:X-Compile-Source-JDK/v:1.4 ]
[ k:Created-By/v:1.5.0_19 (Apple Inc.) ]
[ k:Build-Jdk/v:1.5.0_19 ]
[ k:Specification-Version/v:1.3 ]

AuthProvider

標籤:java.security.*

概述:JAAS相關內容,提供了3個抽象方法。login logout  setCallbackHandler


ConcurrentHashMap

標籤:高併發 線程安全 CAS node
請參見淺讀java.util.Map及其實現類(三)ConcurrentHashMap專題:http://blog.csdn.net/crazyzxljing0621/article/details/73733559

ConcurrentSkipListMap

標籤:Tree 跳錶 SkipList  線程安全 高併發
概述:跳錶機制提供了更高效的有序列表查詢
SkipList:給予有序列表下高效的操作
例:
         3,4,5,6,78,9,10
想要查詢5,9需要 3+7 ,一共10次比較操作
SkipList建立了Index Level
L3 3------------------>7----------->10
L2  3------->5------->7----------->10
L1  3-> 4-> 5-> 6-> 7-> 8-> 9-> 10
=============================
0.L3
1.3<5,3記錄下一個是7,7>5
2.L2
3.3記錄下一個是5,5==5,找到5了 
find : 以此類推跳錶的方式查詢更加迅速當然表越大效果越明顯可以有若干個Level
add:每一個rand levelN 在level 1 ~ levelN中插入自己,如果新值超過最大值,則在levelMax+1中插入自己
del:找到目標,然後依次按層刪除

EnumMap

標籤:枚舉map 非線程安全
概述:處理EnumKey的性能更高,內部使用數組存儲
例:
public static void main(String[] args) {
		
		EnumMap<State,String> e = new EnumMap<State,String>(State.class);
		System.out.println(e.put(State.NPE, "11"));
		System.out.println(e.put(State.NPE, "22"));
		for (Map.Entry<State, String> entry : e.entrySet()) {
			System.out.println(entry.getValue() + " " + entry.getKey().str());
		}
		System.out.println();
	}

public enum State {
	
	NOTFOUND("404", "404"), SERVERERROR("500", "500"),
	SUCCESS("100", "成功"), NPE("101", "空指針"), 
	EXCEPTION("102","異常"), IPPERMISSIONS("103", "IP訪問權限不足"), 
	VERSIONERROR("104", "版本錯誤"),
	DOMAINNOTFOUND("105", "域不存在"), ;

	private String value;
	private String str;

	private State(String value, String str) {
		this.value = value;
		this.str = str;
	}

	public String value() {
		return this.value;
	}

	public String str() {
		return this.str;
	}
}
源碼
  public EnumMap(Class<K> keyType) {
        this.keyType = keyType; 
        keyUniverse = getKeyUniverse(keyType);//將枚舉Key返回爲key[]
        vals = new Object[keyUniverse.length]; //初始化一個vals
    }
 public V put(K key, V value) {
        typeCheck(key); //key類型要匹配Class<K>
        int index = key.ordinal();  //得到Key的下標 Enum.ordinal();其實就是在你的Enum中的定義順序
        Object oldValue = vals[index]; 
        vals[index] = maskNull(value); 
           //如果值不存在則返回一個EnumMapObject //  hasCode return 0 // toString return "java.util.EnumMap.NULL"
        if (oldValue == null) 
            size++; //oldValue不存在計數器+1,代表是新增而不是覆蓋
        return unmaskNull(oldValue);//新增返回null 覆蓋返回 舊值
    }
  public V get(Object key) {
        return (isValidKey(key) ?
                unmaskNull(vals[((Enum<?>)key).ordinal()]) : null); 
          //key類型正確則以key下標去vals取值,空則返回
    }


HashMap

標籤:非線程安全 
概述:hashMap是最長用的Map實現類之一,他是哈希分佈
源碼:
 public HashMap(int initialCapacity, float loadFactor) {  
 //容量和加載因子,容量不說了,因子越小map利用率越高,衝突概率就高,反之越稀鬆,衝突概率越低
        if (initialCapacity < 0)  
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY) //初始容量不能超過最大支持容量,最大容量1<<30
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor)) //因子判斷
            throw new IllegalArgumentException("Illegal load factor:"+ loadFactor); 
           this.loadFactor = loadFactor; this.threshold = tableSizeFor(initialCapacity); //下一次調整大小的值
       }
		
	
static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;
        final K key;
        V value;
        Node<K,V> next;

        Node(int hash, K key, V value, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }

        public final K getKey()        { return key; }
        public final V getValue()      { return value; }
        public final String toString() { return key + "=" + value; }

        public final int hashCode() {
            return Objects.hashCode(key) ^ Objects.hashCode(value);
        }

        public final V setValue(V newValue) {
            V oldValue = value;
            value = newValue;
            return oldValue;
        }

        public final boolean equals(Object o) {
            if (o == this)
                return true;
            if (o instanceof Map.Entry) {
                Map.Entry<?,?> e = (Map.Entry<?,?>)o;
                if (Objects.equals(key, e.getKey()) &&
                    Objects.equals(value, e.getValue()))
                    return true;
            }
            return false;
        }
    }
鏈表散列存儲: 一種數組+鏈表的存儲結構,通過hash值計算,在合適的空間下平均分佈數據存儲,每一條數據都是一個Entry
Hash數據結構
----------------------------------------------------------------------------------------------------------------
數組->  位置1  位置2  位置3  位置4  位置5   位置6  位置7  位置8  位置9  位置10

數據->   "小明"    null    null    "小華"   "小龍"   null     null      null     null       null
               "小黑"
                    ↑
                 鏈表(產生哈希衝突,鏈表存儲)
-----------------------------------------------------------------------------------------------------------------
當數據put進hashmap時,會先計算其hash值
    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }
哈希衝突:
找到指定的hash數組位置,如果位置上沒有其他數據則直接插入,如果有其他數據則以鏈表方式並插到首位
這就是遇到了哈希衝突的鏈表法,還有一種開放地址法通過算法繼續尋找可用位置

Hashtable

標籤:線程安全 穩定 
概述:線程安全不允許空值,幾乎所有方法都是synchronized修飾
擴展:Hashtable ConcurrentHashMap相比下後者支持高併發更高效
    Hashtable Collections.synchronizedMap(Map<K,V>)後者是在參數Map的所有方法上加了個sync並返回,個人建議還是儘可能用Hashtable

IdentityHashMap

標籤:沒有equals Key可以重複
概述:此Map沒有equals,只有k1==k2所以我們可以做出2個相等的key
例:
	public static void main(String[] args) { 
		
		IdentityHashMap<String, Integer> map=new IdentityHashMap<String, Integer>();
		String a=new String("天");
		map.put(a, 1);
		map.put(new String("天"), 2);
		map.put(new String("天"), 3);
		map.put(new String("王"), 4);
		System.out.println(map.toString());
		System.out.println(map.get(a));
	}

LinkedHashMap

標籤:有序 非線程安全
概述:有序的HashMap,允許null key,null value。雙向循環鏈表包含頭結點
源碼
 static class Entry<K,V> extends HashMap.Node<K,V> {
        Entry<K,V> before, after; //繼承HashMap.Node並定義了before after來完成雙向循環鏈表
        Entry(int hash, K key, V value, Node<K,V> next) {
            super(hash, key, value, next);
        }
    }
其他地方與HashMap基本一致,只是增加了before,after並對相關函數重寫已遍生效有序

PrinterStateReasons

標籤: 打印機 非線程安全 HashMap派生類
概述:獲取打印機相關信息數據
public static void main(String[] args) {
		PrintService myPrint = PrintServiceLookup.lookupDefaultPrintService();
		PrinterStateReasons printerStateReasons = myPrint.getAttribute(PrinterStateReasons.class);
		System.out.println( printerStateReasons);
	}

Properties

標籤:屬性 線程安全 Hashtable派生類
概述:讀取java常用的*.properties格式文件
public static void main(String[] args) throws Exception {
		Properties pro = new Properties();
		try {
			pro.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("conf-test.properties"));
			System.out.println(pro.get("username"));
		} catch (IOException e) {
		}
	}

總結

淺讀第二章就到這裏,下期繼續

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章