同事问了个关于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;
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>();
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");
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");
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);
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);
s1.add(m2);
s1.add(m3);
System.out.println(s1);
l1.add(m1);
l1.add(m2);
l1.add(m3);
System.out.println(l1);
l1.add(m2);
l1.add(m3);
System.out.println(l1);
s2.add(n1);
s2.add(n2);
s2.add(n3);
System.out.println(s2);
s2.add(n2);
s2.add(n3);
System.out.println(s2);
l2.add(n1);
l2.add(n2);
l2.add(n3);
System.out.println(l2);
l2.add(n2);
l2.add(n3);
System.out.println(l2);
s3.add(p1);
s3.add(p2);
s3.add(p3);
s3.add(p2);
s3.add(p3);
System.out.println(s3);
l3.add(p1);
l3.add(p2);
l3.add(p3);
System.out.println(l3);
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));
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));
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));
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));
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));
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;
}
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);
}
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;
String name;
public SampleModel1(String name) {
this.name = 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;
}
}
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;
}
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);
}
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;
}
}
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
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中的不同。
更详细的建议去看文档和源代码,再对不明确的地方做下测试会更清楚些。