有什么原因无法使用 Java 字符串的 hashCode 方法来测试其相等性吗?所以基本上,而不是......

"hello".equals("hello")

你可以用...

"hello".hashCode() == "hello".hashCode()

这将很有用,因为一旦字符串计算出它的哈希码,那么比较字符串将与比较 int 一样有效,因为字符串会缓存哈希码,并且如果您设计它,那么该字符串很可能位于字符串池中方式。

有帮助吗?

解决方案

,因为:两个对象的散列码必须相等,如果对象是相等的,但是,如果两个对象是不相等的,哈希码仍然可以等于

(评论后修饰的)

其他提示

让我给你举一个反例。尝试此,

public static void main(String[] args) {
    String str1 = "0-42L";
    String str2 = "0-43-";

    System.out.println("String equality: " + str1.equals(str2));
    System.out.println("HashCode eqauality: " + (str1.hashCode() == str2.hashCode()));
}

在我的Java结果,

String equality: false
HashCode eqauality: true

许多所述的hashCode并不保证唯一性。 事实上,它不能这样做,对于很简单的原因。

的hashCode返回int,这意味着有2 ^ 32个可能的值(约40亿),但也有一定大于2 ^ 32个可能的字符串,这意味着至少两个串具有相同的哈希码值。

这是称为鸽巢原理

其他人指出了为什么它不起作用。所以我只是添加一个附录,无论如何增益都是最小的。

当您在 Java 中比较两个字符串时,String equals 函数首先检查它们是否是对同一对象的两个引用。如果是,则立即返回 true。然后它检查长度是否相等。如果不是,则返回 false。只有这样它才会开始逐个字符进行比较。

如果您在内存中操作数据,则相同对象比较可以快速处理“相同”情况,我认为这是一个快速、嗯、4 字节整数比较。(如果我的对象句柄长度错误,有人会纠正我。)

对于大多数不相等的字符串,我敢打赌长度比较很快就会发现它们不相等。如果您要比较两个事物的名称——客户、城市、产品等等——它们的长度通常不相等。所以一个简单的 int 比较可以快速处理掉它们。

最糟糕的性能情况是两个长的、相同但不相同的对象字符串。然后它必须进行对象句柄比较,为假,继续检查。长度比较,真实,继续检查。然后逐个字符地遍历字符串的整个长度,以验证它们确实是相等的,直到最后。

您可以得到你想要使用String.intern()的效果(这是使用哈希表来实现。)

您可以使用intern()操作比较==的返回值。如果它们是指相同的字符串,则原来的字符串被等效(即equals()将返回true),它仅需要一个指针比较(其具有相同的成本作为int比较)。

String a = "Hello";
String b = "Hel" + "lo";

System.out.println(a.equals(b));
System.out.println(a == b);

String a2 = a.intern();
String b2 = b.intern();

System.out.println(a2.equals(b2));
System.out.println(a2 == b2);

输出:

true
false
true
true

的哈希码值不是唯一的,这意味着字符串实际上可能不匹配。为了提高性能,往往平等的实现将进行更费力的检查之前执行一个hashCode检查。

原因很简单:冲突的风险... 哈希码会比一个字符串可能值少了很多。这取决于有点那种你生成散列的,但让我们一个很简单的例子,在那里你会增加字母的顺序值,乘以它的位置是:A = 1,B = 2,等等。因此,“你好”会翻译成: H:8X1 = 8,E:5×2 = 10,L:12x3 = 36,L:12×4 = 48,O:15x5 = 75。 8 + 10 + 36 + 48 + 75 = 177。

是否有可能最终作为177散列其它字符串值?当然!大量的选项。随意计算几

不过,这散列方法中使用的简单方法。 Java和.NET使用更复杂的哈希算法这种碰撞的小了很多机会。但尽管如此,有一个机会,两种不同的串将导致相同的散列值,因此该方法是不太可靠的。

两个不同的字符串可以很容易地生成相同的散列码或不同的散列码。 如果妳想要一个平等的测试散列码不会给一个唯一的结果。当我们使用String类将返回哈希码的不同价值。所以字符串缓冲区类应该是适用于具有用于每concated对象相同的散列码。

有是没有理由不把你描述使用哈希码。

但是,你必须知道的碰撞。有机会的话 - 诚然,一个小机会 - 两个不同的字符串做散列值相同。考虑在首先进行的hashCode,如果相等也做使用equals的全面比较()。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top