关于equals()跟hashcode()方法的一些实验

关于equals()和hashcode()方法的一些实验

1、新建一Student.java,包含3个field,和相应的get、set方法。

package t;

public class Student{
	
	private String id;
	private String name;
	private int age;

	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}	
}

 

2、不重写equals()方法,进行测试。

package t;

public class Test2 {

	public static void main(String[] args){
		
		Student s1 = new Student();
		s1.setId("001");
		
		Student s2 = new Student();
		s2.setId("001");
		
		System.out.println(s1.equals(s2));
	}
}

 

此时,执行结果是false。

如果不重写equals方法,将默认使用父类的equals方法进行比较,而父类Object的equals()方法如下:

 public boolean equals(Object obj) {
	return (this == obj);
    }

即,在Object中执行equals比较时,实际上是用双等号进行比较的,实质上比较的两个对象是否同一个对象,由于s1和s2是分别new出来的2个对象,所以,双等号是不成立的,故而输出结果是false。

 

3、在Student中重写equals()方法。

@Override
	public boolean equals(Object anObject) {
		if (this == anObject) {
		    return true;
		}
		if (anObject instanceof Student) {
			Student anotherStudent = (Student)anObject;
			
			//只要2个学生的学生编号相同,则认为2个对象相同。
			return this.getId().equals(anotherStudent.getId());
		}
		return false;    
	}

   

此时再行测试,结果是true。

 

4、重写equals(),不重写hashcode()

 

测试代码:

package t;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class Test2 {

	public static void main(String[] args){
		
		Student s1 = new Student();
		s1.setId("001");
		
		Student s2 = new Student();
		s2.setId("001");
		
		//关于HashSet的测试
		Set<Student> set = new HashSet<Student>();
		set.add(s1);
		System.out.println(set.contains(s2));

		//关于HashMap的测试
		Map<Student, Student> map = new HashMap<Student, Student>();
		map.put(s1, s1);
		System.out.println(map.containsKey(s2));
		System.out.println(map.containsValue(s2));
	}
}

 

执行结果:

false
false
true
 

 

 5、重写equals(),并且重写hashcode()。

 

	@Override
	public int hashCode() {	
		return 1;
	}

 

输出结果

true
true
true

 

综上,重写equals()一定要同时重写hashcode(),否则在hash集合中,会出现与预期不一致的结果。

 

补充说明:String之所以可以直接使用equals()比较两个String对象的值是否相等,是因为在String类中已经对equals()方法进行了重写。

 

 /**
     * Compares this string to the specified object.  The result is {@code
     * true} if and only if the argument is not {@code null} and is a {@code
     * String} object that represents the same sequence of characters as this
     * object.
     *
     * @param  anObject
     *         The object to compare this {@code String} against
     *
     * @return  {@code true} if the given object represents a {@code String}
     *          equivalent to this string, {@code false} otherwise
     *
     * @see  #compareTo(String)
     * @see  #equalsIgnoreCase(String)
     */
    public boolean equals(Object anObject) {
	if (this == anObject) {
	    return true;
	}
	if (anObject instanceof String) {
	    String anotherString = (String)anObject;
	    int n = count;
	    if (n == anotherString.count) {
		char v1[] = value;
		char v2[] = anotherString.value;
		int i = offset;
		int j = anotherString.offset;
		while (n-- != 0) {
		    if (v1[i++] != v2[j++])
			return false;
		}
		return true;
	    }
	}
	return false;
    }

 

 

 http://huangqiqing123.iteye.com/blog/1462404