面試官:說一下HashMap和Hashtable的區別吧?
面試者:1. HashMap是線程非安全的,Hashtable是線程安全的
2.HashMap比HashTable快
3.Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的擴展性更好。
面試官:HashMap是否支持null Key,null value?HashTable是否支持null Key,null value?
面試者:HashMap支持null key和null value,HashTable也支持null key和null value
面試官:爲何?
面試者:規定的
面試者心裏:崩潰!我也不知道爲何!上面都是面試題背的。
面試官:回去等通知吧面試
上面的面試場景你是否經歷過?這個問題也許會傷到不少面試者的心,那咱們扒出來這兩個的源碼來細細看看!安全
1.咱們知道HashMap的能夠要作Hash處理的過程:app
/** * Computes key.hashCode() and spreads (XORs) higher bits of hash * to lower. Because the table uses power-of-two masking, sets of * hashes that vary only in bits above the current mask will * always collide. (Among known examples are sets of Float keys * holding consecutive whole numbers in small tables.) So we * apply a transform that spreads the impact of higher bits * downward. There is a tradeoff between speed, utility, and * quality of bit-spreading. Because many common sets of hashes * are already reasonably distributed (so don't benefit from * spreading), and because we use trees to handle large sets of * collisions in bins, we just XOR some shifted bits in the * cheapest possible way to reduce systematic lossage, as well as * to incorporate impact of the highest bits that would otherwise * never be used in index calculations because of table bounds. */ static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }
當key爲null時,將key的值置爲0計算ide
2.Hashcodethis
值得分佈狀況:線程
public final int hashCode() { return Objects.hashCode(key) ^ Objects.hashCode(value); } /** * Returns the hash code of a non-{@code null} argument and 0 for * a {@code null} argument. * * @param o an object * @return the hash code of a non-{@code null} argument and 0 for * a {@code null} argument * @see Object#hashCode */ public static int hashCode(Object o) { return o != null ? o.hashCode() : 0; }
當value爲null時,默認爲0設計
1.key不能爲null,不然報空指針異常指針
/** * Tests if some key maps into the specified value in this hashtable. * This operation is more expensive than the {@link #containsKey * containsKey} method. * * <p>Note that this method is identical in functionality to * {@link #containsValue containsValue}, (which is part of the * {@link Map} interface in the collections framework). * * @param value a value to search for * @return <code>true</code> if and only if some key maps to the * <code>value</code> argument in this hashtable as * determined by the <tt>equals</tt> method; * <code>false</code> otherwise. * @exception NullPointerException if the value is <code>null</code> */ public synchronized boolean contains(Object value) { if (value == null) { throw new NullPointerException(); } Entry<?,?> tab[] = table; for (int i = tab.length ; i-- > 0 ;) { for (Entry<?,?> e = tab[i] ; e != null ; e = e.next) { if (e.value.equals(value)) { return true; } } } return false; }
2.value不能爲null,不然報空指針異常code
/** * Maps the specified <code>key</code> to the specified * <code>value</code> in this hashtable. Neither the key nor the * value can be <code>null</code>. <p> * * The value can be retrieved by calling the <code>get</code> method * with a key that is equal to the original key. * * @param key the hashtable key * @param value the value * @return the previous value of the specified key in this hashtable, * or <code>null</code> if it did not have one * @exception NullPointerException if the key or value is * <code>null</code> * @see Object#equals(Object) * @see #get(Object) */ 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; @SuppressWarnings("unchecked") Entry<K,V> entry = (Entry<K,V>)tab[index]; for(; entry != null ; entry = entry.next) { if ((entry.hash == hash) && entry.key.equals(key)) { V old = entry.value; entry.value = value; return old; } } addEntry(hash, key, value, index); return null; }
jdk 爲何這麼設計?orm
jdk的設計爲何沒有保持一致?
首先,咱們看一下HashTable
/ * @author Arthur van Hoff
再看一下HashMap的狀況
/ * @author Doug Lea * @author Josh Bloch * @author Arthur van Hoff * @author Neal Gafter * @since 1.2 */
它是直到jdk 1.2 纔出現,主要設計者是大名鼎鼎的Doug Lea,實際項目中,真的是有value爲null的狀況的。key爲null的狀況比較少見,但不表明沒有。HashMap容許null爲key和value應當是類的設計者思考讓這個類更有用的設計吧!