public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, java.io.Serializable {…} public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable {…}
public synchronized V put(K key, V value) { // Make sure the value is not null if (value == null) { throw new NullPointerException(); } // Makes sure the key is not already in the hashtable. Entry tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; //… }
import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; public class TestCase { public static void main(String[] args) { Map<Integer,String> hashMap = new HashMap<Integer,String>(); hashMap.put(0, null); hashMap.put(1, "one"); hashMap.put(2, "two"); hashMap.put(null, "null"); for(Entry<Integer, String> e : hashMap.entrySet()) { System.out.println("Key: " + e.getKey() + " -- Value: " + e.getValue()); } System.out.println(hashMap.get(0)); System.out.println(hashMap.get(4)); System.out.println("Contains key 0 ? :" + hashMap.containsKey(0)); System.out.println("Contains key 4 ? :" + hashMap.containsKey(4)); System.out.println("Contains value null ? :" + hashMap.containsValue(null)); } }
Key: null -- Value: null Key: 0 -- Value: null Key: 1 -- Value: one Key: 2 -- Value: two null null Contains key 0 ? :true Contains key 4 ? :false Contains value null ? :true
public synchronized V put(K key, V value) { // Make sure the value is not null if (value == null) { throw new NullPointerException(); } // Makes sure the key is not already in the hashtable. Entry tab[] = table; int hash = key.hashCode();//hashcode int index = (hash & 0x7FFFFFFF) % tab.length; //… }
public V put(K key, V value) { if (key == null) return putForNullKey(value); int hash = hash(key.hashCode());//hashcode int i = indexFor(hash, table.length); //… } static int hash(int h) { h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); }
/** * The default initial capacity - MUST be a power of two. */ static final int DEFAULT_INITIAL_CAPACITY = 16; /** * The load factor used when none specified in constructor. */ static final float DEFAULT_LOAD_FACTOR = 0.75f;
HashTable中的内部数组的初始容量是11,加载因子也是0.75数组的增容方式为(oldCapacity * 2 + 1):
public Hashtable() { this(11, 0.75f); } protected void rehash() { int oldCapacity = table.length; Entry[] oldMap = table; int newCapacity = oldCapacity * 2 + 1; //… }
public HashMap(Map<? extends K, ? extends V> m) { this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1, DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR); putAllForCreate(m); }
而Hashtable的实现是:
public Hashtable(Map<? extends K, ? extends V> t) { this(Math.max(2*t.size(), 11), 0.75f); putAll(t); }