Generating hashCode() for a custom class

丶灬走出姿态 提交于 2019-12-12 03:26:23

问题


I have a class named Dish and I handle it inside ArrayLists So I had to override default hashCode() method.

@Override
public int hashCode() {
    int hash =7;
    hash = 3*hash + this.getId();
    hash = 3*hash + this.getQuantity();
    return hash;
}

When I get two dishes with id=4,quan=3 and id=5,quan=0, hashCode() for both is same;

((7*3)+4)*3+3 = 78
((7*3)+5)*3+0 = 78

What am I doing wrong? Or the magic numbers 7 and 3 I have chosen is wrong?

How do I properly override hashCode() so that it generates unique hashes?

PS: From what I searched from google and SO, people use different numbers but the same method. If the problem is with the numbers, how do I wisely choose numbers that doesn't actually increase the cost for multiplication and at the same time works well even for more number of attributes.

Say I had 7 int attributes and my second magic no. is 31, the final hash will be first magic no. * 27512614111 even if all my attributes are 0. So how do I do it without having my hashed value in billions so as keep my processor burden-free?


回答1:


This is perfectly OK. The hashing function is not supposed to be universally unique - it just gives a quick hint about which elements might be equal and should be checked in more depth by a call to equals().




回答2:


You can use something like this

public int hashCode() {
     int result = 17;
     result = 31 * result + getId();
     result = 31 * result + getQuantity();
     return result;
}

One more thing if your id is unique for each object then no need of using quantity while calculating hashcode.

Here is extract from Effective Java by Joshua bloch telling how implement hashcode method

  1. Store some constant nonzero value, say, 17, in an int variable called result.

  2. For each significant field f in your object (each field taken into account by the equals method, that is), do the following:

    a. Compute an int hash code c for the field:

    i. If the field is a boolean, compute (f ? 1 : 0).
    ii. If the field is a byte , char, short, or int, compute (int) f .
    iii. If the field is a long , compute (int) (f ^ (f >>> 32)) .
    iv. If the field is a float , compute Float.floatToIntBits(f) .
    v. If the field is a double, compute Double.doubleToLongBits(f) , and then hash the resulting long as in step 2.a.iii.
    vi. If the field is an object reference and this class’s equals method compares the field by recursively invoking equals, recursively invoke hashCode on the field. If a more complex comparison is required, compute a “canonical representation” for this field and invoke hashCode on the canonical representation. If the value of the field is null, return 0 (or some other constant, but 0 is traditional).
    vii. If the field is an array, treat it as if each element were a separate field. That is, compute a hash code for each **significant element** by applying these rules recursively, and combine these values per step 2.b. If every element in an array field is significant, you can use one of the Arrays.hashCode methods added in release 1.5.
    

    b. Combine the hash code c computed in step 2.a into result as follows: result = 31 * result + c;

  3. Return result .

  4. When you are finished writing the hashCode method, ask yourself whether equal instances have equal hash codes. Write unit tests to verify your intuition!If equal instances have unequal hash codes, figure out why and fix the problem.

Source: Effective Java by Joshua Bloch




回答3:


From the name of class looks like quantity is the number of dish. So, There is chance that many times it will be zero. I would say in case getquantity() is zero use a variable say x in the hash fucntion.like this:

 @Override
public int hashCode() {
int hash =7;int x =0;

if(getQuantity==0)
 {
   x = getQuantity+getId();
 } 
 else
 {
    x = getquantity;
 }
hash = 3*hash + this.getId();
hash = 3*hash + x;
return hash;

}

I believe this should reduce the collision of hash.since the getId() you have is a unique number.it makes the x a unique number too.



来源:https://stackoverflow.com/questions/36147943/generating-hashcode-for-a-custom-class

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!