Explain res = id^(id >>> 32), please

Hullo!
I have this code

public int hashCode(){
        int res = (int) (id ^ (id >>> 32));
        res = 31 * res + (name != null ? name.hashCode() : 0);
        return res;
    }

And this is my equals code

    public boolean equals(Object o) {
        // object ref identical or not
        if (this == o) return true;
        if (o == null) return false;
        //class identical?
        if (getClass() != o.getClass()) return false;
        Person person = (Person) o;

        if(id != person.id) return false;

        return Objects.equals(name, person.name);
    }

I don`t understand operations over result.
Why do we have to do these operations?
Will be very grateful if someone can explain it to me

Equals i understand well, but i read they are connected somehow, so I’ve attached the comparison code just in case

  • Are you asking why someone wrote equals and hashCode methods in that class?

    – 




  • Don’t think about it too hard. The only thing a hash function has to do is A==B => h(A)==h(B), which this obviously does. Then there is A!=B => h(A)!=h(B) "as often as you can manage" which makes it fast. Violating the second nice-to-have rule will still result in a working hash (albeit a slower one). Try a hashCode that returns 0 for everything. Things should still work.

    – 




  • But to your question, if id is int, ^ >>> does nothing. If it is long, it xors its two 32-bit halves together.

    – 




  • assuming id is a long, this is just calculating its hashcode in the same way as done by Long.hashCode()

    – 




Explain res = id^(id >>> 32) please

  • id >>> n for an int, shifts id right n%32 bits without extending the negative sign bit if one is present. So (id >>> 32) is effectively == id.
  • ^ is an exclusive OR which says for any bit a and b, a^b == 1 if a and b are different otherwise they a^b == 0. E.g. 1^1 == 0. 0^0 == 0, 1^0 == 1

So id ^ id == 0.

if id is a long, (id >>> 32) shifts the high order 32 bits of that long right 32 bits and then exclusive ors the original long with that value.

The over all computation of hashCode is to use that technique sometimes employed with others to generate a number for use in data structures that are used to index by hashcode. in Java, primary examples are Maps and Sets.

Here is a demo.

long v = Long.MIN_VALUE; // has 1 in hob (high order bit) and rest is 0's
System.out.println(Long.toBinaryString(v));
 
long result = v ^ (v >>> 32); // now hob should be 1 and hob of low order int should be 1

System.out.println(Long.toBinaryString(result));
1000000000000000000000000000000000000000000000000000000000000000
1000000000000000000000000000000010000000000000000000000000000000

Leave a Comment