论坛首页 Java企业应用论坛

HashMap中的元素玩起了躲猫猫

浏览 7859 次
精华帖 (1) :: 良好帖 (6) :: 新手帖 (2) :: 隐藏帖 (5)
作者 正文
   发表时间:2011-06-16  
HashMap是非线程安全的。

试下用ConcurrentHashMap吧。
0 请登录后投票
   发表时间:2011-06-16  
楼主只是解释说明一个现象的背后产后的原因,至于为什么不安全用什么安全这个大家都是知道的,呵呵,支持
0 请登录后投票
   发表时间:2011-06-17  
tianzizhi 写道
楼主只是解释说明一个现象的背后产后的原因,至于为什么不安全用什么安全这个大家都是知道的,呵呵,支持


终于有个明白人
0 请登录后投票
   发表时间:2011-06-17  
freish 写道
handby123 写道
看到这我突然想弱弱地问一句:很看到几次HASHMAP通过KEY查找值得时间复杂度为O(1)
然我疑惑的是 get()方法中不是也先要遍历table数组么 难道这不算时间复杂度?

是不用遍历table数组的,数组的下标是通过indexFor迅速定位的,但是table中的元素是一个链表,如果hash的加载因子太大,就有可能出现很多元素hash得到的table索引是一样的,这就需要遍历这个链表了


通常你给一个key,通过其hashCode 值 然后 indexFor 就可以计算出其数组下标,直接定位到该元素
static int indexFor(int h, int length) {
   return h & (length-1);
}

但是 不同对象的hashCode 有可能一样,所以HashMap 中 每个key 对应的是一个链表,当两个不同key 的hashCode 相同时,那么就放入到对应的同一个链表里,当你取的时候,根据key的hashCode定位到这个链表(链表中存的是 Entry<K,V> 对象),遍历然后逐个equals key 直到找到元素(不同对象equals绝对是false)。

假如一个链表 你直接遍历 那么当链表非常大的时候,会非常慢的,但一般情况下不同对象的hashCode值是不同的,根据hashCode 和 indexFor() 直接就能找到该元素的索引,然后直接就取出来了,万一hashCode 相同,仅需要遍历一个相对小的链表即可。

所以
  1.当你 需要存取大量元素的时候,运用 hashMap 这类集合 自然比较高效
  2.当你定义一个class的时候,假如需要重写 hashCode 和 equals 方法的时候要注意这两个方法
0 请登录后投票
   发表时间:2011-06-17  
renwolang521 写道
freish 写道
handby123 写道
看到这我突然想弱弱地问一句:很看到几次HASHMAP通过KEY查找值得时间复杂度为O(1)
然我疑惑的是 get()方法中不是也先要遍历table数组么 难道这不算时间复杂度?

是不用遍历table数组的,数组的下标是通过indexFor迅速定位的,但是table中的元素是一个链表,如果hash的加载因子太大,就有可能出现很多元素hash得到的table索引是一样的,这就需要遍历这个链表了


通常你给一个key,通过其hashCode 值 然后 indexFor 就可以计算出其数组下标,直接定位到该元素
static int indexFor(int h, int length) {
   return h & (length-1);
}

但是 不同对象的hashCode 有可能一样,所以HashMap 中 每个key 对应的是一个链表,当两个不同key 的hashCode 相同时,那么就放入到对应的同一个链表里,当你取的时候,根据key的hashCode定位到这个链表(链表中存的是 Entry<K,V> 对象),遍历然后逐个equals key 直到找到元素(不同对象equals绝对是false)。

假如一个链表 你直接遍历 那么当链表非常大的时候,会非常慢的,但一般情况下不同对象的hashCode值是不同的,根据hashCode 和 indexFor() 直接就能找到该元素的索引,然后直接就取出来了,万一hashCode 相同,仅需要遍历一个相对小的链表即可。

所以
  1.当你 需要存取大量元素的时候,运用 hashMap 这类集合 自然比较高效
  2.当你定义一个class的时候,假如需要重写 hashCode 和 equals 方法的时候要注意这两个方法



在定义好hashCode和equals方法后,加载因子就是一个重要因素,加载因子越大,重复的可能性就越大,但table数组的利用率越高;加载因子越小,重复的可能性越小,但table数组很多空间被浪费掉了。需要在时间和空间上有一个折中
0 请登录后投票
   发表时间:2011-06-17  
一直么有研究过,哈哈,看完QQ再看。
0 请登录后投票
   发表时间:2011-06-17  
kingkan 写道
HashMap是非线程安全的。

试下用ConcurrentHashMap吧。


楼上说的对,在多线种情况下对一个线程不安全的容器进行操作显然是不对的.还是用ConcurrentHashMap这个比较好 或者Collections.synchronizedMap(map).
0 请登录后投票
   发表时间:2011-06-18  
jv520jv 写道
kingkan 写道
HashMap是非线程安全的。

试下用ConcurrentHashMap吧。


楼上说的对,在多线种情况下对一个线程不安全的容器进行操作显然是不对的.还是用ConcurrentHashMap这个比较好 或者Collections.synchronizedMap(map).

Collections.synchronizedMap(map)这个更好用些
0 请登录后投票
   发表时间:2011-06-18  
ConcurrentHashMap
Collections.synchronizedMap(map).

这俩不是一个等级的,
第一个是局部加锁,
第二个是整体加锁,
效率差很多
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics