HashTable,HashMap和HashSet比较

 

1. HashTable和HashMap的区别

---------------------------------------------------------java

相信这个是你们最容易混淆的。安全

 

HashMap和Hashtable都实现了Map接口,但决定用哪个以前先要弄清楚它们之间的分别。主要的区别有:线程安全性同步(synchronization),以及速度多线程

  1. HashMap几乎能够等价于Hashtable,除了HashMap是非synchronized的,并能够接受null(HashMap allows one null key and any number of null values.,而Hashtable则不行)。这就是说,HashMap中若是在表中没有发现搜索键,或者若是发现了搜索键,但它是一个空的值,那么get()将返回null。若是有必要,用containKey()方法来区别这两种状况。
  2. HashMap是非synchronized,而Hashtable是synchronized,这意味着Hashtable是线程安全的,多个线程能够共享一个Hashtable;而若是没有正确的同步的话,多个线程是不能共享HashMa的。 便是说,在多线程应用程序中,不用专门的操做就安全地可使用Hashtable了;而对于HashMap,则须要额外的同步机制。但HashMap的同步问题可经过Collections的一个静态方法获得解决:
                Map Collections.synchronizedMap(Map m)
    这个方法返回一个同步的Map,这个Map封装了底层的HashMap的全部方法,使得底层的HashMap即便是在多线程的环境中也是安全的。                                                                                              而并且
    Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。

    要详细了解ConcurrentHashMap见《构建一个更好的 HashMap---ConcurrentHashMap框架

  1. 另外一个区别是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。因此当有其它线程改变了HashMap的结构(增长或者移除元素),将会抛出ConcurrentModificationException,但迭代器自己的remove()方法移除元素则不会抛出ConcurrentModificationException异常。但这并非一个必定发生的行为,要看JVM。这条一样也是Enumeration和Iterator的区别。
  2. 因为Hashtable是线程安全的也是synchronized,因此在单线程环境下它比HashMap要慢。若是你不须要同步,只须要单一线程,那么使用HashMap性能要好过Hashtable。
  3. HashMap不能保证随着时间的推移Map中的元素次序是不变的。
  4. 哈希值的使用不一样,HashTable直接使用对象的hashCode,代码是这样的:
          int hash = key.hashCode();
          int index = (hash & 0x7FFFFFFF) % tab.length;
    而HashMap从新计算hash值,并且用与代替求模:
    int hash = hash(k);
    int i = indexFor(hash, table.length);

 

 

要注意的一些重要术语:

1) sychronized意味着在一次仅有一个线程可以更改Hashtable。就是说任何线程要更新Hashtable时要首先得到同步锁,其它线程要等到同步锁被释放以后才能再次得到同步锁更新Hashtable。源码分析

2) Fail-safe和iterator迭代器相关。若是某个集合对象建立了Iterator或者ListIterator,而后其它的线程试图“结构上”更改集合对象,将会抛出ConcurrentModificationException异常。但其它线程能够经过set()方法更改集合对象是容许的,由于这并无从“结构上”更改集合。可是假如已经从结构上进行了更改,再调用set()方法,将会抛出IllegalArgumentException异常。性能

3) 结构上的更改指的是删除或者插入一个元素,这样会影响到map的结构。spa

 

2. HashSet和HashMap的区别

---------------------------------------------------------.net

在分析他们的区别以前,咱们首先分别来简单介绍一下他们俩。(后面我会详细的结合源码分析他俩)线程

 

什么是HashSet?

 

HashSet实现了Set接口,它不容许集合中有重复的值,当咱们提到HashSet时,第一件事情就是在将对象存储在HashSet以前,要先确保对象重写equals()和hashCode()方法,这样才能比较对象的值是否相等,以确保set中没有储存相等的对象。若是咱们没有重写这两个方法,将会使用这个方法的默认实现。详见《探索equals()和hashCode()方法》。code

public boolean add(Object o)方法用来在Set中添加元素,当元素值重复时则会当即返回false,若是成功添加的话会返回true。

 

什么是HashMap?

HashMap实现了Map接口,Map接口对键值对进行映射。Map中不容许重复的键。Map接口有两个基本的实现,HashMap和TreeMap。TreeMap保存了对象的排列次序,而HashMap则不能。HashMap容许键和值为null。HashMap是非synchronized的,但collection框架提供方法能保证HashMap synchronized,这样多个线程同时访问HashMap时,能保证只有一个线程更改Map。

public Object put(Object Key,Object value)方法用来将元素添加到map中。

HashSet和HashMap的区别

*HashMap* *HashSet*
HashMap实现了Map接口 HashSet实现了Set接口
HashMap储存键值对 HashSet仅仅存储对象(且无重复对象)
使用put()方法将元素放入map中 使用add()方法将元素放入set中
HashMap中使用键对象来计算hashcode值 HashSet使用成员对象来计算hashcode值,对于两个对象来讲hashcode可能相同,因此equals()方法用来判断对象的相等性,若是两个对象不一样的话,那么返回false
HashMap比较快,由于是使用惟一的键来获取对象 HashSet较HashMap来讲比较慢
相关文章
相关标签/搜索