免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1791 | 回复: 3
打印 上一主题 下一主题

Java equals()和hashCode()的作用 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-02-26 21:58 |只看该作者 |倒序浏览
Java equals()和hashCode()的作用









Object的方法 equals()和hashCode() 是用来判断两个对象是否相等。基础类型判断是否相等时,使用“==”来判断,按java的说话,“==”当用来判断是基础类型是判断内容的,而引用对象是判断内存地址的。一般情况我们之间继承Object的默认方法是可以的。但是,某些情况是要我们Override的。特别是在处理java集合时。按java的集合分类:List,Set,Map 其中List是有序的,可以有重复项的。如ArrayList。Set 是无序的并且不允许有重复项的。Map 是个键值对,也是对key有要求的。这边主要说Set因为他不允许重复项。

当我们使用自定义类型时,在add到Set时,就需要我们自己处理一下对象是否相等的情况。一般情况下,我们多是使用下面类似的代码
  1.         UserInfo i1=new UserInfo("zz",11);
  2.                 UserInfo i2=new UserInfo("zz",11);
  3.                
  4.                
  5.                 Set s=new HashSet();
  6.                 s.add(i1);
  7.                 s.add(i2);
  8.                 //判断i1的内容是否和i2的相等
  9.                 System.out.println( i1.equals(i2));
  10.                 //i1的hashCode
  11.                 System.out.println( i1.hashCode());
  12.                 //i2的hashCode
  13.                 System.out.println( i2.hashCode());
  14.                 //S 集合的元素个数
  15.                 System.out.println(s.size());
复制代码
其中UserInfo 是我们自定义类型。具体定义如下

  1. public class UserInfo {

  2.         private String userName;
  3.         private int userAge;
  4.        
  5.         public UserInfo(String userName, int userAge) {
  6.                 super();
  7.                 this.userName = userName;
  8.                 this.userAge = userAge;
  9.         }

  10.         @Override
  11.         public boolean equals(Object obj)
  12.         {
  13.                 if(obj==this)
  14.                         return true;
  15.                 UserInfo userinfo=(UserInfo)obj;
  16.                 if(userName.equals(userinfo.getUserName()) && userAge==userinfo.getUserAge())
  17.                         return true;
  18.                 return false;
  19.         }
  20.        
  21.        
  22.         @Override
  23.         public String toString() {
  24.                 // TODO Auto-generated method stub
  25.                 //return super.toString();
  26.                 return "UserInfo UserName:"+getUserName()+"UserAge:"+getUserAge();
  27.         }
  28.         public String getUserName() {
  29.                 return userName;
  30.         }
  31.         public void setUserName(String userName) {
  32.                 this.userName = userName;
  33.         }
  34.         public int getUserAge() {
  35.                 return userAge;
  36.         }
  37.         public void setUserAge(int userAge) {
  38.                 this.userAge = userAge;
  39.         }
  40.        
  41. }
复制代码
请注意,UserInfo 我并没有Override hashCode这个函数,只是重写了equals。所以第一步的代码输出结果是

true  //i1和i2的内容是相等
33263331 //i1的hashCode
6413875 //i2的hashCode
2 //s的元素个数

默认情况 是我们要同时重写 equals和hashCode的函数。要不就会出现上面的情况,按规定两个值的内容相等的对象应该就是同一个对象(这个话可能会有歧义)。也就是 hashCode相等 一定是同一个对象。但是反之缺不一定。

Set  集合是按hashCode来判断对象是否相等的。所以,我们要重写 hashCode 如下:
  1. @Override
  2.         public int hashCode()
  3.         {
  4.                 final int offer=31;
  5.                
  6.                 return userAge*userName.hashCode()*offer;
  7.                
  8.         }
复制代码
其实好对人对java默认的hashCode 不是太明白为啥要那么复杂,其实就是按自己的一个规则生成一个int值就行。

当我们复写了hashCode以后,马上我们的输出结果就不一样了。

true
1331264
1331264
1

这样就达到了我们的目的了。内容相同就应该hashCode也一样。这样Set add的时候就只会插入一个,另一个会自动过滤掉。并不会出异常。这点需要注意一下。

基本说完了。发个牢骚,就因为这个问题,完美世界的某个黄XX程序经理装B一样一直问我,鄙视这样的SB,这样的东西只要做过一次就不会有太大的问题。他还当发明原子弹一样高深的来问。干。

论坛徽章:
0
2 [报告]
发表于 2012-02-26 21:58 |只看该作者
谢谢分享

论坛徽章:
1
数据库技术版块每日发帖之星
日期:2016-04-28 06:20:00
3 [报告]
发表于 2012-09-05 18:36 |只看该作者
非常感谢,该发一发牢骚

论坛徽章:
0
4 [报告]
发表于 2012-09-05 20:14 |只看该作者
不错,有用。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP