大学时候学到类里面重写equal必须重写hashCode,但为什么当时没深究。
做个实验:
student类:
package codeTest; import java.io.Serializable; public class Student implements Serializable{ /** * @Fields serialVersionUID : TODO(用一句话描述这个变量表示什么) */ private static final long serialVersionUID = 222122222222222L; private String name; private String passwd; private Node n; public final String getName() { return name; } public final void setName(String name) { this.name = name; } public final String getPasswd() { return passwd; } public final void setPasswd(String passwd) { this.passwd = passwd; } public final Node getN() { return n; } public final void setN(Node n) { this.n = n; } @Override public boolean equals(Object obj) { // TODO Auto-generated method stub return this.name.equals(((Student)obj).name); } // @Override // public int hashCode() { // // TODO Auto-generated method stub // return 3; // } public String toString(){ return "name:"+this.name+"\t"+"passwds:"+this.passwd+"\t"+"node:"+this.n+"\r\n"; } }
public static void main(String[] arge){ Student s1 = new Student(); Student s2 = new Student(); Set<Student> s = new HashSet<Student>(); s1.setName("123"); s2.setName("123"); Map<Student,Integer>m = new HashMap<Student,Integer>(); m.put(s1, 1); m.put(s2, 2); s1.setName("123"); System.out.println(m.get(s1)); System.out.println(m.get(s2)); s1.setPasswd("as"); System.out.println(m.get(s1)); // System.out.println(s.size()); // System.out.println(s1.equals(s2)); }
结果:
1 2 1
分析一下: 首先,在map的key里面放的时候,是根据hash值来决定取放的。如果只重写equal不重写hashCode,就会发生代码里面的事情: s1和s2明明是一个人,但是s1放在map里面的东西,s2就是取不出来。s1不是原来的s1了,我们不希望他还能取出来1,但如果不重写hashCode,map里面的1,只能由他取出来,也失去的map作为参数的特性。
这个往往发生在我们利用map保存值,甚至是传递值的时候。比如我们用s1保存一个值1,那么传递到别的方法的时候,对方应该能用s2取出来。但是如果不重载hashCode,那么在map里面的值只能用当初put时候那个对象取出来了。。。 鬼知道我们取map的时候那个put进去的对象还在不在了。。。 比如这样的代码:
m.put(new Student(“123”),1); 那这个map里面的值1 除非用遍历,否则这辈子取不出来的。。。。
如果重写hashCode,并令他返回定值,会发现不论你往map里面放什么值,map的size只有一个,因为map的key根据hashCode生成的,所有的student对象都会被映射到一个位置。
总结: 当我们不需要把对象放到map中当作key的时候,我们可以只重写equal而不必重写hashCode,不过谁知道以后的事会怎样? 重写equal的时候最好还是能重写hashCode,反正也简单。
重写hashCode而不重写equal,如果我们的对象永远不可能放到map的value里面和永远不会放到set等容器里面,那么也没问题。。。 不过这种代码。。。 自求多福吧