zoukankan      html  css  js  c++  java
  • Java-HashMap和HashTable的区别

    类继承and实现上看

    public class Hashtable  
        extends Dictionary  
        implements Map, Cloneable, java.io.Serializable  
    public class HashMap  
        extends AbstractMap  
        implements Map, Cloneable, Serializable  

    可见Hashtable 继承自 Dictiionary 而 HashMap继承自AbstractMap

    从put方法比较

    hashTable:

    public synchronized V put(K key, V value) {  //###### 注意这里1  
      // Make sure the value is not null  
      if (value == null) { //###### 注意这里 2  
        throw new NullPointerException();  
      }  
      // Makes sure the key is not already in the hashtable.  
      Entry tab[] = table;  
      int hash = key.hashCode(); //###### 注意这里 3  
      int index = (hash & 0x7FFFFFFF) % tab.length;  
      for (Entry e = tab[index]; e != null; e = e.next) {  
        if ((e.hash == hash) && e.key.equals(key)) {  
          V old = e.value;  
          e.value = value;  
          return old;  
        }  
      }  
      modCount++;  
      if (count >= threshold) {  
        // Rehash the table if the threshold is exceeded  
        rehash();  
        tab = table;  
        index = (hash & 0x7FFFFFFF) % tab.length;  
      }  
      // Creates the new entry.  
      Entry e = tab[index];  
      tab[index] = new Entry(hash, key, value, e);  
      count++;  
      return null;  
    }  

    注意1 方法是同步的
    注意2 方法不允许value==null
    注意3 方法调用了key的hashCode方法,如果key==null,会抛出空指针异常

    hashMap:

    public V put(K key, V value) { //###### 注意这里 1  
      if (key == null)  //###### 注意这里 2  
        return putForNullKey(value);  
      int hash = hash(key.hashCode());  
      int i = indexFor(hash, table.length);  
      for (Entry e = table[i]; e != null; e = e.next) {  
        Object k;  
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {  
          V oldValue = e.value;  
          e.value = value;  
          e.recordAccess(this);  
          return oldValue;  
        }  
      }  
      modCount++;  
      addEntry(hash, key, value, i);  //###### 注意这里   
      return null;  
    }  

    注意1 方法是非同步的
    注意2 方法允许key==null
    注意3 方法并没有对value进行任何调用,所以允许为null

    contains争议
    Hashtable 有一个 contains方法,容易引起误会,所以在HashMap里面已经去掉了
    当然,2个类都用containsKey和containsValue方法。

    Hashtable的contains方法为什么容易引起误解?

    Hashtable继承于Map接口contains(Object value)
    测试此映射表中是否存在与指定值关联的键(如果此 Hashtable 将一个或多个键映射到此值,则返回 true)。
    判断容器中是否存在值
    但是contains并非和containsKey的功能一致而是和containsValue功能等同. 
    之所以说是等同原因是需要实现MAP中的containsValue:
    public boolean containsValue(Object value) { return contains(value); } 性能上没有区别 所以很让人引起误解认为:contains是判断是否存在关联的键

    默认值大小比较

    Hashtable中hash数组默认大小是11,增加的方式是 old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数

    hashtable:

        public Hashtable() {
            this(11, 0.75f);
        }

    hashmap:

        public HashMap() {
            this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
        }
        /**
         * The default initial capacity - MUST be a power of two.
         */
        static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
        /**
         * The load factor used when none specified in constructor.
         */
        static final float DEFAULT_LOAD_FACTOR = 0.75f;


    结论: hashMap 在大多数情况下是优先选择的。

  • 相关阅读:
    codewars sum of pairs
    codewars贪吃蛇算法题目
    记录一道有意思的js题目
    JS判断变量类型
    mock之初体验
    three.js尝试(二)模拟游戏开发:3D人物在地图上行走
    three.js尝试(一)模拟演唱会效果
    Vue中父组件使用子组件的emit事件,获取emit事件传出的值并添加父组件额外的参数进行操作
    网易前端工程师课程中,布局解决方案
    js飘窗
  • 原文地址:https://www.cnblogs.com/hwaggLee/p/4510410.html
Copyright © 2011-2022 走看看