简体   繁体   中英

Why is 'equals' in Java true with different hashcodes?

I am going through the java.lang.Object API which states the below the point on objects equality:https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html

public boolean equals(Object obj):

It is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.

Now to test the above theory on "equal objects must have equal hash codes", I have come up with the below simple code:

public class Product {

    private String name;

    public Product(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object obj) {
        //always returns true for all objects
        return true;
    }

    @Override
    public int hashCode() {
        //Different hascodes for different objects
        if(name.equals("PRODUCT1")) {
            return 10;
        } else {
            return 20;
        }
    }

    public static void main(String[] args) {
        Product p1 = new Product("PRODUCT1");
        Product p2 = new Product("PRODUCT2");

        if(p1.equals(p2)) {
            System.out.println(" p1 p2 are equal **** ");
        } else {
            System.out.println(" p1 p2 are NOT equal **** ");
        }

    HashSet<Product> set = new HashSet<>();
    set.add(p1);
    set.add(p2);
    System.out.println(" size :"+set.size());
    }
}

Output:

p1 p2 are equal ****

size : 2

So, isn't the above code violating/contradicting the API statement "equal objects must have equal hash codes" ie, equal objects need NOT have same hashcodes?

I understand that the compiler can't validate this contract, but doesn't JVM at runtime complain any error/warning stating that equal objects should have different hashcodes?

Am I correct in understanding that the 'equal objects should have same hashcodes' is strictly followed only for performance improvements for huge/large sets of object comparisons and no JRE (no one) complains about the same (except losing performance)? If not, can you help with an example (using hashsets or hashmaps or any hash...) which throws an error by violating the contract along with the error message?

Your code violates the contract, but this contract can't be verified by the compiler. This is why you don't get any compile time error message.

You might get incorrect behavior or runtime errors when inserting instances of this class in sets or maps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM