简体   繁体   English

结合字符串哈希和long哈希

[英]Combining Hash of String and Hash of Long

I have the following java class: 我有以下java类:

public class Person{
   String name;  //a unique name
   Long DoB;     //a unique time
   .
   .
   .
   @Override
   public int hashCode(){
     return name.hashCode() + DoB.hashCode();
   }

}

Is my hashCode method correct (ie would it return a unique number of all combinations. 我的hashCode方法是否正确(即,它将返回所有组合的唯一编号)。

I have a feeling I'm missing something here. 我觉得我在这里想念什么。

您可以让java.util.Arrays为您做这件事:

return Arrays.hashCode(new Object[]{ name, DoB });

Aside for the obvious, which is, you might want to implement the equals method as well... 除了显而易见的以外,您可能还想实现equals方法...

  • Summing two hash codes has the very small risk of overflowing int 对两个哈希码求和具有int溢出的很小的风险
  • The sum itself seems like a bit of a weak methodology to provide unique hash codes. 总和本身似乎是提供唯一哈希码的较弱方法。 I would instead try some bitwise manipulation and use a seed. 相反,我将尝试按位操作并使用种子。

You might also want to use something more fluent and more NPE-bulletproof like Google Guava : 您可能还想使用更流畅,更NPE防弹的工具,例如Google Guava

@Override
public int hashCode(){
    return Objects.hashCode(name, DoB);
}

@Override
public boolean equals(Object o) {
    if ( this == o ) {
        return true;
    }
    if ( o == null || o.getClass() != Person.class ) {
        return false;
    }
    final Person that = (Person) o;
    return Objects.equal(name, that.name) && Objects.equal(DoB, that.DoB);
}

Edit: 编辑:

IntelliJ IDEA and Eclipse can generate more efficient hashCode() and equals() . IntelliJ IDEA和Eclipse可以生成更有效的hashCode()equals()

usually a hashcode is build like so: 通常,哈希码的构建方式如下:

   @Override
   public int hashCode(){
     return name.hashCode() ^ DoB.hashCode();
   }

but the important thing to remember when doing a hashcode method is the use of it. 但是使用哈希码方法时要记住的重要一点是使用它。 the use of hashcode method is to put different object in different buckets in a hashtable or other collection using hashcode. 哈希码方法的使用是将不同的对象放在使用哈希码的哈希表或其他集合的不同存储桶中。 as such, it's impotent to have a method that gives different answers to different objects at a low run time but doesn't have to be different for every item, though it's better that way. 这样,没有一种方法可以在较低的运行时间为不同的对象提供不同的答案,但是不必对每个项目都有所不同,尽管这样做会更好。

This hash is used by other code when storing or manipulating the instance – the values are intended to be evenly distributed for varied inputs in order to use in clustering. 在存储或操作实例时,其他代码会使用此哈希-旨在将这些值均匀分配给各种输入,以便在群集中使用。 This property is important to the performance of hash tables and other data structures that store objects in groups ("buckets") based on their computed hash values 此属性对于哈希表和其他基于对象的计算哈希值将对象存储在组(“存储桶”)中的数据结构的性能很重要

and

The general contract for overridden implementations of this method is that they behave in a way consistent with the same object's equals() method: that a given object must consistently report the same hash value (unless it is changed so that the new version is no longer considered "equal" to the old), and that two objects which equals() says are equal must report the same hash value. 此方法的重写实现的一般约定是,它们的行为方式与相同对象的equals()方法一致:给定对象必须一致地报告相同的哈希值(除非更改了该值,以便不再使用新版本)被认为与旧的“相等”),并且equals()表示相等的两个对象必须报告相同的哈希值。

See Bloch's Effective Java #9. 请参阅Bloch的有效Java#9。

But you should start with an initial value (so that subsequent zero values are significant), and combine the fields that apply to the result along with a multiplier so that order is significant (so that similar classes will have much different hashes.) 但是,您应该从一个初始值开始(以便随后的零值有效),然后将与结果相乘的字段与一个乘数相结合,以便顺序有效(以使相似的类具有不同的哈希值)。

Also, you will have to treat things like long fields and Strings a little different. 同样,您将不得不对待长字段和字符串之类的东西有所不同。 eg, for longs: 例如,长期:

(int) (field ^ (field>>>32))

So, this means something like: 因此,这意味着:

@Override public int hashCode() {
   int result = 17;
   result += name.hashCode() == null ? 0 : name.hashCode();
   result = 31 * result + (int) (DoB ^ (DoB >>> 32));
   return result;
}

31 is slightly magic, but odd primes can make it easier for the compiler to optimize the math to shift-subtraction. 31有点魔术,但是奇数质数可以使编译器更容易优化数学以进行减法运算。 (Or you can do the shift-subtraction yourself, but why not let the compiler do it.) (或者您可以自己进行移位减法,但是为什么不让编译器来做。)

Your hash code implementation is fine and correct. 您的哈希码实现是正确的。 It could be better if you follow any of the suggestions other people have made, but it satisfies the contract for hashCode , and collisions aren't particularly likely, though they could be made less likely. 如果您遵循其他人提出的任何建议,可能会更好,但它满足hashCode的约定,并且碰撞的可能性不大,尽管可能会降低。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM