java - 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 ?
解决方案
equals(...)
和之间有一个隐含的契约hashCode()
:
的总合同
hashCode
是:
在 Java 应用程序执行期间,只要在同一个对象上多次调用该方法,该
hashCode
方法必须始终返回相同的整数,前提是没有修改对象上的 equals 比较中使用的信息。该整数不需要从应用程序的一次执行到同一应用程序的另一次执行保持一致。如果根据方法两个对象相等
equals(Object)
,则对两个对象中的每一个调用该hashCode
方法必须产生相同的整数结果。不要求如果两个对象根据
equals(java.lang.Object)
方法不相等,则对两个对象中的每一个调用该hashCode
方法必须产生不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。
您的实现满足所有三个约束。但是,最佳实践是所有比较的属性也equals(...)
应该影响hashCode()
,反之亦然。hashCode()
否则,使用(例如HahsMap
和)的数据结构可能会HashSet
表现不佳。正如您所提到的,原因之一是所有具有相同的对象hashCode
都放在同一个桶中,因此访问可能没有恒定的时间复杂度。
但是,这不会导致抛出异常。
推荐阅读
- http - 使用 IIS 在服务器和客户端之间建立持续的 HTTPS 连接
- clipboard - QA 测试剪贴板操作
- php - 以模型为参数的资源控制器方法不起作用
- xquery - 创建并运行一次“计划任务”
- iis - 如何在 web.config 中用不同的名称重写文件夹名称?
- r - 在这个图中我的自定义调色板有什么问题?
- bash - 如何更快地制作一个在 k/v 对上循环调用 awk 的脚本?
- php - mysqld_safe 来自 pid 文件 mysqld.pid 的 mysqld 结束
- java - 如何将自定义按钮和文本添加到 android 导航?(以 X 身份登录)
- wpf - 如何将值从页面传递到文本框到WPF中的主窗体?