gpt4 book ai didi

java - 用于在 Java 中比较对象的哈希

转载 作者:行者123 更新时间:2023-11-29 05:30:33 26 4
gpt4 key购买 nike

我需要在 java 中比较两个对象,应该测试它们的属性是否具有相同的值。而不是简单地比较我正在考虑使用哈希函数的所有属性。因此我写了下面的代码

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Vector;

public class Test {

private static Vector<String> vecA, vecB;

public static void main(String args[]) {
vecA = new Vector<String>();
vecB = new Vector<String>();

vecA.add("hallo");
vecA.add("blödes Beispiel");
vecA.add("Einer geht noch");
vecB.add("hallo");
vecB.add("blödes Beispiel");
vecB.add("Einer geht noch");

System.out.println("HashCode() VecA: " + vecA.hashCode());
System.out.println("HashCode() VecB: " + vecB.hashCode());

System.out.println("md5 VecA: " + md5(vecA));
System.out.println("md5 VecB: " + md5(vecB));

vecA.add("ungleich");

System.out.println("HashCode() VecA: " + vecA.hashCode());
System.out.println("HashCode() VecB: " + vecB.hashCode());

System.out.println("md5 VecA: " + md5(vecA));
System.out.println("md5 VecB: " + md5(vecB));

}

private static String md5(Vector<String> v){
try {
MessageDigest algorithm = MessageDigest.getInstance("MD5");
algorithm.reset();
algorithm.update(vecA.toString().getBytes());
byte messageDigest[] = algorithm.digest();

StringBuffer hexString = new StringBuffer();
for (int i = 0; i < messageDigest.length; i++) {
String hex = Integer.toHexString(0xFF & messageDigest[i]);
if (hex.length() == 1)
hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException nsae) {}
return null;
}
}

md5函数是一些网站简单复制的。这导致以下输出

HashCode() VecA: -356464767
HashCode() VecB: -356464767
md5 VecA: 6805716958249f5b7f177fc95408713e
md5 VecB: 6805716958249f5b7f177fc95408713e
HashCode() VecA: 1477685990
HashCode() VecB: -356464767
md5 VecA: c76297ce297d5308359ca06f26fb97ca
md5 VecB: c76297ce297d5308359ca06f26fb97ca

我很困惑,在 vecA 中添加一个元素似乎会改变 vecB 的 md5 代码,因此它们的哈希值仍然相同。在这种情况下,使用 java.security.MessageDigest 或简单地使用 hashCode() 的原因是什么?它们有什么优势吗?哈希函数的性能与所有属性的比较相比如何?

最佳答案

在这两种情况下,您都在为 vecA 构建 md5 哈希:

algorithm.update(vecA.toString().getBytes());

应该是

algorithm.update(v.toString().getBytes());

Whats the reason and is their any advantage in using java.security.MessageDigest or simply hashCode() in that case?

不使用 hashCode 的一个优点是,如果该方法未被重写,同一类和具有相同属性值的两个实例仍会返回不同的哈希值,因为默认实现哈希码

How about the performance of hash functions vs. comparisons of all attributes?

如果您只比较一次属性,可能不会有任何明显的性能差异(然而,这取决于您比较属性的方式)但是如果重复比较多个属性与一次又一次地计算哈希值比较哈希,后者可能更快。

编辑:

这里有一个例子来阐明第一条引述的答案。考虑以下简单的代码:

static class A {   
int x;

public A( int i) {
x = i;
}
}


static class B {
int x;

public B( int i) {
x = i;
}

public int hashCode() {
final int prime = 31;
return prime * x;
}

public boolean equals( Object obj ) {
//by contract you should always override equals and hashCode together
//also note that some checks are omitted for simplicity's sake (obj might be null etc.)
return getClass().equals( obj.getClass()) && x == ((B)obj).x;
}
}

如您所见,A 不会覆盖 hashCodeB 会覆盖。因此,您将得到以下结果:

System.out.println(new A( 500 ).hashCode() == new A(500).hashCode());  //false
System.out.println(new B( 500 ).hashCode() == new B(500).hashCode()); //true

请注意,x 在这两种情况下是相同的,但对于 A#hashCode() 使用的是对象标识,而不是像 B#hashCode() 那样使用 x 的值>

关于java - 用于在 Java 中比较对象的哈希,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21229336/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com