开发者

Are two Java objects with same hashcodes not necessarily equal?

开发者 https://www.devze.com 2023-02-19 18:30 出处:网络
I understand why providing same hashcode for two equal (through equals)objects is important. But is the vice vers开发者_运维知识库a true as well, if two objects have same hashcode do they have to be e

I understand why providing same hashcode for two equal (through equals) objects is important. But is the vice vers开发者_运维知识库a true as well, if two objects have same hashcode do they have to be equal? Does the contract still hold? I cannot find an example where this could happen, because if all those attributes that are taking part in equals method are being used to override hashcode method as well then we will always same hashcode of objects that are equal. Please comment.


If two objects have the same hashcode then they are NOT necessarily equal. Otherwise you will have discovered the perfect hash function.

But the opposite is true: if the objects are equal, then they must have the same hashcode.


The purpose of the hashCode function is allow objects to be quickly partitioned into sets of things that are known to unequal to all items outside their own set. Suppose one has 1,000 items and one divides them into ten roughly-equal-sized sets. One call to hashCode could quickly identify the item as being not equal to 900 of the items, without having to use equals on any of those items. Even if one had to use equals to compare the item to 100 other items, that would still be only 1/10 the cost of comparing it to all 1000 items. In practice, even in a large collection, hashCode will often eliminate 99.9% or more of the unequal items, leaving at most a handful to be examined.


According to the Javadoc in: http://download.oracle.com/javase/6/docs/api/java/lang/Object.html#hashCode%28%29

It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.

Edit: In the real world two Strings may have the same hash code. For instance, if you want to store all string combinations that contain lowercase English letters (like "aaaaaaaaaa","aaaaaaaaab" and so on) of length 10, you can't assign a unique hash code to each of the 141.167.095.653.376 combinations, since int in Java is 32-bit and, therefore, can have up to 4.294.967.296 distinct values.


hashCode value depends on the implementation. for example String class implements hashCode() function depending upon the value. it means

String a=new String("b");
String b=new String("b");

will have same hashcode but, these are two different objects. and a==b will return false.


As a matter of fact

public int hashCode(){
    return 1;
}

Is a valid hashcode implementation...but a terrible one. Will make all your hashtables slow. But yes, you can have two different objects with the same hashcode. But that should not be the general case, a real implementation should give different hashcodes for different values most of the time.


Curiously, NumberFormat is an example of a Java foundation class which violates the recommendation that:

As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects.

Here is some code showing this, at least under the version of Java I'm currently running under Mac OS X 10.6.

Numberformat nf = NumberFormat.getNumberInstance();
NumberFormat nf2 = NumberFormat.getNumberInstance();
assert nf != nf2;  // passes -- they are different objects
assert !nf.equals(nf2);  // passes -- they are not equal
assert nf.hashCode() != nf2.hashCode();  // fails -- same hash code


Hash code method returns integer. If range of integer finishes then also two different object will have same hash code. So it is not necessary that two different object will have same hash code are equal.


To prove , if two objects have the same hashCode does not mean that they are equal

Say you have two user defined classes

    class Object1{
        private final int hashCode = 21;
        public int hashCode(){
            return hashCode;
        }

        public boolean equals(Object obj) {
            return (this == obj);
        }
    }

    class Object2{
        private final int hashCode = 21;
        public int hashCode(){
            return hashCode;
        }

        public boolean equals(Object obj) {
            return (this == obj);
        }
    }

    Object1 object1 = new Object1();
    Object2 object2 = new Object2(); 

    Object1 object3 = new Object1();


    if(object1.hashCode() == object2.hashCode()){
         // return true, because the hashcodes are same
    }

    but 
    if(object1.equals(object3)){
            // will fail, because two different objects   
    }


hashcode() returns a unique integer ID for each object. If an object’s hashcode is not the same as another object’s hashcode, there is no reason to execute the equals() method: you just know the two objects are not the same. On the other hand, if the hashcode is the same, then you must execute the equals() method to determine whether the values and fields are the same.


Whenever two different objects have the same hash code, we call this a collision. A collision is nothing critical, it just means that there is more than one object in a single bucket, so a HashMap lookup has to look again to find the right object. I found it from here, hope this helps. https://eclipsesource.com/blogs/2012/09/04/the-3-things-you-should-know-about-hashcode/#:~:text=HashCode%20collisions,to%20find%20the%20right%20object.

0

精彩评论

暂无评论...
验证码 换一张
取 消