问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

hashCode方法怎么用?

发布网友 发布时间:2022-04-27 00:43

我来回答

3个回答

热心网友 时间:2022-06-21 21:36

对于包含容器类型的程序设计语言来说,基本上都会涉及到hashCode。在Java中也一样,hashCode方法的主要作用是为了配合基于散列的集合一起正常运行,这样的散列集合包括HashSet、HashMap以及HashTable。
  为什么这么说呢?考虑一种情况,当向集合中插入对象时,如何判别在集合中是否已经存在该对象了?(注意:集合中不允许重复的元素存在)
  也许大多数人都会想到调用equals方法来逐个进行比较,这个方法确实可行。但是如果集合中已经存在一万条数据或者更多的数据,如果采用equals方法去逐一比较,效率必然是一个问题。此时hashCode方法的作用就体现出来了,当集合要添加新的对象时,先调用这个对象的hashCode方法,得到对应的hashcode值,实际上在HashMap的具体实现中会用一个table保存已经存进去的对象的hashcode值,如果table中没有该hashcode值,它就可以直接存进去,不用再进行任何比较了;如果存在该hashcode值, 就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址,所以这里存在一个冲突解决的问题,这样一来实际调用equals方法的次数就大大降低了,说通俗一点:Java中的hashCode方法就是根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,这个数值称作为散列值。下面这段代码是java.util.HashMap的中put方法的具体实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}

modCount++;
addEntry(hash, key, value, i);
return null;
}

  put方法是用来向HashMap中添加新的元素,从put方法的具体实现可知,会先调用hashCode方法得到该元素的hashCode值,然后查看table中是否存在该hashCode值,如果存在则调用equals方法重新确定是否存在该元素,如果存在,则更新value值,否则将新的元素添加到HashMap中。从这里可以看出,hashCode方法的存在是为了减少equals方法的调用次数,从而提高程序效率。
  如果对于hash表这个数据结构的朋友不清楚,可以参考这几篇博文;
  http://www.cnblogs.com/jiewei915/archive/2010/08/09/1796042.html
  http://www.cnblogs.com/dolphin0520/archive/2012/09/28/2700000.html
  http://www.java3z.com/cwbwebhome/article/article8/83560.html?id=4649
  有些朋友误以为默认情况下,hashCode返回的就是对象的存储地址,事实上这种看法是不全面的,确实有些JVM在实现时是直接返回对象的存储地址,但是大多时候并不是这样,只能说可能存储地址有一定关联。下面是HotSpot JVM中生成hash散列值的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

static inline intptr_t get_next_hash(Thread * Self, oop obj) {
intptr_t value = 0 ;
if (hashCode == 0) {
// This form uses an unguarded global Park-Miller RNG,
// so it's possible for two threads to race and generate the same RNG.
// On MP system we'll have lots of RW access to a global, so the
// mechanism inces lots of coherency traffic.
value = os::random() ;
} else
if (hashCode == 1) {
// This variation has the property of being stable (idempotent)
// between STW operations. This can be useful in some of the 1-0
// synchronization schemes.
intptr_t addrBits = intptr_t(obj) >> 3 ;
value = addrBits ^ (addrBits >> 5) ^ GVars.stwRandom ;
} else
if (hashCode == 2) {
value = 1 ; // for sensitivity testing
} else
if (hashCode == 3) {
value = ++GVars.hcSequence ;
} else
if (hashCode == 4) {
value = intptr_t(obj) ;
} else {
// Marsaglia's xor-shift scheme with thread-specific state
// This is probably the best overall implementation -- we'll
// likely make this the default in future releases.
unsigned t = Self->_hashStateX ;
t ^= (t << 11) ;
Self->_hashStateX = Self->_hashStateY ;
Self->_hashStateY = Self->_hashStateZ ;
Self->_hashStateZ = Self->_hashStateW ;
unsigned v = Self->_hashStateW ;
v = (v ^ (v >> 19)) ^ (t ^ (t >> 8)) ;
Self->_hashStateW = v ;
value = v ;
}

value &= markOopDesc::hash_mask;
if (value == 0) value = 0xBAD ;
assert (value != markOopDesc::no_hash, "invariant") ;
TEVENT (hashCode: GENERATE) ;
return value;
}

  该实现位于hotspot/src/share/vm/runtime/synchronizer.cpp文件下。
  因此有人会说,可以直接根据hashcode值判断两个对象是否相等吗?肯定是不可以的,因为不同的对象可能会生成相同的hashcode值。虽然不能根据hashcode值判断两个对象是否相等,但是可以直接根据hashcode值判断两个对象不等,如果两个对象的hashcode值不等,则必定是两个不同的对象。如果要判断两个对象是否真正相等,必须通过equals方法。
  也就是说对于两个对象,如果调用equals方法得到的结果为true,则两个对象的hashcode值必定相等;
  如果equals方法得到的结果为false,则两个对象的hashcode值不一定不同;
  如果两个对象的hashcode值不等,则equals方法得到的结果必定为false;
  如果两个对象的hashcode值相等,则equals方法得到的结果未知。

热心网友 时间:2022-06-21 21:36

等的。
那你会说,不是还有equals这个方法吗?

不错,这2个方法都是用来判断2个对象是否相等的。但是他们是有区别的。

一般来讲,equals这个方法是给用户调用的,如果你想判断2个对象是否相等,你可以重写equals方法,然后在代码中调用,就可以判断他们是否相等了。简单来讲,equals方法主要是用来判断从表面上看或者从内容上看,2个对象是不是相等。举个例子,有个学生类,属性只有姓名和性别,那么我们可以认为只要姓名和性别相等,那么就说这2个对象是相等的。

