HashMap和Hashtable的区别(Hashtable的key和value都不可以为null)

不用多说,看下面的程序就可以:

HashMap map = new HashMap();

       map.put( "Null" , null );

       map.put( null , "Null" );

       map.put( null , "Empty" );

       System. out .println(map.get( null ));

       System. out .println(map.get( "Null" ));

       System. out .println(map.get( "NullThere" ));

       System. out .println(map.containsKey ( "Null" ));

System. out .println(map.containsKey ( "NullThere" ));

 

 

输出结果为:

Empty

null

null

true

false

 

 

 

HashMap

Hashtable

继承,实现

HashMap <K,V>    extends AbstractMap<K,V>    implements Map<K,V>, Cloneable, Serializable

Hashtable <K,V>

    extends Dictionary<K,V>

    implements Map<K,V>, Cloneable,Serializable

多线程,同步

未同步的,可以使用 Colletcions 进行同步

Map Collections.synchronizedMap(Map m)

已经同步过的可以安全使用

null 的处理

HashMap map = new HashMap();

map.put( null , "Null" );

map.put( "Null" , null );

map.containsKey( null );

map.containsValue( null );

以上这 5 条语句无论在编译期,还是在运行期都是没有错误的 .

HashMap 中, null 可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为 null 。当 get() 方法返回 null 值时,即可以表示 HashMap 中没有该键,也可以表示该键所对应的值为 null 。因此,在 HashMap 中不能由 get() 方法来判断 HashMap 中是否存在某个键, 而应该用 containsKey() 方法来判断。

Hashtable table = new Hashtable();

table.put(null, "Null");

table.put("Null", null);

table.contains(null);

table.containsKey(null);

table.containsValue(null);

后面的 5 句话在编译的时候不会有异常,可在运行的时候会报空指针异常

具体原因可以查看源代码

public synchronized V put(K key, V value) {

     // Make sure the value is not null

     if (value == null) {

         throw new NullPointerException();

     }

………….

增长率

void addEntry( int hash, K key, V value, int bucketIndex) {

      Entry<K,V> e = table [bucketIndex];

        table [bucketIndex] = new Entry<K,V>(hash, key, value, e);

        if ( size ++ >= threshold )

            resize (2 * table . length );

    }

protected void rehash() {

      int oldCapacity = table . length ;

      Entry[] oldMap = table ;

      int newCapacity = oldCapacity * 2 + 1;

      Entry[] newMap = new Entry[newCapacity];

      modCount ++;

      threshold = ( int )(newCapacity * loadFactor );

      table = newMap;

      for ( int i = oldCapacity ; i-- > 0 ;) {

          for (Entry<K,V> old = oldMap[i] ; old != null ; ) {

           Entry<K,V> e = old;

           old = old. next ;

           int index = (e. hash & 0x7FFFFFFF) % newCapacity;

           e. next = newMap[index];

           newMap[index] = e;

          }

      }

    }

 

哈希值的使用

HashMap 重新计算 hash 值,而且用与代替求模

      public boolean containsKey(Object key) {

              Object k = maskNull(key);

              int hash = hash(k.hashCode());

              int i = indexFor(hash, table.length);

              Entry e = table[i];

              while (e != null ) {

                  if (e.hash == hash && eq(k, e.key))

                      return true ;

                  e = e.next;

              }

              return false ;

          }

HashTable 直接使用对象的 hashCode ,代码是这样的:

public synchronized boolean containsKey(Object key) {

      Entry tab[] = table ;

      int hash = key.hashCode ();

      int index = (hash & 0x7FFFFFFF) % tab. length ;

      for (Entry<K,V> e = tab[index] ; e != null ; e = e. next ) {

          if ((e. hash == hash) && e. key .equals(key)) {

           return true ;

          }

      }

      return false ;

    }

 

引用自:http://www.99inf.net/SoftwareDev/Java/53925.htm

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值