首页 > 解决方案 > Will my object creation fail with improper hashcode-equals implementation?

问题描述

I want to create a class Customer who can be uniquely identified by Customer No.

I wrote the code below

public class Customer{
    private Integer customerNo;
    private String customerName;
    
    public Customer(Integer customerNo, String customerName){
        this.customerNo = customerNo;
        this.customerName = customerName;
    }
    
    @Override
    public int hashCode(){
        return this.customerNo;
    }
    
    public Integer getCustomerNo(){
        return this.customerNo;
    }

    public String getCustomerName(){
       return this.customerName;
    }
    
    @Override
    public boolean equals(Object o){
        Customer cus = (Customer) o;
        return (this.customerNo == cus.getCustomerNo() && this.customerName != null && this.customerName.equals(cus.getCustomerName()));
    }
    
    @Override
    public String toString(){
        StringBuffer strb = new StringBuffer();
        strb.append("Customer No ")
            .append(this.customerNo)
            .append(", Customer Name ")
            .append(this.customerName)
            .append("\n");
        return strb.toString(); 
    }       
    
    public static void main(String [] args){
        Set<Customer> set = null;
        try{
            set = new HashSet<Customer>();
        
            set.add(new Customer(1,"Jack"));
            set.add(new Customer(3,"Will"));
            set.add(new Customer(1,"Tom"));
            set.add(new Customer(3,"Fill"));
        
            System.out.println("Size "+set.size());
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

From the above code you can see that I am returning my hashcode as customer No.

And my equality is also based on customer No. and Customer Name

If I run the above code the output will be

D:\Java_Projects>java Customer
Size 4

D:\Java_Projects>

The output is 4 objects getting created of same customer No. The reason is even though the customer no. is same, but the names are different, as per my above implementation of 'equals' its based on both customerNo and customer Name. As 4 different combinations of CustomerNo-CustomerName, hence 4 objects getting created.

My question is,

Is my above hashcode implementation a bad practise ?

What all failures I can come accross ?

What if I create 500,000 Customer objects with same customer No, what will happen ?

Whether there will be 500,000 customer objects placed in a same bucket No ?

标签: javaoopjava-8compiler-errorsruntime-error

解决方案


equals(...)和之间有一个隐含的契约hashCode()

的总合同hashCode是:

  • 在 Java 应用程序执行期间,只要在同一个对象上多次调用该方法,该hashCode方法必须始终返回相同的整数,前提是没有修改对象上的 equals 比较中使用的信息。该整数不需要从应用程序的一次执行到同一应用程序的另一次执行保持一致。

  • 如果根据方法两个对象相等equals(Object),则对两个对象中的每一个调用该hashCode方法必须产生相同的整数结果。

  • 不要求如果两个对象根据equals(java.lang.Object)方法不相等,则对两个对象中的每一个调用该hashCode方法必须产生不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。

您的实现满足所有三个约束。但是,最佳实践是所有比较的属性也equals(...)应该影响hashCode(),反之亦然。hashCode()否则,使用(例如HahsMap和)的数据结构可能会HashSet表现不佳。正如您所提到的,原因之一是所有具有相同的对象hashCode都放在同一个桶中,因此访问可能没有恒定的时间复杂度。

但是,这不会导致抛出异常。


推荐阅读