HashMap / HashTable / HashSet
HashTable 與 HashMap:
表面:
HashTable不允許null值(key和value都不可以),HashMap允許null值(key和value都可以)。
HashTable的方法是同步的,HashMap未經同步,所以在多線程場合要手動同步HashMap這個區別就像Vector和ArrayList一樣。
HashTable有一個contains(Object value),功能和containsValue(Object value)功能一樣。
HashTable使用Enumeration,HashMap使用Iterator。
內部:
HashTable中hash數組默認大小是11,增加的方式是 old*2+1。HashMap中hash數組的默認大小是16,而且一定是2的指數。
哈希值的使用不同,HashTable直接使用對象的hashCode,代碼是這樣的:
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
而HashMap重新計算hash值,而且用與代替求模:
int hash = hash(k);
int i = indexFor(hash, table.length);
static int hash(Object x) {
int h = x.hashCode();
h += ~(h << 9);
h ^= (h >>> 14);
h += (h << 4);
h ^= (h >>> 10);
return h;
}
static int indexFor(int h, int length) {
return h & (length-1);
}
HashSet 、 HashMap:
HashMap可以看作三個視圖:key的Set,value的Collection,Entry的Set。這里HashSet就是其實就是HashMap的一個視圖。HashSet內部就是使用Hashmap實現的,和Hashmap不同的是它不需要Key和Value兩個值。
往hashset中插入對象其實只不過是內部做了
public boolean add(Object o) {
return map.put(o, PRESENT)==null;
}
往hashset中插入對象其實只不過是內部做了
public boolean add(Object o) {
return map.put(o, PRESENT)==null;
}
HashMap為散列映射,它是基于hash table的一個實現,它可在常量時間內安插元素,或找出一組key-value pair.
HashSet為散列集,它把查找時間看的很重要,其中所有元素必須要有hashCode()