HashMap与HashTable的区别

来源:互联网 发布:windows office 2013 编辑:程序博客网 时间:2024/06/06 01:18

一 、Hashing概念


是一种将字符组成的字符串转换为固定长度(一般是更短长度)的数值或索引值的方法,称为哈希法。

二 、HashMap


1 概述

(1)HashMap是基于hash表的Map接口的非同步实现(非线程安全在多线程环境下需要手动同步)在单线程下效率较高。
(2)元素是键值对(key-value)的形式,允许key,value为null类型。
(3)不保证映射的顺序,并且也不保证映射顺序的恒久不变。
(4)继承了AbstractMap类
(5)数据结构:hash表(数组与链表的结合体)。hashMap底层就是一个数组,而每个数组中又包含了一个链表
  hash表特点:结合了数组与链表的优点,做出了一种寻址容易,插入删除也容易的数据结构。从而使得查询方便,同时又不会占用太大   内存空间。 

工作原理

使用put(key,value)方法存储对象到HashMap中,
使用get(key)方法获取HashMap中的对象。
在存储的过程中会通过key的hashCode值与Entry数组长度取模计算出下标(这个下标也就是键值对对象在Entry数组中对应的位置,当多个下标相同的元素存储在同一个数组位置时就形成了一张链表)。在使用put方法的过程中如果key在链表中已经存(通过hashCode与equals方法进行判断)在则会将key对应的value替换为最新的。(备注:若两个对象相同则对应的hash值一定相同,反之hash值相同的两个对象不一定相同)


扩展:http://blog.csdn.net/vking_wang/article/details/14166593  http://www.importnew.com/7099.html
补充源码分析:------
http://www.cnblogs.com/chenssy/p/3521565.html

3 HashMap中解决碰撞的方法?

(1)由于不同的键值对对象在通过hash算法计算时,可能会得到相同的hashCode,在这种情况下会产生HashCode的碰撞。
(2)HashMap通过链表的方式来解决碰撞问题,当碰撞产生时,HashMap会将产生碰撞的对象存储在同一个bucket(哈希桶)位置的          链表中。在取碰撞对象 的时候通过equals()与hashCode()方法结合使用

三、Hashtable


(1)Hashtable是基于hash表的Map接口的同步实现。(线程安全适用于多线程环境,在这种情况下会导致效率降低)
(2)元素也是键值对的形式,不允许key,value为null类型。
(3)继承了Dictionary类


四、HashMap与HashTable的同步实现?


(1)HashMap是非sychronized的,如果在多线程中使用HashMap可以使用sychronizedMap方法返回一个同步版本的hashMap,在这个版本中的每个方法都进行了同步,但是并不能说明整个类就是线程安全的。介于这个问题的存在jdk1.5以后提供了一个更好的选择:ConcurrentHashMap。使用如下:

  1. Map<String,String> h = Collections.synchronizedMap(hashMap);


sychronizedMap方法说明: 

  1. if(shm.containsKey('key')){
  2. shm.remove(key);
  3. }

a.这段代码shm是sychronizedMap的实例用于从map中删除一个元素之前判断是否存在这个元素。这里的 containsKey和reomve方法都是同步的,但是整段代码却不是。考虑这么一个使用场景:线程A执行了containsKey方法返回 true,准备执行remove操作;这时另一个线程B开始执行,同样执行了containsKey方法返回true,并接着执行了remove操作;然 后线程A接着执行remove操作时发现此时已经没有这个元素了。要保证这段代码按我们的意愿工作,一个办法就是对这段代码进行同步控制,但是这么做付出 的代价太大。


ConcurrentHashMap类说明(简述):

a.提供了不同于Hashtable与HashMap中sychronizedMap的锁机制:Hashtable采用的是一次性锁住整个hash表,从而保证一次只能有一个线程进行操作。而ConcurrentHashMap中则是 一次锁住一个桶。ConcurrentHashMap默认将hash表分为16个桶诸如get,put,remove等常用操作只锁当前需要用到的桶。 这样,原来只能一个线程进入,现在却能同时有16个写线程进入(写线程才需要锁,读线程几乎不受限制),并发性能的提升是显而易见的。

(2)Hashtable是线程同步的但是在多线程竞争激烈的情况下会Hashtable效率会很低下。因为当线程1在访问Hashtable的同步方法时,其他线程再来访问Hashtable的方法时,可能会陷入阻塞或轮询状态(多个线程竞争同一把锁导致效率底下)。如:当1线程在使用put方法添加元素的时候,2线程不能使用put方法,而且也不能使用get方法获取元素。


原创粉丝点击