为什么要重写equals和hashcode方法

本文探讨了为何在Java中重写equals方法的同时需要重写hashCode,通过实例演示了未重写和仅重写其中一个方法时可能出现的问题,以及正确重写两者以避免哈希冲突和重复元素的重要性。

为什么重写equals方法还要重写hashcode方法

举例说明

只重写equals方法

class B {
    private String name;
    public B(String name) {this.name = name;}
    public boolean equals(Object o) {
        if (this == o) return true;
        B b = (B) o;
        return name == b.name;
    }
}
B b1 = new B("1");
B b2 = new B("1");
System.out.println(b1.equals(b2)); // true
System.out.println(b1.hashCode()); // 460141958
System.out.println(b2.hashCode()); // 1163157884
// 会发现,它们内容相同了,但是hash值却不相同
// 如果这时使用B类元素来作为Map集合的key,那么map中就会存在重复内容的元素
// 因为map是跟据hash来计算索引位置的,而这时它们的hash值不相同,所以可以直接添加到map集合中(hash不同索引位置不同)
【跟据hash来计算索引位置是java开发者为了减少hash冲突概率的一种算法】

只重写hashcode方法

class C {
    private String name;
    public C(String name) {
        this.name = name;
    }
    public int hashCode() {
        return Objects.hash(name);
    }
}
C c1 = new C("1");
C c2 = new C("1");
System.out.println(c1.hashCode()); // 80
System.out.println(c2.hashCode()); // 80
System.out.println(c1.equals(c2)); // false
/*
	可以看出上面hash值相同了,但是equals比较它们却不相同,默认equals方法比较的是内存地址
	假设现在用C类元素作为hashMap集合的key,c1已经添加到容器中了,这时添加c2,当它们判断到它们key相同时,就会继	  续调用C类中的equals方法来比较 因为没有重写,所以比较的是c1和c2的内存地址,因为不同,所以添加成功了。
	但是这种情况下是不允许的,为什么。
	因为它们的内容 name属性都是"1", 从人类思维上来说,它们的内容是一样的啊,按理说一样的属性equals应该判断为
	true才对,但是因为equals方法默认比较的是内存地址
	所以这个时候需要重写equals方法来比较它们的name属性是否相同。这个时候计算机就知道c1和c2它们的内容是相同的
*/

重写equals和hashcode方法

class D {
    private String name;
    public D(String name) {this.name = name;}
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        D d = (D) o;
        return name == d.name;
    }
    public int hashCode() {
        return name.hashCode();
    }
}
D d1 = new D("1");
D d2 = new D("1");
System.out.println(d1.equals(d2)); // true
System.out.println(d1.hashCode()); // 49
System.out.println(d2.hashCode()); // 49
/*
	在重写了两个方法后,我们来用D类作为hashMap的key来使用
	当d1添加进去后,又添加了d2时,这时会通过hash值计算出当前元素在容器中的索引位置,因为hash值相同,所以在d1	
	添加的时候,假设它的索引位置时4,这时d2也通过计算后其索引也为4,这时就会判断d1和d2的hash值是否相同,相同则		继续比较它们的内容是否相同,就会调用D类中的equals方法,比较的是它们内部的name属性是否相同,又因为name属性是
	字符串类型,所以"1"值指向都是常量池中同一个对象,最后执行 return name == d.name; 比较后发现它们的name属性	相同,所以hashmap就会认为当前要添加的元素的key在容器中已经存在,那么就会将新的元素覆盖掉容器中已存在的元素。
*/

结论:在确保不允许有重复元素的情况下,必须重写两个方法。

基于径向基函数神经网络RBFNN的自适应滑模控制学习(Matlab代码实现)内容概要:本文介绍了基于径向基函数神经网络(RBFNN)的自适应滑模控制方法,并提供了相应的Matlab代码实现。该方法结合了RBF神经网络的非线性逼近能力滑模控制的强鲁棒性,用于解决复杂系统的控制问题,尤其适用于存在不确定性外部干扰的动态系统。文中详细阐述了控制算法的设计思路、RBFNN的结构与权重更新机制、滑模面的构建以及自适应律的推导过程,并通过Matlab仿真验证了所提方法的有效性稳定性。此外,文档还列举了大量相关的科研方向技术应用,涵盖智能优化算法、机器学习、电力系统、路径规划等多个领域,展示了该技术的广泛应用前景。; 适合人群:具备一定自动控制理论基础Matlab编程能力的研究生、科研人员及工程技术人员,特别是从事智能控制、非线性系统控制及相关领域的研究人员; 使用场景及目标:①学习掌握RBF神经网络与滑模控制相结合的自适应控制策略设计方法;②应用于电机控制、机器人轨迹跟踪、电力电子系统等存在模型不确定性或外界扰动的实际控制系统中,提升控制精度与鲁棒性; 阅读建议:建议读者结合提供的Matlab代码进行仿真实践,深入理解算法实现细节,同时可参考文中提及的相关技术方向拓展研究思路,注重理论分析与仿真验证相结合。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值