Java对自定义类对象进行equals判断的注意事项

在 Java 中,自定义类是指开发人员自己定义的类,而不是Java语言中内置的类。在自定义类中,如果要将自定义类用作 Map 的键或 Set 的元素,那么必须要重写 equals 方法和 hashCode 方法

重写 equals 方法和 hashCode 方法是为了保证自定义类的正确性。在 Java 中,MapSet 等容器类使用 equals 方法来比较两个对象是否相等,使用 hashCode 方法来计算对象的哈希值。如果没有重写 equals 方法和 hashCode 方法,那么默认的 equals 方法和 hashCode 方法可能会导致一些问题。

首先,默认的 equals 方法只比较对象的引用,而不是对象的属性值。如果自定义类中有多个属性,这可能会导致一些问题。例如,如果两个对象只有一个属性不同,那么它们的 equals 方法会返回 true ,从而导致 MapSet 中出现重复元素。其次,默认的 hashCode 方法也存在同样的问题。

因此,为了保证自定义类的正确性,必须要重写 equals 方法和 hashCode 方法。在重写 equals 方法和 hashCode 方法时,需要考虑自定义类的所有属性,并返回一个 布尔值 和一个 整数值

  • 示例 1:自定义类中只有单个属性
public class CustomClazz {
    private final String key;
    
    public CustomClazz(String key) {
        this.key = key;
    }
    
    public String getKey() { return key; }
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if ((obj == null) || getClass != obj.getClass()) return false;
        
        return key.equals((CustomClazz) obj.key);
    }
    
    @Override
    public int hashCode() {
        return key.hashCode();
    }
}
  • 示例2:自定义类中有多个属性
public class CustomClazz {
    private final String key1;
    private final String key2;
    
    public CustomClazz(String key1, String key2) {
        this.key1 = key1;
        this.key2 = key2;
    }
    
    public String getKey1() { return key1; }
    public String getKey2() { return key2; }
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if ((obj == null) || getClass != obj.getClass()) return false;
        
        if (!key1.equals((CustomClazz) obj.key1)) return false;
        return key2.equals((CustomClazz) obj.key2);
        
        // 或者直接新建一个临时对象 
        // CustomClazz that = (CustomClazz) obj;
        // if (!key1.equals(that.key1)) return false;
        // return key2.equals(that.key2);
    }
    
    @Override
    public int hashCode() {
        int result = key1.hashCode();
        result = 31 * result + key2.hashCode();
        
        return result;
    }
}

至于为什么在哈希值计算时用到了 31 31 31 这个数,由于本人数学水平实在不咋地,我只能大概的说是因为 31 31 31 是一个不大不小的质数,且可以被 JVM 优化成位移运算,即 31 * i = (i << 5) -i,想要深入探究,建议百度 😝

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值