Equals and Hashcode

本文通过测试代码展示了equals方法和hashcode方法的区别及其联系。强调了在覆盖equals方法时也应覆盖hashcode方法的重要性,特别是在集合操作中。通过具体实例说明了不同实现方式对集合的影响。
同事问了个关于equals和hashcode的问题,我写了个测试说明了一下有啥不同,为什么SUN的文档会说改写equals方法要改写hashcode方法(不改写当然可以,但在使用中会有些不一样的地方,从下面的代码可以看出来),要求equals为true时,hashcode值一样,equals为假时,hashcode并不要求一定要不一样。下面给出测试代码与测试结果来说明:
 
package test;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class EqualsNHashcodeTest {
 public static void main(String[] args) {
  Set<SampleModel> s1 = new HashSet<SampleModel>();
  Set<SampleModel1> s2 = new HashSet<SampleModel1>();
  Set<SampleModel2> s3 = new HashSet<SampleModel2>();
  List<SampleModel> l1 = new ArrayList<SampleModel>();
  List<SampleModel1> l2 = new ArrayList<SampleModel1>();
  List<SampleModel2> l3 = new ArrayList<SampleModel2>();
  List<SampleModel> l4 = new ArrayList<SampleModel>();
  List<SampleModel1> l5 = new ArrayList<SampleModel1>();
  List<SampleModel2> l6 = new ArrayList<SampleModel2>();
  Set<SampleModel> s4 = new HashSet<SampleModel>();
  Set<SampleModel1> s5 = new HashSet<SampleModel1>();
  Set<SampleModel2> s6 = new HashSet<SampleModel2>();
  SampleModel m1 = new SampleModel("anny");
  SampleModel m2 = new SampleModel("lily");
  SampleModel m3 = new SampleModel("lily");
  SampleModel1 n1 = new SampleModel1("anny");
  SampleModel1 n2 = new SampleModel1("lily");
  SampleModel1 n3 = new SampleModel1("lily");
  SampleModel2 p1 = new SampleModel2("anny");
  SampleModel2 p2 = new SampleModel2("lily");
  SampleModel2 p3 = new SampleModel2("lily");
  System.out.println(m2.equals(m3));
  System.out.println(p2.equals(p3));
  System.out.println(p2 + " vs " + p3);
  System.out.println(p2 == p3);
  s1.add(m1);
  s1.add(m2);
  s1.add(m3);
  System.out.println(s1);
  l1.add(m1);
  l1.add(m2);
  l1.add(m3);
  System.out.println(l1);
  s2.add(n1);
  s2.add(n2);
  s2.add(n3);
  System.out.println(s2);
  l2.add(n1);
  l2.add(n2);
  l2.add(n3);
  System.out.println(l2);
  s3.add(p1);
  s3.add(p2);
  s3.add(p3);
  System.out.println(s3);
  l3.add(p1);
  l3.add(p2);
  l3.add(p3);
  System.out.println(l3);
  l4.add(m1);
  l4.add(m2);
  System.out.println(l4.contains(m1));
  System.out.println(l4.contains(m2));
  System.out.println(l4.contains(m3));
  l5.add(n1);
  l5.add(n2);
  System.out.println(l5.contains(n1));
  System.out.println(l5.contains(n2));
  System.out.println(l5.contains(n3));
  l6.add(p1);
  l6.add(p2);
  System.out.println(l6.contains(p1));
  System.out.println(l6.contains(p2));
  System.out.println(l6.contains(p3));
  
  s4.add(m1);
  s4.add(m2);
  System.out.println(s4.contains(m1));
  System.out.println(s4.contains(m2));
  System.out.println(s4.contains(m3));
  s5.add(n1);
  s5.add(n2);
  System.out.println(s5.contains(n1));
  System.out.println(s5.contains(n2));
  System.out.println(s5.contains(n3));
  s6.add(p1);
  s6.add(p2);
  System.out.println(s6.contains(p1));
  System.out.println(s6.contains(p2));
  System.out.println(s6.contains(p3));
 }
}
class SampleModel {
 String name;
 public SampleModel(String name) {
  this.name = name;
 }
 @Override
 public boolean equals(Object obj) {
  if (!(obj instanceof SampleModel))
   return false;
  SampleModel s = (SampleModel) obj;
  return this.name.equals(s.name);
 }
}
class SampleModel1 {
 String name;
 public SampleModel1(String name) {
  this.name = name;
 }
 @Override
 public int hashCode() {
  char[] cs = this.name.toCharArray();
  int temp = 0;
  for (char c : cs) {
   temp += Integer.MAX_VALUE % (int) c;
  }
  return temp;
 }
}
class SampleModel2 {
 public SampleModel2(String name) {
  this.name = name;
 }
 String name;
 @Override
 public boolean equals(Object obj) {
  if (!(obj instanceof SampleModel2))
   return false;
  SampleModel2 s = (SampleModel2) obj;
  return this.name.equals(s.name);
 }
 @Override
 public int hashCode() {
  char[] cs = this.name.toCharArray();
  int temp = 0;
  for (char c : cs) {
   temp += Integer.MAX_VALUE % (int) c;
  }
  return temp;
 }
}
 
编译及运行结果:
E:\PlatEclipseWorkSpace\TestProject>javac test/EqualsNHashcodeTest.java
E:\PlatEclipseWorkSpace\TestProject>java test.EqualsNHashcodeTest
true
true
test.SampleModel2@125 vs test.SampleModel2@125
false
[test.SampleModel@61de33, test.SampleModel@ca0b6, test.SampleModel@14318bb]
[test.SampleModel@61de33, test.SampleModel@14318bb, test.SampleModel@ca0b6]
[test.SampleModel1@120, test.SampleModel1@125, test.SampleModel1@125]
[test.SampleModel1@120, test.SampleModel1@125, test.SampleModel1@125]
[test.SampleModel2@120, test.SampleModel2@125]
[test.SampleModel2@120, test.SampleModel2@125, test.SampleModel2@125]
true
true
true
true
true
false
true
true
true
true
true
false
true
true
false
true
true
true
 
看下代码对下结果应该比较好理解,就不写很详细的注释了。而且注意LIST与SET中的不同。
更详细的建议去看文档和源代码,再对不明确的地方做下测试会更清楚些。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值