0

I am stuck around while studying hashCode() in java. I wrote a sample code PFB snippet

public class Shared {
    String type;
    Date date;
 public Shared(String type) {
    this.type = type;

 }

public void setType(String type) {
    this.type = type;
    this.date = new Date(19894894823948L);
}

public static void main(String arg[]) {
    HashMap<Shared, String> hm = new HashMap<Shared, String>();
    Shared key = new Shared("me");
    Shared key1 = new Shared("me1");
    hm.put(key1, "value1");
    hm.put(key, "value");

    System.out.println(key.hashCode());//returning hashcode suppose X
    key.type=null;
    key.setType("type");
    System.out.println(key.hashCode());// it's even returning X again
    key.type="null";
    System.out.println(key.hashCode());// it's even returning X again.

}

I am really confused how this is possible even after changing the value contained within the key hashCode is same. it's literally breaking the immutable key concept.

Is the hashCode() method architecture/platform dependent?

The VOYOU
  • 522
  • 4
  • 14
  • 4
    Did you create `Shared` class? Did you override `hashCode()` and `equals()`? – vidit Jan 24 '16 at 20:09
  • 1
    How does the `HashMap` influence `hashCode()` generation of the `Shared` class? I suppose that you would get the same results without putting `key1` and `key` into a HashMap ... – Andreas Fester Jan 24 '16 at 20:11
  • 3
    It seems pretty likely that you're either overriding `hashCode` not to use `type`, or you're not overriding it at all... but we can't tell which when we can't see the code for `Shared.hashCode`. Please post a [mcve]. – Jon Skeet Jan 24 '16 at 20:12
  • No I did not override hashCode or equals. – The VOYOU Jan 24 '16 at 20:12
  • 6
    Well there we go then. It's behaving exactly as I'd expect. – Jon Skeet Jan 24 '16 at 20:12
  • It's simply not unique. Different keys can generate the same hash code. What happens is when searching for a key, it uses the generated hash code to get to a position in the table where it's LIKELY to be, but the keys are always compared. When they are not the same, the key is rehashed, using the same or different hash function ( with extra input like the current found position for another position and the process repeats. – Hans Lepoeter Jan 24 '16 at 20:13
  • @HansLepoeter: I don't think the OP ever mentioned an expectation of uniqueness... – Jon Skeet Jan 24 '16 at 20:13
  • 1
    Possible duplicate of [Why do I need to override the equals and hashCode methods in Java?](http://stackoverflow.com/questions/2265503/why-do-i-need-to-override-the-equals-and-hashcode-methods-in-java) – Andreas Fester Jan 24 '16 at 20:16
  • I think so, he mentioned "it's even returning X again", so he expected a different one. Even with below answer, which adresses the main problem in the code, my comment is still valid. It's likely it's diffrent though when overriding hashCode, but it's not guaranteed. – Hans Lepoeter Jan 24 '16 at 20:19

2 Answers2

4

I am really confused how this is possible even after changing the value contained within the key hashCode is same. it's literally breaking the immutable key concept.

Nope, it's fine. You're not overriding equals or hashCode, so it's not using the value of the type field as part of the equality comparison... it's just using reference identity, effectively. key still refers to the same object as it did, so it's entirely sensible for it to return the same hash code. Nothing affecting the hash code or equality has changed.

If you want your Shared type to be useful as a key in a map, I'd suggest:

  • Overriding hashCode() and equals(), making sure you obey all the relevant contracts
  • Preventing instances from being mutated in equality-affecting ways
  • Renaming it to be clearer about what it's meant to represent

Is the hashCode() method architecture/platform dependent?

It's up to the implementation, basically. From the docs:

As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the Java™ programming language.)

It would be valid for the Object.hashCode() method to always return 0... it just wouldn't be very useful.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
1

if you don't override hashcode() method in your class, you will get it fromObject. this means that it will not look at any of your class's fields when calculating the hashcode, therefor re-setting the value of type does nothing.

You need to override the method and calculate all fields of your class.

Nir Levy
  • 12,750
  • 3
  • 21
  • 38