-3

I have found many possible duplicates question on this but none clarifies my doubt on how it works?

    Integer a =25654; // a.hashCode()=>25654
    Integer b =25654; // b.hashCode()=>25654
    System.out.println(a.equals(b)); => true
    System.out.println(a == b);   => false

I have read this answer somewhere..

If no parent classes have provided an override, then it defaults to the method from the ultimate parent class, Object, and so you're left with the Object#equals(Object o) method. Per the Object API this is the same as ==; that is, it returns true if and only if both variables refer to the same object, if their references are one and the same. Thus you will be testing for object equality and not functional equality.

in this case both object have same memory address(as per hashcode) still why does it returns false when we compare using == ? or the actual memory address is different? please correct me if i am wrong. Thanks

Hooman.AS
  • 190
  • 1
  • 3
  • 18
Sharan Rai
  • 94
  • 8
  • 2
    Integer class itself overrides both `hashCode` and `equals` method. HashCode simply returns value held by Integer object, in this case `25654` despite the fact that both objects are different instances (which you can see via `a == b` -> `false`). – Pshemo Jul 01 '18 at 07:58
  • is there a way to see the actual memory address of the Integer object? – Sharan Rai Jul 01 '18 at 08:07
  • 4
    You should hardly ever care about the actual memory address of an object (and the JVM can move objects in memory!) – Mark Rotteveel Jul 01 '18 at 08:10
  • 3
    Why do you think they're in the same memory address? These are two different objects. They can't possibly be at the same address. – Dawood ibn Kareem Jul 01 '18 at 08:11
  • @DawoodibnKareem: actually the JLS allows implementations to cache all integer references, and the range -128 to 127 is guaranteed. If the OP had presented the question with smaller numbers, the final result would have been different. – Bathsheba Jul 01 '18 at 08:15
  • @Bathsheba well, yes, obviously. But that doesn't apply here. We know they're two different objects, because `==` gave false. – Dawood ibn Kareem Jul 01 '18 at 08:17
  • 1
    Reopened. A good duplicate would discuss integer caching. This part of java is very bewildering: flawed, almost. – Bathsheba Jul 01 '18 at 08:17
  • On some implementations it could be true. – Bathsheba Jul 01 '18 at 08:17
  • Yes, but it isn't true in OP's implementation. OP said that. – Dawood ibn Kareem Jul 01 '18 at 08:18

2 Answers2

2

Object.hashCode:

The hashCode method defined by class Object does return distinct integers for distinct objects.

But Integer.hashCode overrides Object.hashCode:

returns a hash code value for this object, equal to the primitive int value represented by this Integer object.

which means Integers with same hashCode does not have to share the same object.


The source code of Integer.hashCode

@Override
public int hashCode() {
    return Integer.hashCode(value);
}

public static int hashCode(int value) {
    return value;
}

If you let:

Integer a = 127;
Integer b = 127; 
System.out.println(a.equals(b)); // true
System.out.println(a == b); // true

this is because Integers between [-128, 127] could be cached.

xingbin
  • 27,410
  • 9
  • 53
  • 103
1

in this case both object have same memory address(as per hashcode) still why does it returns false when we compare using == ? or the actual memory address is different? please correct me if i am wrong. Thanks

  1. The hashcode has not to be considered as the memory address because the internal address of an object may change through the time.

  2. The specification of hashCode() never state that two objects with the same hashcode value refer necessarily the same object.
    Even two objects with the same hashcode may not be equals in terms of Object.equals().

But the specification states :

If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.

And this is verifiable in your example :

Integer a =25654; // a.hashCode()=>25654
Integer b =25654; // a.hashCode()=>25654
System.out.println(a.equals(b)); => true

a and b refer to objects that are equals(), and yes their hash code is indeed the same.


Your quotation doesn't refer to hashCode() but to the default Object.equals() method that will be used if no overriding was done for equals().

For example if I don't override equals() and hashCode() for a Foo class :

Foo fooOne = new Foo(1);
Foo fooOneBis = new Foo(1);
fooOne.equals(fooOneBis); // return false

The two objects have the same state but they are not equals as under the hood is used Object.equals() that compares the object itself and not their state.

And indeed equal() will return true only if the variables refer the same object :

Foo foo = new Foo(1); 
foo.equals(foo); // return true
davidxxx
  • 125,838
  • 23
  • 214
  • 215