我们先看2个类的定义

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

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

Hashtable的put方法如下

  1. public synchronized V put(K key, V value) {  //###### 注意这里1
  2. // Make sure the value is not null
  3. if (value == null) { //###### 注意这里 2
  4. throw new NullPointerException();
  5. }
  6. // Makes sure the key is not already in the hashtable.
  7. Entry tab[] = table;
  8. int hash = key.hashCode(); //###### 注意这里 3
  9. int index = (hash & 0x7FFFFFFF) % tab.length;
  10. for (Entry e = tab[index]; e != null; e = e.next) {
  11. if ((e.hash == hash) && e.key.equals(key)) {
  12. V old = e.value;
  13. e.value = value;
  14. return old;
  15. }
  16. }
  17. modCount++;
  18. if (count >= threshold) {
  19. // Rehash the table if the threshold is exceeded
  20. rehash();
  21. tab = table;
  22. index = (hash & 0x7FFFFFFF) % tab.length;
  23. }
  24. // Creates the new entry.
  25. Entry e = tab[index];
  26. tab[index] = new Entry(hash, key, value, e);
  27. count++;
  28. return null;
  29. }

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

  1. public V put(K key, V value) { //###### 注意这里 1
  2. if (key == null)  //###### 注意这里 2
  3. return putForNullKey(value);
  4. int hash = hash(key.hashCode());
  5. int i = indexFor(hash, table.length);
  6. for (Entry e = table[i]; e != null; e = e.next) {
  7. Object k;
  8. if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
  9. V oldValue = e.value;
  10. e.value = value;
  11. e.recordAccess(this);
  12. return oldValue;
  13. }
  14. }
  15. modCount++;
  16. addEntry(hash, key, value, i);  //###### 注意这里
  17. return null;
  18. }

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

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

                  HashMap                Hashtable

父类                  AbstractMap          Dictiionary

是否同步            否                            是

k,v可否null     是                            否

HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,

主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。

HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。

HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。

Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。

最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步(Collections.synchronizedMap)。

Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。

Hashtable和HashMap的区别举例的更多相关文章

  1. C# Hashtable 使用说明 以及 Hashtable和HashMap的区别

    一,哈希表(Hashtable)简述 在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似key/value的键值对,其 ...

  2. Java容器类List、ArrayList、Vector及map、HashTable、HashMap的区别与用法

    Java容器类List.ArrayList.Vector及map.HashTable.HashMap的区别与用法 ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数 ...

  3. HashTable, HashSet, HashMap的区别

    HashTable, HashSet, HashMap的区别     hash是一种很常见也很重要的数据结构,是用hash函数根据键值(key)计算出存储地址,以便直接访问.由完美hash函数(即键值 ...

  4. ConcurrentHashMap、HashTable、HashMap的区别

    HashTable与ConcurrentHashMap: 相同点:都是线程安全的,可以在多线程的环境下运行.key和value都不能为null 区别:性能上的差异.HashTable每次操作对象都会锁 ...

  5. HashTable和HashMap的区别详解(转)

    一.HashMap简介 HashMap是基于哈希表实现的,每一个元素是一个key-value对,其内部通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长. HashMap是非线程安全的, ...

  6. HashTable和HashMap的区别详解

    一.HashMap简介 HashMap是基于哈希表实现的,每一个元素是一个key-value对,其内部通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长. HashMap是非线程安全的, ...

  7. Java中HashTable和HashMap的区别

    在Java中,HashTable和HashMap都是哈希表,那么它们有什么区别呢?   1.它们所继承的类不一样. HashTable和HashMap都实现了Map接口,但是它们所继承的类时不同的.H ...

  8. hashTable 和 hashMap的区别

    HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,HashMap把Hashtable的contains方法去掉了,改成containsvalue和contai ...

  9. Vector和ArrayList的区别联系,Hashtable和HashMap的区别联系

    Vector.Hashtable是早期的集合类,线程安全,但是效率低下,被相同原理.结构的ArrayList.HashMap取代. 1.Vector和ArrayList的区别和联系: 联系:实现原理相 ...

随机推荐

  1. centos 网络配置

    centos 网络配置网络配置 -bash-4.1# setup    #如果没有setup命令,可以yum install setuptool -y  也可以安装setup 命令 http://ji ...

  2. Java关键字——transient

    当使用Serializable接口实现序列化操作时,如果一个对象中的某一属性不希望被序列化,则可以使用transient关键字进行声明 import java.io.File; import java ...

  3. JavaScript学习笔记——数组

    javascript数组数组是一个可以存储 一组 或是 一系列 相关数据 的 容器. 一.为什么要使用数组. (1)为了解决大量相关数据的存储和使用的问题. (2)模拟真是的世界. 二.如何创建数组 ...

  4. localdb

    <connectionStrings> - <add name="default" connectionString="Data Source=.; I ...

  5. 在Razor中如何引入命名空间?("import namespace in razor view") 【转】

    原文链接 找了半天,原来如此: 在aspx中: <%@ Import Namespace = "Martian.Areas.SFC.Models" %><%@ I ...

  6. Java调试

    线上load高的问题排查步骤是: 先用top找到耗资源的进程 ps+grep找到对应的java进程/线程 jstack分析哪些线程阻塞了,阻塞在哪里 jstat看看FullGC频率 jmap看看有没有 ...

  7. idea中的svn配置

    idea的使用之svn篇--有图超详细 http://ylq365.iteye.com/blog/1955291

  8. [C#]集合已修改;可能无法执行枚举操作

    摘要 我相信很多人对这个再熟悉不过了.对已经修改的集合进行操作就会出现这个错. 解决办法 比如有下面的一段代码,我们创建一个集合,并向集合中添加10个数,然后,我们循环再将这些数移除了. static ...

  9. 如何在editplus中配置ctags?

    首先要说明的是, 在editPlus中的ctags功能确实是没有 vs vim等中的好用. 最主要的原因 是它不能直接在文件中 跳转. 而是要通过一个另外的框来实现, 这就大大的降低了跳转的速度和使用 ...

  10. CF459C Pashmak and Buses (构造d位k进制数

    C - Pashmak and Buses Codeforces Round #261 (Div. 2) C. Pashmak and Buses time limit per test 1 seco ...