字符串不变性的优点之一是哈希码缓存以加快访问速度。
- 在这种情况下,如何为具有相同哈希码的字符串处理缓存?
- 在这种情况下,它真的能提高性能吗?
在这种情况下,如何为具有相同哈希码的字符串处理缓存?
缓存的是字符串的哈希码。它缓存在int
字符串本身的私有字段中。不同的字符串可能具有相同的哈希码没有任何区别......因为哈希码存储在各自的字符串对象中。
(最重要的是具有相同字符序列(因此是equal
)的两个字符串具有相同的哈希码值。这是可以保证的,因为 Java 字符串的哈希码算法是标准化的......并且具有此属性。)
在这种情况下,它真的能提高性能吗?
平均而言,是的,并且随着字符串长度变大而更多。
一个像样的字符串哈希码算法需要查看字符串中的每个字符......否则相似的字符串最终可能会系统地映射到相同的哈希码(这很糟糕)。避免多次查看这 N 个字符是一个巨大的胜利。
缓存无济于事的唯一重要情况是:
(还有一个非常模糊的情况。如果String
哈希到0
,那么缓存将无效。这是因为String
该类0
在缓存字段中使用表示哈希码尚未缓存。)
在这种情况下,如何为具有相同哈希码的字符串处理缓存?
我不明白你问题的第一部分。缓存对所有字符串的处理都是相同的,无论哈希码是否相同(因为理论上两个不同的字符串可以具有相同的哈希码,因此如果哈希码相等,并不意味着字符串相等)。但如果使用相同的 String对象,hashCode 不必重新计算,因为它已被缓存。
它真的能提高性能吗?
绝对是的
缓存只是 String 对象中的一个 int 字段。多个字符串可以毫无问题地具有相同的哈希码。
它显着提高了性能,因为:
有兴趣的可以看看源码:
在大多数情况下,在您尝试将字符串放入 HashMap 之前,不会计算 hashCode。然后地图将其缓存在 Map.Entry 中,以加快比较和重新散列。
对于第一个,这取决于您的哈希策略。例如,如果将一个单词的所有字母的 ascii 代码加在一起作为该字母的哈希码(a 为 65,A 为 97),在这种情况下,单词“abc”和“bca”具有相同的哈希码。
对于第二个,它也取决于您的哈希策略,但在大多数情况下,答案是肯定的。