views:

378

answers:

10

This is a an interview question.

+6  A: 

yes, since you can have as many objects with the same hashCode as you want. For example, the following code, without interning Strings, show this fact:

String foo = new String("dfa");
String bar = new String("dfa");
assert foo != bar; // yields false, two distinct objects (references)
assert foo.hashCode() == bar.hashCode(); // yields true
dfa
do you need a proof?
dfa
Longer answer: the Java specification doesn't set any particular expectations as per what the hash of an object should be. A constant function would be a compliant implementation...
Romain
Yes I would appreciate the proof. Thanks.
Murali
+1  A: 

Yes, hashcode is a standard algorithm that tries to avoid duplicates ('collisions') but doesn't guarantee it.

Moreover, it's overrideable, so you could write your own implementation yielding the same hashcode for every object; as to why you would want to do that I have no answer however. :-)

Peter
+20  A: 

Yes.

public class MyObject {
    @Override
    public int hashCode() {
        return 42;
    }

    public static void main(String[] args) {
        MyObject obj1 = new MyObject();
        MyObject obj2 = new MyObject(); // Ta-da!
    }
}

For a less flippant answer, consider the hashCode Javadocs:

The general contract of hashCode is:

  • ... (snip) ...
  • 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.
Michael Myers
@Peter: Weird. I've never, ever seen that.
erickson
@Peter: That's an absolutely terrible thing to do.
Nick Veys
@sylvarking: What happened to erickson?
Michael Myers
@sylvarking I have! Took a while to debug since we were using the hash to store into a cache and objects were being overwritten.
Robin
@robin : why would you use the hash as a key when duplicates are possible?? When duplicates aren't possible, that wouldn't lead to overwriting
Peter
@Peter - I was dubugging a problem some years ago, and this is when I found out about the non uniqueness of the hashcode. In reality, it rarely shows itself since many VM's simply uses the objects address for the hash, thus no two objects can have the same one, but this was not the case of course in the VM we were using.
Robin
Oh, in the last comment I was specifically referring to the default hashcode, which is what the objects in question were using.
Robin
A: 

in a 32-bit environment, I doubt any JVM would return same 'identity hash code' for different objects. but in 64-bit, that is certainly a possibility; the likelihood of collision is still very small given the limited memory we have now.

irreputable
+3  A: 

About hash codes: yes they are nearly, but not really unique. :) It depends on the implementation/theory how nearly unique they are.

But if we talk about the JVM, we must first of all talk about what kind of hash code you've meant.

If you talk about the result of the hashCode() method which is used f.e. by the HashMap, then the answer is: it depends on your implementation and the number of objects in your JVM.
It's your choice and plan and knowledge to resolve this conflict in a self-implemented hashCode() method.

If you talk about the result of the method System.identityHashCode( obj ), then it's a little bit different. This implementation doesn't call your hashCode() method. And the implementation isn't unique - but it's nearly unique, like many other different hash functions. :)

public class MyObject {
    @Override
    public int hashCode() {
        return 42;
    }

    public static void main(String[] args) {
        MyObject obj1 = new MyObject();
        MyObject obj2 = new MyObject(); // Ta-da!

        final int obj1Hash = System.identityHashCode( obj1 );
        final int obj2Hash = System.identityHashCode( obj2 );

        if( obj1Hash == obj2Hash ) throw new IllegalStateException();
    }
}

In this example you will get different hashes, and in the most cases they are different, but not definitely unique...

Best regards!

drdrej
N.B. The wording on Object.hashCode() is that distinct objects will have distinct hash codes "as much as is reasonably practical". This sort of implies distinct hash codes on a 32-bit system, where it is totally and utterly practical.
Neil Coffey
Most classes wille have many possible collisions however, because the hash code is only an int...
Peter
+3  A: 

Trivial proof: hashCode returns a 32 bit integer.

Allocate 2^32+1 Objects. (Probably going to need a 64-bit VM and a lot of RAM for this! ;-) )

Now your hashCode method, no matter how clever, must have a collision.

Steven Schlansker
just iterate over Float() and you'll have plenty
Peter
A: 

Yes you certainly can have more than one object with the same hashcode. However, usually this doesn't cause problems because the java.util.* data structures that use the object hashcode use it as a key into a "bucket" that stores all objects returning the same hash.

Aditya
A: 

You can, but it's not generally a good idea. The example mentioned several times above:

public int hashCode(){
     return 1;
}

is perfectly valid under the specification for hashCode(). However, doing this turns HashMap into a Linked List, which significantly degrades performance. So you generally want to implement hashCode to return values as unique as you can get it.

As a practical matter, though, collisions can occur with many implementations. Take this for example:

public class OrderedPair{
     private int x;
     private int y;

     public int hashCode(){
          int prime = 31;
          int result=x;
          result =result*prime+y;
          return result; 
     }

     public boolean equals(){...}
}

This is a pretty standard implementation of hashCode() (in fact, this is pretty close to the output which is automatically generated in IDEA and Eclipse), but it can have many collisions: x=1,y=0 and x=0,y=1 will work for starters. The idea of a well-written hashCode() implementation is to have few enough collisions that your performance is not unduly affected.

Scott Fines
+1  A: 

Of course, and obviously you can write:

class MyClass{
   ...
   public int hashCode(){
      return 1;
   }
   ...
}

in which case all instances of MyClass will have the same hash code.

Chad Okere
A: 
Object a = new Integer(1);
Object b = new Integer(1);

System.out.printf(" Is the same object?     = %s\n",(a == b ));
System.out.printf(" Have the same hashCode? = %s\n",( a.hashCode() == b.hashCode() ));

Prints:

Is the same object?     = false
Have the same hashCode? = true
OscarRyz