java - 为什么默认的 Object.toString() 返回 hashCode 的十六进制表示?

标签 java hash tostring hashcode

我很好奇为什么 Object.toString() 返回这个:

return getClass().getName() + "@" + Integer.toHexString(hashCode());

与此相反:

return getClass().getName() + "@" + hashCode();

将哈希码显示为十六进制而不是十进制对您有什么好处?

最佳答案

简短的回答:

哈希码通常以十六进制显示,因为这样我们更容易将它们保留在我们的短期内存中,因为十六进制数字比十进制表示的相同数字更短且字符种类更多。

此外,(正如 supercat 在评论中所说的那样)十六进制表示往往会阻止人们尝试为数字分配一些含义,因为他们没有任何含义。 (以 supercat 为例,Fnord@194 绝对不是第 194 个 Fnord;它只是 Fnord 旁边有一些唯一编号。)

长答案:

十进制有两点方便:

  • 做算术
  • 估计震级

但是,这些操作不适用于哈希码。您当然不会在脑海中将哈希码加在一起,也不会关心一个哈希码与另一个哈希码相比有多大。

您可能使用哈希码做的事情是它们唯一的目的:判断两个哈希码是否可能引用同一对象,或者肯定引用不同的对象。

换句话说,您将使用它们作为对象的唯一标识符或助记符。因此,哈希码是一个数字这一事实实际上完全无关紧要;您不妨将其视为哈希字符串。

嗯,碰巧我们的大脑发现在短期内存中(为了比较)更容易保留由 16 个不同字符组成的短字符串,而不是仅由 10 个不同字符组成的较长字符串。

为了通过荒谬的方式进一步说明这个类比,想象一下如果哈希码用二进制表示,其中每个数字都比十进制长得多,并且字符种类要少得多。如果您现在看到散列码 010001011011100010100100101011,10 秒后再次看到,您是否有丝毫机会判断您正在查看相同的散列码? (我不能,即使我同时查看这两个数字。我必须逐个数字地比较它们。)

另一端是四六十进制编号系统,即以 64 为基数。该系统中的数字包括:

  • 数字 0-9,加上:
  • 大写字母 A-Z,加上:
  • 小写字母 a-z,加上:
  • 几个符号,如“+”和“/”,达到 64。

Tetrasexagesimal 显然比低位系统具有更多的字符多样性,并且用它表示的数字非常简洁也就不足为奇了。 (我不确定为什么 JVM 不使用这个系统作为哈希码;也许有些谨慎的人担心机会可能会导致形成某些不方便的四字母单词?)

因此,在具有 32 位对象哈希码的假设 JVM 上,“Foo”对象的哈希码可能类似于以下任何一种:

Binary:           com.acme.Foo@11000001110101010110101100100011
Decimal:          com.acme.Foo@3251989283
Hexadecimal:      com.acme.Foo@C1D56B23
Tetrasexagesimal: com.acme.Foo@31rMiZ

你更喜欢哪一个?

我肯定更喜欢四六十进制,如果没有,我会满足于十六进制。大多数人都会同意。

一个可以玩转换的网站在这里: https://www.mobilefish.com/services/big_number/big_number.php

关于java - 为什么默认的 Object.toString() 返回 hashCode 的十六进制表示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3736260/

相关文章:

java - JADE 平台的错误

architecture - Amazon S3 文件和路径命名架构决策

r - R中的单向哈希函数

java - Java中NodeList转字符串

java - Eclipse 不会覆盖括号

java - LWJGL - 隐藏时隐藏立方体面

java - 为什么 java ParNew 年轻代集合会通过 CMS 降级为单 CPU?

php - 散列 "remember me"cookie token 的最佳方法

java - Hibernate:将 toString() 类方法映射到 String db 列

java - 在很多实体中自动生成 toString 方法