HashMapとHashTableの違いがわからないかもしれません

バックグラウンド

HashMapとHashTableの違いがわからないかもしれません

インタビュアー: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を使用できます。クラスの設計者である必要があります。このクラスをより便利にするための設計について考えてください。

おすすめ

転載: blog.51cto.com/15015181/2556409