java中的equal和hashCode

         大学时候学到类里面重写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等容器里面,那么也没问题。。。 不过这种代码。。。  自求多福吧

猜你喜欢

转载自709002341.iteye.com/blog/2257979