自定义对象需要重写hashcode

本文探讨了在Java编程中,自定义对象如何通过重写equals和hashCode方法来确保在hash集合中对象的正确比较和标识。通过实例展示了不重写hashCode方法可能导致的误解,并强调了在实现这些方法时的注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java中的很多对象都override了equals方法,都知道,这是为了能比较两个对象是否相等而定义,如果不需要比较,则不需要定义equals方法。比如StringBuffer类,没有提供equals方法,则说明没有两个StringBuffer对象是相等的。再比如Collections类,全部是静态方法,根本没必要创建对象,所以也就没有提供equals方法。
      我们程序中自定义的对象有时候需要比较它们是否相等,也需要重写equals方法。如果我们要将对象放到HashMap或者Hashtable这样的hash集合中的时候,就需要重写hashcode方法了。因为它们是根据hashcode来标识对象的。
      如果我们不重写hashcode方法,把他们作为key放入hashmap中是什么情况呢?看看下面代码:

Java代码 
  1. import java.util.HashMap;  
  2.   
  3. public class HashTest {  
  4.   
  5.     public static void main(String...args) {  
  6.         MyBean a = new MyBean();  
  7.         a.x = 1;  
  8.         a.s = "xyz";  
  9.         MyBean b = new MyBean();  
  10.         b.x = 1;  
  11.         b.s = "xyz";  
  12.         HashMap<MyBean, String> map = new HashMap<MyBean, String>();  
  13.         map.put(a, "a");  
  14.         map.put(b, "b");  
  15.         System.out.println("a equals b:"+a.equals(b));  
  16.         System.out.println("map size:"+map.size());  
  17.         System.out.println("a:"+map.get(a));  
  18.         System.out.println("b:"+map.get(b));  
  19.     }  
  20. }  
  21.   
  22. class MyBean {  
  23.     int x;  
  24.     String s;  
  25.     @Override  
  26.     public boolean equals(Object obj) {       
  27.         if(this == obj) return true;  
  28.         if(!(obj instanceof MyBean)) return false;  
  29.         if(((MyBean)obj).x == x) return true;  
  30.         return false;  
  31.     }  
  32. }  

      结果如下:

a equals b:true
map size:2
a:a
b:b  

      a和b明明是相等的,可是放进hashmap中之后,却被认为是两个对象,很诡异哦。
      下面加上hashcode,再看看什么结果:

Java代码   收藏代码
  1. class MyBean {  
  2.     int x;  
  3.     String s;  
  4.     @Override  
  5.     public boolean equals(Object obj) {       
  6.         if(this == obj) return true;  
  7.         if(!(obj instanceof MyBean)) return false;  
  8.         if(((MyBean)obj).x == x) return true;  
  9.         return false;  
  10.     }  
  11.     @Override  
  12.     public int hashCode() {  
  13.         return (s!=null?s.hashCode():1)*31+x;  
  14.     }  
  15. }  

     结果如下:

a equals b:true
map size:1
a:b
b:b

 

      这样才保证了相等的对象在hash集合中也相等。计算hashcode的时候,一般使用关键的属性的hashcode值。计算hashcode的属性较多则计算复杂,降低了效率,若较少的属性计算,则重复的hashcode较多,同样降低性能,写一个好的hashcode方法,还比较难。
      所以,我们重写equals的时候,一定要重写hashcode方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值