论坛首页 Java企业应用论坛

HashMap hashCode奇怪的实现

浏览 3699 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-09-20   最后修改:2011-09-22

无意看群里有人讨论HashMap的hashCode,new出来的HashMap实例hashCode都是一样的。而且循环放入键值也还是一样,都是0.细看HashMap hashCode的实现,也就是它的父类AbstractMap的代码 :

public int hashCode() {
	int h = 0;
	Iterator<Entry<K,V>> i = entrySet().iterator();
	while (i.hasNext())
	    h += i.next().hashCode();
	return h;
}

 

 继续看Entry的hashCode:

public final int hashCode() {
            return (key==null   ? 0 : key.hashCode()) ^
                   (value==null ? 0 : value.hashCode());
}

 

 

由此就不难看出,当一个HashMap实例中,所存储的所有元素key value 对 的hashcode都相同时,那么这个HashMap的hashCode将恒为0,这不知道算不算得上一个bug.

 

测试代码:

 

		Map<String,String> map;
		for(int i=0;i<3;i++){
			map=new HashMap<String,String>();
			map.put(i+"", i+"");
			System.out.println(map.hashCode());
		}
		System.out.println("===========");
		for(int i=0;i<3;i++){
			map=new HashMap<String,String>();
			map.put(i+"", i+i+"");
			System.out.println(map.hashCode());
		}
 


   发表时间:2011-09-20  
有点意思。之前一直没有关注这个问题。但是说是bug,到未必。
如果map中所有的kv都是同一个值,在这种场景下,使用map作为数据结构本身就不合理。
0 请登录后投票
   发表时间:2011-09-20   最后修改:2011-09-20
stone2083 写道
有点意思。之前一直没有关注这个问题。但是说是bug,到未必。
如果map中所有的kv都是同一个值,在这种场景下,使用map作为数据结构本身就不合理。


不一定是同个值,可能存在这样的情况,
class User{
    private int id;
    public void hashCode(){
        return id;
    }
}

0 请登录后投票
   发表时间:2011-09-22  
hashCode即便相同又能说明什么呢?
0 请登录后投票
   发表时间:2011-09-22   最后修改:2011-09-22
Agrael 写道
hashCode即便相同又能说明什么呢?

是不会有啥严重问题,就是sun本身对hashcode定义中就轻描淡写的有这么一句:
It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.
0 请登录后投票
   发表时间:2011-09-22  
确实比较奇怪entry的hashcode为什么要这样写。XOR好像没什么必要吧?
0 请登录后投票
   发表时间:2011-09-22  
lydawen 写道
stone2083 写道
有点意思。之前一直没有关注这个问题。但是说是bug,到未必。
如果map中所有的kv都是同一个值,在这种场景下,使用map作为数据结构本身就不合理。


不一定是同个值,可能存在这样的情况,
class User{
    private int id;
    public void hashCode(){
        return id;
    }
}



这样写其实是有违反了java本身对于equals和hashcode的规定的。那就是如果两个对象not equals,那么它们的hashcode应该尽量不要保持一致。虽然没有强制规定保持不一致,但是不一致是能够提高hash的性能的。

所以,我觉得吧,这个算bug应该还谈不上,因为KV如果equals,如前面所说,用map做数据结构不合理,如果像你说这种情况,kv不equals但是hashcode是相等的,这种本身也不是推荐的方式。这也许算是hashmap一个有待提高的问题,当然我不太清楚Map.Entry这样实现是否还有其他的考虑。
0 请登录后投票
   发表时间:2011-09-22  
是挺奇怪的。、、、、
0 请登录后投票
   发表时间:2011-09-22  
lydawen 写道
Agrael 写道
hashCode即便相同又能说明什么呢?

是不会有啥严重问题,就是sun本身对hashcode定义中就轻描淡写的有这么一句:
It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.

+++++++
Long里面hashCode相同更多
0 请登录后投票
论坛首页 Java企业应用版

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