java - 如果哈希码等于实现不正确,我的对象创建会失败吗?

标签 java oop java-8 compiler-errors runtime-error

我想创建一个可以由客户编号唯一标识的客户类。
我写了下面的代码

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();
        }
    }
}
从上面的代码中,您可以看到我将哈希码作为客户编号返回。
我的平等也基于客户编号和客户名称
如果我运行上面的代码,输出将是
D:\Java_Projects>java Customer
Size 4

D:\Java_Projects>
输出是由相同客户编号创建的4个对象。
原因是即使客户没有。一样,但名字不同,
根据我以上基于“客户编号”和“客户名称”的“等于”实现。
作为CustomerNo-CustomerName的4种不同组合,因此创建了4个对象。
我的问题是
我上面的哈希码实现是不好的做法吗?
我会遇到什么失败?
如果我与同一个客户一起创建500,000个Customer对象,该怎么办?
是否将500,000个客户对象放在同一个存储桶中?

最佳答案

Is my above hashcode implementation a bad practise ?


假设大多数时候大多数客户的customerNo不同,这是一个很好的实现。在现实世界的应用程序中,customerNo很可能是唯一的标识符,其唯一性由数据库约束来保证。

What all failures I can come accross ?


您尚未处理customerNonull的情况。这是一种方法:
public int hashCode(){
    return Objects.hash(customerNo);
}
customerNonull时,它将返回0。equals方法中还有另一个错误:不应将Integer对象与==进行比较,这会给您带来意想不到的结果。另外,将customerName设置为null的两个客户永远都不相等。 Objects.equals方法解决了这些问题。
return Objects.equals(this.customerNo, cus.customerNo) 
          && Objects.equals(this.customerName, cus.customerName);

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 ?


在这种情况下,所有对象实际上都将放置在同一存储桶中。您的HashSet被简化为一个链表数据结构,并且性能会很差:要找到客户对象,在最坏的情况下,数据结构必须将给定对象与每个对象进行比较。
如果Customer实现了Comparable,则哈希表存储桶可以使用二进制搜索树而不是链接列表,并且性能不会受到严重影响。

关于java - 如果哈希码等于实现不正确,我的对象创建会失败吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63092861/

相关文章:

java.sql.SQLSyntaxErrorException : You have an error in your SQL syntax; when inserting data into SQL database through JAVA

model-view-controller - 在MVC中,放授权码的正确位置在哪里?

swift - 如何避免重写父类(super class)初始值设定项

java - 是否可以使用 lambda 就地更改列表的值(无需创建新列表)?

java - 如何从嵌套的 ArrayList 访问特定元素

java - HashSet.clear() 未按预期工作

java - Android 中的处理程序和线程之间的区别以及处理程序是否创建单独的线程?

java - Quartz 从 00h35 到 06h15 停止预定的重复作业

php - 可扩展的基于规则的访问模式

Java 8 可选空检查