今天想要进行实体类集合,结果我list强制转型set报错了,然后我new HashSet<>(list);
这个虽然没报错,但是这个却没有实现去重。
有懂底层的能科普么?
为什么想要实现list实体转set实体去重,要重写hashcode和equals方法?
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
2条回答 默认 最新
- 走一步-再走一步 2021-07-17 22:19关注
HashSet的底层其实是封装了HashMap,而 new HashSet<>(list)
底层就是调用了addAll 方法
addAll 底层调用了add 方法,add 又调用了HashMap的 put(key,val) 方法
HashMap 底层是数组+链表的结构
其中如何判断map 中是否已经有值也就是所谓的去重 判断方法如下- 计算 key 的hashCode值,在hashMap中找到 该key 存放在数组的位置的元素 p,然后判断
元素p的hashCode值是否和需要添加的元素key 的hashCode值是否一致
如果一致,再去判断 需要添加的key 和 p的key的 是否是同一个对象如果不是同一个对象,那么 调用equals 是否相等
如果相等了,用新的值 替换掉旧的值
判断是否相等的逻辑如下:
p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))
也就是说,重写了hashCode 和 equals 能实现去重,如果没有重写 equals ,只能 实现是同一个对象的去重,
举个栗子
class A{
String name;
public A(String name){
this.name = name;
}
}不重写equals的话,
A a = new A("wu");
A b = new A("wu");在 HashMap中 哪怕 a和b的hashCode值相等
但是 后续判断 a ==b 为false,因为a 和b的地址并不一样,
a.equals(b) 也是false,因为没有重写 equals,那么该方法继承自 Object
方法定义如下:public boolean equals(Object obj) { return (this == obj); }
其实还是判断地址是否一致
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 2无用 - 计算 key 的hashCode值,在hashMap中找到 该key 存放在数组的位置的元素 p,然后判断
悬赏问题
- ¥15 删除虚拟显示器驱动 删除所有 Xorg 配置文件 删除显示器缓存文件 重启系统 可是依旧无法退出虚拟显示器
- ¥15 vscode程序一直报同样的错,如何解决?
- ¥15 关于使用unity中遇到的问题
- ¥15 开放世界如何写线性关卡的用例(类似原神)
- ¥15 关于并联谐振电磁感应加热
- ¥60 请查询全国几个煤炭大省近十年的煤炭铁路及公路的货物周转量
- ¥15 请帮我看看我这道c语言题到底漏了哪种情况吧!
- ¥66 如何制作支付宝扫码跳转到发红包界面
- ¥15 pnpm 下载element-plus
- ¥15 解决编写PyDracula时遇到的问题