hashcode方法一般用户不会去调用,比如在hashmap中,由于key是不可以重复的,他在判断key是不是重复的时候就判断了hashcode这个方法,而且也用到了equals方法。这里不可以重复是说equals和hashcode只要有一个不等就可以了!所以简单来讲,hashcode相当于是一个对象的编码,就好像文件中的md5,他和equals不同就在于他返回的是int型的,比较起来不直观。我们一般在覆盖equals的同时也要覆盖hashcode,让他们的逻辑一致。举个例子,还是刚刚的例子,如果姓名和性别相等就算2个对象相等的话,那么hashcode的方法也要返回姓名的hashcode值加上性别的hashcode值,这样从逻辑上,他们就一致了。

要从物理上判断2个对象是否相等,用==就可以了。
另外,团IDC网上有许多产品团购,便宜有口碑

热心网友 时间:2022-06-21 21:37

hashcode这个方法是用来鉴定2个对象是否相等的。
那你会说,不是还有equals这个方法吗?

不错,这2个方法都是用来判断2个对象是否相等的。但是他们是有区别的。

一般来讲,equals这个方法是给用户调用的,如果你想判断2个对象是否相等,你可以重写equals方法,然后在代码中调用,就可以判断他们是否相等了。简单来讲,equals方法主要是用来判断从表面上看或者从内容上看,2个对象是不是相等。举个例子,有个学生类,属性只有姓名和性别,那么我们可以认为只要姓名和性别相等,那么就说这2个对象是相等的。

hashcode方法一般用户不会去调用,比如在hashmap中,由于key是不可以重复的,他在判断key是不是重复的时候就判断了hashcode这个方法,而且也用到了equals方法。这里不可以重复是说equals和hashcode只要有一个不等就可以了!所以简单来讲,hashcode相当于是一个对象的编码,就好像文件中的md5,他和equals不同就在于他返回的是int型的,比较起来不直观。我们一般在覆盖equals的同时也要覆盖hashcode,让他们的逻辑一致。举个例子,还是刚刚的例子,如果姓名和性别相等就算2个对象相等的话,那么hashcode的方法也要返回姓名的hashcode值加上性别的hashcode值,这样从逻辑上,他们就一致了。

要从物理上判断2个对象是否相等,用==就可以了。

参考资料:http://zhidao.baidu.com/question/97910305.html

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
怎么考经纪人 如何去除白墙上的彩笔字 消除墙上彩笔的小妙招 保健器械 淘宝:淘宝网上卖的medex护腰,护膝,护腕 等医疗器械、是不是... 淘宝上有卖沃尔康护腰的吗?有链接吗? 跪求 黄家强 清唱吧《海阔天空》 96年、黄家强唱的祝你愉快,海阔天空在哪可以下载? 黄家强1996年唱的海阔天空MP3哪有下载啊? 朱关田作品 书画名家朱关田 朱关田代表作 【欣赏 价格 图片 鉴定... 用肝病冷藏食品比用冰好的理由是 杜长明相关成果 跪求2020年搞笑电影排行榜前十名,【在线观看】免费百度云资源 盘点20年搞笑电影,【在线观看】免费百度云资源 盘点有关芭蕾舞的电影动漫片,【免费高清】在线观看百度网盘资源 跪求2020年喜剧电影,【免费高清】在线观看百度网盘资源 【合集】芭蕾舞的电影,【免费高清】在线观看百度网盘资源 盘点2020喜剧电影排行榜前十名,【在线观看】免费百度云资源 盘点2020喜剧电影推荐,【免费高清】在线观看百度网盘资源 盘点2020年喜剧电影排行榜,【免费高清】在线观看百度网盘资源 跪求搞笑电影2020,【在线观看】免费百度云资源 go语言的垃圾回收有隐患吗 为什么sim卡不可以用流量?明明已经充了流量了啊。 手机卡用不起流量怎么回事 Go 的垃圾回收机制在实践中有哪些需要注意的地方 放了手机卡用不了流量? 求教java中的unsafe.allocateMemory 会导致内存申请失败吗 新换的手机卡不能用流量上网,通话短信都是正常的 打电话人工服务也_百 ... java中垃圾回收器让工作线程停顿下来是怎么做的? 手机卡有钱用不了流量 jvm什么时候会触发full gc? 为什么手机上了手机卡用不了流量 跪求芭蕾舞电影有哪些,【在线观看】免费百度云资源 LED的高亮与普亮怎么检测? LED屏幕亮度判断方法解析是什么? 怎样有效地测试led显示屏 有哪种仪器可以测试LED灯的亮度是否符合标准? 怎么检测LED灯具的亮度 如何用iCAT LED自动化测试仪完成LED颜色及亮度的自动化测试? LED显示屏测试亮度如何通过X坐标y坐标来计算亮度? LED的亮度是怎么测量的呀? 高亮度和低亮度led灯有什么区别? vivox50pro+里面的隐藏应用怎么解除隐藏?? 任达华和温碧霞拍的上床戏的电影叫什么名子 一部任达华*温碧霞并杀死温碧霞的未婚夫,同时和温碧霞有床戏,请问是什么电影,告诉一下 《出埃及记》我没看懂!到底是什么意思呀! 求任达华影片 他在里面是好人 做过监狱 期间花心老婆出轨 出来后和一个善良的女老师好上 最后打架有硫酸 隐藏20年,任达华老婆终曝光,网友:难怪不选全智贤温碧霞,所以她是谁? 广西梧州也是一个说粤语的地方吗? 梧州人对广东为什么有一种特殊的感情 电梯直流门机系统工作原理图(电器部分) 梧州距离珠三角很远,为何当地却是广府文化发源地?