バックグラウンド
インタビュアー:HashMapとHashtableの違いについて教えてください。
インタビュアー:
1。HashMapはスレッドに安全ではなく、Hashtableはスレッドセーフです2.HashMapはHashTableよりも高速です3.Java
5はConcurrentHashMapを提供します。これは、HashTableの代わりであり、HashTableよりも優れたスケーラビリティを備えています。
インタビュアー:HashMapはnullキーとnull値をサポートしていますか?HashTableはnullキーとnull値をサポートしていますか?
インタビュアー:HashMapはnullキーとnull値をサポートし、HashTableはnullキーとnull値もサポートします。
インタビュアー:なぜですか?
インタビュアー:処方された
インタビュアーの核心:崩壊!理由もわかりません!上記はすべてインタビューの質問です。
インタビュアー:戻って通知を待つ
上記のインタビューシーンを体験したことがありますか?この質問は多くのインタビュー対象者の心を傷つける可能性があるので、これら2つのソースコードを見てみましょう!
HashMapがnullキー値をサポートするのはなぜですか?
1.HashMapがハッシュ処理のプロセスを実行できることはわかっています。
/**
* 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);
}
キーがnullの場合、計算のためにキーの値を0に設定します
2.ハッシュコード
価値のある配布:
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;
}
値がnullの場合、デフォルトは0です。
HashTableがnullキー値をサポートしないのはなぜですか
1.キーをnullにすることはできません。そうしないと、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.値をnullにすることはできません。そうしないと、nullポインター例外が報告されます。
/**
* 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はそのように設計されているのですか?
jdkの設計に一貫性がないのはなぜですか?
まず、HashTableを見てみましょう
/ * uthorauthor Arthur van Hoff
- @author Josh Bloch
- @authorニール・ガフター
- @since JDK1.0
* /jdk1.0
の最初のバージョンでした。メインのデザイナーはArthurvan Hoffでした。おそらく、デザイナーはnullはキーと値として役に立たないと思っていました。
HashMapの状況をもう一度見てください
/ * @author Doug Lea
* @author Josh Bloch
* @author Arthur van Hoff
* @author Neal Gafter
* @since 1.2
*/
jdk1.2まで登場しませんでした。メインデザイナーは有名なダグリーでした。実際のプロジェクトでは、値は実際にはヌルです。キーがnullになることはまれですが、nullがないことを意味するわけではありません。HashMapでは、キーと値としてnullを使用できます。クラスの設計者である必要があります。このクラスをより便利にするための設計について考えてください。