Maybe you don’t know the difference between HashMap and HashTable

background

Maybe you don’t know the difference between HashMap and HashTable

Interviewer: Tell me about the difference between HashMap and Hashtable?
Interviewer: 1. HashMap is thread-insecure, Hashtable is thread-safe 2. HashMap is
faster than HashTable
3. Java 5 provides ConcurrentHashMap, which is a replacement for HashTable and has better scalability than HashTable.
Interviewer: Does HashMap support null Key and null value? Does HashTable support null Key and null value?
Interviewer: HashMap supports null key and null value, HashTable also supports null key and null value
Interviewer: Why?
Interviewer: The
heart of the prescribed interviewer: collapse! I do not know why either! The above are all interview questions.
Interviewer: Go back and wait for the notice

Have you experienced the above interview scene? This question may hurt the hearts of many interviewees, so let's take a look at the source code of these two!

Why does HashMap support null key values?

1. We know that HashMap can do the process of Hash processing:

 /**
 * 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);
 }

When the key is null, set the value of the key to 0 for calculation

2.Hashcode

Worth distribution:

 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;
 }

When value is null, the default is 0

Why does HashTable not support null key values

1. The key cannot be null, otherwise a null pointer exception will be reported

 /**
 * 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 cannot be null, otherwise a null pointer exception will be reported

 /**
 * 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;
 }

Why is jdk so designed?

Why is the design of jdk not consistent?

First, let's take a look at HashTable

/ * uthorauthor Arthur van Hoff

  • @author Josh Bloch
  • @author Neal Gafter
  • @since JDK1.0
    */
    It was the first version of jdk1.0. The main designer was Arthur van Hoff. Perhaps the designer thought that null was useless as a key and value.

Look at the situation of HashMap again

/ * @author Doug Lea
 * @author Josh Bloch
 * @author Arthur van Hoff
 * @author Neal Gafter
 * @since 1.2
 */

It didn't appear until jdk 1.2. The main designer was the famous Doug Lea. In actual projects, the value is really null. It is rare for the key to be null, but it does not mean there is no. HashMap allows null as the key and value. It should be the designer of the class. Think about the design to make this class more useful!

Guess you like

Origin blog.51cto.com/15015181/2556409