我需要比较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()是他们的优势?散列函数的性能与所有属性的比较如何?
答案 0 :(得分:2)
在这两种情况下,您都要为vecA构建md5哈希:
algorithm.update(vecA.toString().getBytes());
应该是
algorithm.update(v.toString().getBytes());
原因是什么,在这种情况下使用java.security.MessageDigest或简单地使用hashCode()是他们的优势吗?
不使用hashCode
的一个好处是,如果不覆盖该方法,由于{{1的默认实现,同一个类和具有相同属性值的两个实例仍会返回不同的哈希值}}
哈希函数的性能与所有属性的比较如何?
如果你只是比较属性一次,可能没有任何明显的性能差异(但是,这取决于你如何比较属性)但是在重复比较多个属性与一次重复计算哈希的情况下比较哈希,后者可能会更快。
修改强>:
这是一个澄清第一句话答案的例子。 请考虑以下简单的代码:
hashCode
正如您所看到的,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
的情况下不会覆盖hashCode
。因此,您将获得以下结果:
B
请注意,x在两种情况下都相同,但对于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()
答案 1 :(得分:1)
您的md5方法存在问题
algorithm.update(vecA.toString().getBytes());
可能应该是
algorithm.update(v.toString().getBytes());