为什么不同的布尔实例的哈希代码总是相同的?
在下面的代码中,哈希码总是相同的。 为什么这样?
码:
public class BooleanClass { public static void main(String[] args) { Boolean b1 = new Boolean(true); Boolean b2 = new Boolean(false); Boolean b3 = new Boolean(true); Boolean b4 = new Boolean(false); Boolean b5 = new Boolean(false); Boolean b6 = new Boolean(true); System.out.println(b1.hashCode()); System.out.println(b2.hashCode()); System.out.println(b3.hashCode()); System.out.println(b4.hashCode()); System.out.println(b5.hashCode()); System.out.println(b6.hashCode()); } }
输出:
1231 1237 1231 1237 1237 1231
始终打印相同的号码1231
和1237
。 任何原因?
Boolean.hashCode()
方法的JavaDoc说:
如果此对象表示为
true
,则返回整数1231
; 如果此对象表示为false
则返回整数1237
。
hashCode()的合约是:
如果两个对象根据
equals(Object)
方法equals(Object)
,那么对这两个对象的每一个调用hashCode()
方法必须产生相同的整数结果。
而布尔值只有两个值, true
和false
,你只会得到两个不同的散列码。
直接从布尔类:
public int hashCode() { return ((this.value) ? 1231 : 1237); }
这是为布尔types生成哈希码的方法。 这就是为什么你总是得到相同的哈希码为true或false。
这是布尔的构造函数
public Boolean(boolean paramBoolean) { this.value = paramBoolean; }
所以this.value将是真或假,如果是真的,它会给1231,如果是假,它会给1237
哈希函数的要点是将任意长度的数据映射到固定长度的数据。 散列函数返回的值称为散列值,散列码,散列总和,校验和或简单散列。 如果input相同,散列函数将始终返回完全相同的散列值,因此散列true
将始终等于1231
并且散列false
将始终等于1237
如果你真的需要区分实例而不是值 – 这很less是你真正想要的,但偶尔会发生 – 参见IdentityHashMap
。
(本质上, IdentityHashMap
绕过对象的“真实”类中的.equals()
和.hashcode()
实现,并使用Object
那些实现。)
我不明白为什么这个问题引起如此多的关注。 否则,我会感到惊讶。 正如其他人所指出的那样,甚至在文件中也是如此。
但即使没有文档,也很容易理解原因:你可以只检查散列函数函数的定义。
散列函数是将任意长度的数据映射到固定长度的数据的algorithm。
而从math定义图是一个函数,这意味着相同的值将始终产生相同的值。
如果这不能帮助,你可以看看这个例子:
int a = 400; int b = 400;
你应该期望哈希值会有所不同吗? 很可能没有。 那么为什么它们在真假的情况下会有所不同呢?