---------------------------------------------------------java
相信这个是你们最容易混淆的。安全
HashMap和Hashtable都实现了Map接口,但决定用哪个以前先要弄清楚它们之间的分别。主要的区别有:线程安全性,同步(synchronization),以及速度。多线程
HashMap
allows one null key and any number of null
values.,而Hashtable则不行)。这就是说,HashMap中若是在表中没有发现搜索键,或者若是发现了搜索键,但它是一个空的值,那么get()将返回null。若是有必要,用containKey()方法来区别这两种状况。要详细了解ConcurrentHashMap见《构建一个更好的 HashMap---ConcurrentHashMap》框架
1) sychronized意味着在一次仅有一个线程可以更改Hashtable。就是说任何线程要更新Hashtable时要首先得到同步锁,其它线程要等到同步锁被释放以后才能再次得到同步锁更新Hashtable。源码分析
2) Fail-safe和iterator迭代器相关。若是某个集合对象建立了Iterator或者ListIterator,而后其它的线程试图“结构上”更改集合对象,将会抛出ConcurrentModificationException异常。但其它线程能够经过set()方法更改集合对象是容许的,由于这并无从“结构上”更改集合。可是假如已经从结构上进行了更改,再调用set()方法,将会抛出IllegalArgumentException异常。性能
3) 结构上的更改指的是删除或者插入一个元素,这样会影响到map的结构。spa
---------------------------------------------------------.net
在分析他们的区别以前,咱们首先分别来简单介绍一下他们俩。(后面我会详细的结合源码分析他俩)线程
HashSet实现了Set接口,它不容许集合中有重复的值,当咱们提到HashSet时,第一件事情就是在将对象存储在HashSet以前,要先确保对象重写equals()和hashCode()方法,这样才能比较对象的值是否相等,以确保set中没有储存相等的对象。若是咱们没有重写这两个方法,将会使用这个方法的默认实现。详见《探索equals()和hashCode()方法》。code
public boolean add(Object o)方法用来在Set中添加元素,当元素值重复时则会当即返回false,若是成功添加的话会返回true。
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中。
*HashMap* | *HashSet* |
HashMap实现了Map接口 | HashSet实现了Set接口 |
HashMap储存键值对 | HashSet仅仅存储对象(且无重复对象) |
使用put()方法将元素放入map中 | 使用add()方法将元素放入set中 |
HashMap中使用键对象来计算hashcode值 | HashSet使用成员对象来计算hashcode值,对于两个对象来讲hashcode可能相同,因此equals()方法用来判断对象的相等性,若是两个对象不一样的话,那么返回false |
HashMap比较快,由于是使用惟一的键来获取对象 | HashSet较HashMap来讲比较慢 |