csdngxl 2021-11-02 22:03 采纳率: 92.9%
浏览 83
已结题

Object类存入HashSet,重写equals方法。

我重写的equals方法,但为什么运行结果还有重复的?

package Test_05;
import java.util.HashSet;
import java.util.Iterator;
class Person{
    private String name;
    private int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    // 重写hashCode方法,返回name属性的哈希值
    public int hashCode(){
        return name.hashCode();
    }
    // 重写equals方法
    public boolean equals(Object obj){
        if(this.name == obj)
            return true;
        return false;
    }
    public String toString(){
        return "Person  " + name + age;
    }
}
public class T5_10 {
    public static void main(String[] args) {
        // 创建HashSet对象
        HashSet hs = new HashSet();
        // 将Person对象存入集合
        hs.add(new Person("lisa", 21));
        hs.add(new Person("lisi", 32));
        hs.add(new Person("lisi", 32));
        hs.add(new Person("leilei", 31));
        hs.add(new Person("lusi", 25));
        hs.add(new Person("lusi", 25));
        // 遍历集合中的元素
        Iterator it = hs.iterator();
        while (it.hasNext()) {
            Person p = (Person) it.next();
            System.out.println(p);
        }
    }
}

img

img

  • 写回答

2条回答 默认 最新

  • Tomshidi 2021-11-02 22:28
    关注

    问题出在你重写的equals方法上,17行的 this.name == obj 换成this.name == ((Person) obj).name就不会有重复值了。
    解析:
    HashSet底层用的是HashMap中key的存储方式,先看HashMap源码中的put方法关键代码。

    img

    源码中判断两个对象是否相等的条件:
    两个对象的hashCode相等,并且==或者equals判断相等
    这里又引申出==与equals的区别。
    ==比较的是两对象的内存地址,equals是可以由开发者自己定义判断逻辑的比较方法。
    你放进HashMap里的Person对象,每一个都有自己独立的地址空间,即内存地址不同。很明显,==判定为不同的对象,可以同时放进HashMap中。又因为你重写的equals方法中也是用的==,
    导致equals实际上是用Person这个对象的name属性与Person对象比较,当然是判定为不同的对象,即可以同时存在于HashMap中
    由以上分析得出,将equals中的this.name == obj 换成this.name == ((Person) obj).name即可解决问题。
    实际上这里还涉及到了字符串常量池的问题,有兴趣你可以去百度看看相关博客,我这里展开就太多了。
    String更推荐用这种比较形式 this.name.equals(((Person) obj).name)

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 11月11日
  • 已采纳回答 11月3日
  • 创建了问题 11月2日

悬赏问题

  • ¥500 高有偿提问!求优化设计微信小程序
  • ¥15 matlab在安装时报错 无法找到入口 无法定位程序输入点
  • ¥15 收益高的广告联盟有哪些
  • ¥15 Android Studio webview 的使用问题, 播放器横屏全屏
  • ¥15 删掉jdk后重新下载,Java web所需要的eclipse无法使用
  • ¥15 uniapp正式环境中通过webapi将本地数据推送到设备出现的跨域问题
  • ¥15 xui建立节点,显示错误
  • ¥15 关于#单片机#的问题:开始、复位、十进制的功能可以实现,但是切换八进制的功能无法实现(按下按键也没有效果),把初始状态调成八进制,也是八进制可以实现但是切换到十进制不行(相关搜索:汇编语言|计数器)
  • ¥15 VINS-Mono或Fusion中feature_manager中estimated_depth是特征的深度还是逆深度?
  • ¥15 谷歌浏览器如何备份抖音网页数据