java重写object_java 重写Object中的hashCode方法-----转载

1 hashCode()用于返回调用该方法的对象的散列码值,此方法将返回整数形式的散列码值。2 在object类中,hashcode()方法是本地方法,返回的是对象的地址值,而object类中的equals()方法比较的也是两个对象的地址 值,如果equals()相等,说明两个对象地址值也相等,当然hashcode()也就相等了。一旦一个类重写equals()方法,通常也会重写 hashCode()方法。3

4 下面是重写hashCode()方法的约定的内容,来自Object规范[JavaSE6]:5

6 (1)、在应用程序的执行期间,只要对象的equals方法的比较操作所用到的信息没有被修改,那么对这同一个对象调用多次,hashCode方法都必须始终如一地返回同一个整数。在同一个应用程序的多次执行过程中,每次执行所返回的整数可以不一直。7

8 (2)、如果两个对象根据equals(Object)方法比较是相等的,那么调用这两个对象中任意一个对象的hashCode方法都必须产生同样的整数结果。9

10 (3)、如果两个对象根据equals(Object)方法比较是不相等的,那么调用这两个对象中任意一个对象的hashCode方法,则不一定要产生不同的整数结果。但是程序员应该知道,给不相等的对象产生截然不同的整数结果,有可能提高散列表的性能。11

12 总之只有一个目的:hashCode方法要为"不相等的对象产生不相等的散列吗"。下面我给出一个反例的代码。13

14 [java] view plain copy15 importjava.util.HashSet;16

17 public classUser {18 //用户名称

19 privateString userName;20 //用户密码

21 privateString password;22

23 publicUser(String userName, String password){24 this.userName =userName;25 this.password =password;26 }27

28 /**

29 * 覆盖equals方法30 */

31 public booleanequals(Object obj){32 if(obj == null){33 return false;34 }35 //如果是同一个对象返回true,反之返回false

36 if(this ==obj){37 return true;38 }39 //判断是否类型相同

40 if(this.getClass() !=obj.getClass()){41 return false;42 }43 User user =(User)obj;44 return userName.equals(user.userName) &&password.equals(user.password);45 }46

47 publicString toString(){48 //System.out.println(userName.hashCode() + " oooo");

49 return userName + ":" +password;50 }51

52 public static voidmain(String[] args) {53 HashSet set = new HashSet();54 User user01 = new User("xiaom", "1");55 User user02 = new User("xiaom", "1");56 User user03 = new User("xiaoh", "2");57 User user04 = new User("xiaoj", "3");58 set.add(user01);59 set.add(user02);60 set.add(user03);61 set.add(user04);62

63 System.out.println("对象的内容" + "\t\t" + "对象的散列码");64 for(User user : set){65 System.out.println(user.toString() + "\t\t" +user.hashCode());66 }67 }68 输出的结果:69

70 [java] view plain copy71 对象的内容 对象的散列码72 xiaoj:3 17510567

73 xiaom:1 6413875

74 xiaoh:2 827574

75 xiaom:1 21174459

76

77 这时候,我们可能期望只打印三个对象的值。由于我们重写了equals方法,所以user01对象和user02的对象是相等的。那么在hashSet集合中就应该只有三个元素。这是为什么呢?78

79 Java 中的集合类有两类:一类是List,一类是Set。前者允许集合内的元素可 以重复,后者则不允许集合中的元素可以重复。那么Java是如何判断集合中的元素是否重复呢?是通过对象中的equals()方法进行比较。但是,如果每 增加一个元素,都要进行一次equals比较。那么当集合中有很多元素时,就要进行很多次比较。也就是说,如果集合中有10000个元素,就得调用 10000次equals。这很明显降低了效率。于是,Java就采用了哈希表的原理,将数据依据指定的算法映射到一个地址上。这样一来,当集合要添加一 个元素时,只要调用该对象的hashCode方法,就可以找到指定的物理地址。如果该地址上没有元素,那么就将元素放在该地址上,不用再进行其他任何比较 了。如果该地址上有元素,那就调用equals方法进行比较,如果相同,则不需要添加改元素;如果不相同,就散列到其他地址。这样一来,实际调用 equals方法的次数就大大地减少了。80

81 我们再回过头看看刚刚的小例子。会出现那种错误,是因为我们没有重写hashCode方法。HashSet调用的是Object中的hashCode方法,而Object中的hashCode方法返回的是对象的地址值,所以HashSet认为user01对象与user02对象是不相等的,才在hashSet集合中出现4个对象。现在我们就来重写一下hashCode方法,看看效果如何,代码如下:82

83 [java] view plain copy84 importjava.util.HashSet;85

86 public classUser {87 //用户名称

88 privateString userName;89 //用户密码

90 privateString password;91

92 publicUser(String userName, String password){93 this.userName =userName;94 this.password =password;95 }96

97 /**

98 * 覆盖equals方法99 */

100 public booleanequals(Object obj){101 if(obj == null){102 return false;103 }104 //如果是同一个对象返回true,反之返回false

105 if(this ==obj){106 return true;107 }108 //判断是否类型相同

109 if(this.getClass() !=obj.getClass()){110 return false;111 }112 User user =(User)obj;113 return userName.equals(user.userName) &&password.equals(user.password);114 }115

116 /**

117 * 重写toString118 */

119 publicString toString(){120 return userName + ":" +password;121 }122

123 /**

124 * 重写hashCode125 */

126 public inthashCode(){127 int result = 17;128 result = 31 * result +userName.hashCode();129 result = 31 * result +password.hashCode();130 returnresult;131 }132

133 public static voidmain(String[] args) {134 HashSet set = new HashSet();135 User user01 = new User("xiaom", "1");136 User user02 = new User("xiaom", "1");137 User user03 = new User("xiaoh", "2");138 User user04 = new User("xiaoj", "3");139

140 set.add(user01);141 set.add(user02);142 set.add(user03);143 set.add(user04);144 System.out.println("对象的内容" + "\t\t" + "对象的散列码");145 for(User user : set){146 System.out.println(user.toString() + "\t\t" +user.hashCode());147 }148 }149 }150 输出的结果:151

152

153 [java] view plain copy154 对象的内容 对象的散列码155 xiaom:1 -759483308

156 xiaoh:2 -759483462

157 xiaoj:3 -759483399

158 执行结果正确,收工。159

160 顶161 0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值