0

I have a class that generates hash code based only on limited amount of properties. One of the requirements for hashCode uniqueness is that one of the properties must be exactly the same object instance. See this sample code:

class A {
  private B b;
  public A(B p) {
    b = p;
  }
  public int hashCode() {
      ???
  }
}

Now the only cases where the hashCode will be equal is when a1.b == a2.b. The problem is that I don't know how to add object instance ID to hashCode. Using B.hashCode would fail - the fact that two object's hashCodes are equal doesn't mean the object are the same instance.

Edit: I really have problems explaining this problem. I'll try some more:

My A class has a property B b. When generating hashCode of A, two A should have same hashCode, if their b property is the same object instance. Along with this, two A's with different instances in b should have different hashCode. This should work regardless off how B.hashCode is generated.

3
  • It's unclear to me what you're asking. There is no requirement that a hashcode is unique -- the requirement is that its uniformly distributed. Can you rephrase your question? Commented Apr 11, 2015 at 20:06
  • Why would you want your hash code to be unique ? Commented Apr 11, 2015 at 20:08
  • @JeroenVannevel Sorry, already when writing the question, was unsure how to put it. I tried to explain once more. Commented Apr 11, 2015 at 20:19

3 Answers 3

3

Hash codes aren't actually required to be unique. It's useful for them to be as close to unique as possible, but it's unlikely that someone will compare an A object's hash to a B object's hash, and if they do, it's not a huge loss. That said, to reduce collisions between A and B hashes, you could XOR b's hash code with some fixed int:

public int hashCode() {
    return b.hashCode() ^ 260299079;
}

If your concern is that you want A instances with equal but distinct b members to hash differently, rather than making sure A and B instances hash differently, you can use System.identityHashCode:

public int hashCode() {
    return System.identityHashCode(b) ^ 260299079;
}

This isn't actually guaranteed to produce different values for different B objects, but it's very likely to.

Sign up to request clarification or add additional context in comments.

1 Comment

System.identityHashCode is what I needed. For example things like String return same hashCode for different instances.
0

Would that suffice?

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((b == null) ? 0 : b.hashCode());
    return result;
}

The second solution is coming.

3 Comments

As I was pointing out, two B instances can have same hash code. For example, "foo"=="foo" evaluates to false (different instances) but "foo".hashCode()=="foo".hashCode() evaluates to true.
@TomášZato Excuse me but: "foo" == "foo" is perfectly true. "foo" == new String("foo") is false. Do you want to get same hashcode for o1 and o2 if the b identical in both objects? Ok I read edit in OP, but why not use equals method instead?
Ok, that was a bad example, I didn't know that "foo" == "foo" gives true and it makes no sense. I guess it's some sort of optimalization. I was talking about variables of course. I don't use equals because the hashCode is actually called by ArrayList. So unless extending or delegating ArrayList, this is the way to go.
0

Use a combination of the runtime class and your b property.

public int hashCode() {
    return getClass().hashCode() ^ b.hashCode();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.