hashCode()和equals()方法的概念
1)如果两个对象根据相等(相等),则调用每个这两个对象的哈希码方法应当产生相同的散列码。
而另一种是
2)不要求是,如果两个对象根据等于()是不相等的,然后调用散列码方法在各两个对象的必须产生不同的值。
我尝试并理解第一个,这是第一点的代码。
public class Test {
public static void main(String[] args) {
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
map.put(1, 11);
map.put(4, 11);
System.out.println(map.hashCode());
Map<Integer, Integer> map1 = new HashMap<Integer, Integer>();
map1.put(1, 11);
map1.put(4, 11);
System.out.println(map1.hashCode());
if (map.equals(map1)) {
System.out.println("equal ");
}
}
}
上述程序给出了两个不同的对象相同的散列码。
有人可以解释我用一个例子,根据equals(这是不相等的)两个不同的对象怎么能有相同的哈希码。
2) 不要求是,如果两个对象根据等于()是不相等的 ,然后调用散列码方法在各两个对象的必须产生不同的值。
根据散列函数,2个不同的对象可以有相同的散列码。 然而,2个对象哪都一样必须产生相同的结果散列时(除非有人与实施随机数的散列函数在这种情况下也没用)
例如,如果我散列整数和我的哈希函数是简单的(n % 10)
则数字17
和数字27
会产生相同的结果。 这并不意味着,这些数字都是相同的。
例如用字符串(下面所有的字符串具有0的哈希码):
public static void main(String[] args) {
List<String> list = Arrays.asList("pollinating sandboxes",
"amusement & hemophilias",
"schoolworks = perversive",
"electrolysissweeteners.net",
"constitutionalunstableness.net",
"grinnerslaphappier.org",
"BLEACHINGFEMININELY.NET",
"WWW.BUMRACEGOERS.ORG",
"WWW.RACCOONPRUDENTIALS.NET",
"Microcomputers: the unredeemed lollipop...",
"Incentively, my dear, I don't tessellate a derangement.",
"A person who never yodelled an apology, never preened vocalizing transsexuals.");
for (String s : list) {
System.out.println(s.hashCode());
}
}
(被盗这篇文章 )。
的hashCode()具有32位的可能的值。 你的对象可以有比这更使你将有一些对象具有相同的hashCode,即你不能保证他们将是独一无二的。
这是一个规模有限的哈希值集合变得更糟。 HashMap中的最大容量为1 << 30或约十亿。 这就是说,只有30位是真正使用,如果您的收藏不使用16+ GB,并且只能说千桶(或1 << 10技术),那么你真的只有1000桶可能。
注:在热点JVM,默认的是Object.hashCode()从不为负,即只有31位,虽然我不知道为什么。
如果要产生大量具有相同的hashCode看龙的对象。
// from Long
public int hashCode() {
return (int)(value ^ (value >>> 32));
}
for(long i = Integer.MIN_VALUE; i < Integer.MAX_VALUE;i++) {
Long l = (i << 32) + i;
System.out.print(l.hashCode()+" ");
if (i % 100 == 0)
System.out.println();
}
这将产生4个十亿龙都为0的哈希码。
I'T很容易理解,如果你知道一个HashMap是如何实现的,它的目的。 一个HashMap取较大的值的集合,并且将它们分成更小的集合(桶)的元件的快得多检索。 基本上你只需要搜索一个水桶,而不是完整的列表你的元素。 桶是在阵列中,其中该索引是哈希码。 每个桶包含具有相同散列码的元素的链接列表,但是不相等()。 我认为,在Java中8他们交换了,当桶的大小变大使用树形图。
的目的hashCode
是让下面的公理和推论:
如果一个碰巧知道两个对象的哈希码,而这些散列码不匹配,一个不必理会检查对象的任何进一步知道该对象将不匹配。 即使两个任意挑选的非匹配对象必须具有匹配散列码的10%的机会,测试散列码将让一个消除90%,否则一个将需要比较的。 还不如一个大胜利,因为消除了99.99%,但绝对值得仍然。
知识没有在一堆的对象的具有特定的哈希码意味着没有在一堆对象将匹配与散列码的对象。 如果一个分区对象的集合到那些散列码是偶数,那些散很奇怪,一个想找到一个人是否有其哈希码正好是连一个给定的项目,就没有需要检查什么在奇数散列项目的集合。 同样就没有必要寻找一个奇数哈希项目甚至哈希收藏。 即使是两个散列值可以通过几乎一半从而加快搜索速度。 如果一个人把一个集合到较小的分区,可以进一步加快速度。
需要注意的是hashCode()
,如果每个不同的项目将返回不同的散列将提供最大的利益,但它可以提供巨大的好处,即使许多项目具有相同的哈希值。 90%的储蓄和储蓄99.99%之间的差别往往是远远大于该数字将表明,这样一个如果能合理地容易改善的事情到99%,99.9%,或更好的应该这样做,但他之间的差异具有零场误报比赛和集合中有几个错误的匹配是相当轻微。
这其实很简单,
首先我们要知道一个哈希码是什么。
在Java中,一个散列码是简单一个32位有符号整数,它以某种方式从所讨论的数据的。 整数类型通常是刚刚(int数据)MOD(一些合理的大素数)。
让我们做一个简单的哈希上的整数。
限定:
public int hash(int num){ return num % 19 ; }
在这种情况下,既图19和38将返回0的散列值。
为字符串类型,散列从单个字符和字符串中的每个位置的人,通过一个相当大的数量除以衍生。 (或者,在Java的情况下,忽略了一个32位的总和溢出)。
鉴于有可能任意地许多字符串,且有散列码(2 ^ 32),用于串的数量有限,鸽子洞原理阐明,有导致相同的散列码的至少两个不同的字符串。
Actullay,此链接解释是否哈希码等于更清楚发生了什么。
http://www.javamadesoeasy.com/2015/02/hashmap-custom-implementation.html
我的理解是,hashCode与内存地址的数字表示,而不是实际的地址。 它是可以改变的,不影响实际地址。 因此,它应该是可以将所有对象设置为相同的hashCode,即使他们都是完全不同的事情。 大家对一个块突然所有具有相同街道地址想想。 他们是真正的不同的人,但现在都有着相同的街道地址。 他们的房子没动,一个mischevious青少年只是标示大家为“100 N.主”。
我非常新的Java,所以把我的回答带着几分谨慎。