Java 基础 - hashCode()在什么场景下需要重写?
总结
在自定义中,重写hashCode()不需要加@Override.
因为Object.hashCode()并不是abstract函数。
在java中,hashCode()方法的主要作用是为了配合基于散列的集合一起正常运行,这样的散列集合包含HashSet、HashMap以及HashTable。
- 当你的自定义类Customer,要作为散列集合(HashSet、HashMap以及HashTable)的key时,就需要重写hashCode()方法。
- 不然,同一个Customer对象,哪怕其属性值发生了改变,其的hashCode始终一致。
- 因为在自定义类Customer没重写hashCode()时,其默认调用本地native方法 Object.hashCode(),同一个对象始终返回同一个hashCode
以我们最常用的HashMap为例,如果Customer不重写hashCode(), 很容易造成多个对象hash值相同,当这些对象在hashmap中当为key保存,其value会被“不经意”地覆盖。
不重写hashCode()
不重写时,hashCode 始终一致,所以往HashMap加入元素时,会覆盖前值
public class Solution { public static class Customer { private String username; private int age; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } public static void main(String[] args) { System.out.println("打印对象Customer的hashCode值----------->"); HashMap<Customer, Integer> map = new HashMap<>(); Customer customer = new Customer(); System.out.println(customer.hashCode()); map.put(customer,1); customer.setAge(10); System.out.println(customer.hashCode()); map.put(customer,2); customer.setUsername("张三"); System.out.println(customer.hashCode()); map.put(customer,3); customer.setUsername("张"); System.out.println(customer.hashCode()); map.put(customer,4); customer.setAge(8); System.out.println(customer.hashCode()); map.put(customer,5); // size = 1 System.out.println("HashMap size ----------->" + map.size()); } }
输出:
打印对象Customer的hashCode值----------->
1761291320
1761291320
1761291320
1761291320
1761291320
HashMap size ----------->1
重写hashCode()
重写时,hashCode随着对象属性的改变而改变,所以往HashMap加入元素时,不会覆盖前值。
public class Solution { public static class Customer { private String username; private int age; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int hashCode(){ String temp = this.username + this.age; return temp.hashCode(); } } public static void main(String[] args) { System.out.println("打印对象Customer的hashCode值----------->"); HashMap<Customer, Integer> map = new HashMap<>(); Customer customer = new Customer(); System.out.println(customer.hashCode()); map.put(customer,1); customer.setAge(10); System.out.println(customer.hashCode()); map.put(customer,2); customer.setUsername("张三"); System.out.println(customer.hashCode()); map.put(customer,3); customer.setUsername("张"); System.out.println(customer.hashCode()); map.put(customer,4); customer.setAge(8); System.out.println(customer.hashCode()); map.put(customer,5); // size = 5 System.out.println("HashMap size ----------->" + map.size()); } }
输出:
打印对象Customer的hashCode值----------->
105180041
-1034385946
744669896
23403839
754968
HashMap size ----------->5
posted on 2020-08-26 00:06 frank_cui 阅读(1311) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?