Java_集合_HashCode

1.现象

public class Test {
	public static void main(String[] args) {
		Set col = new HashSet();
		
		Person p1 = new Person(11);
		Person p2 = new Person(12);
		Person p3 = new Person(13);
		Person p4 = new Person(11);
		
		col.add(p1);
		col.add(p2);
		col.add(p3);
		col.add(p4);	//Person的HashCode()方法根据age判断,故添加不成功

		p2.setAge(200);
		System.out.println(col.remove(p2));//此处移除失败
	}
}
        为什么在集合中移除元素失败?

2.HashCode的作用

        如果需要查找一个集合中是否包含一个元素,如果集合的数量很大,势必导致查询的效率很低。使用Hash算法可以改善,将集合分成若干个存储区域,每个对象可以计算出一个哈希值,分组重查询对应存储区域,查询效率提高!

3.原因分析

        col.remove(p2);//会自动进行equals比较,即p2重新计算的HashCode值如果在HashTable中存在(可能该值所对应的对象不同),则可以移除,否则移除不成功!

        如果remove为false,即实际已经存在于类存中,但却移除失败,必将导致该部分内存溢出

public class My {
	public static void main(String[] args) {
		Set col = new HashSet();
		Person p1 = new Person(11);
		Person p2 = new Person(12);
		Person p3 = new Person(13);
		Person p4 = new Person(11);
		col.add(p1);
		col.add(p2);
		col.add(p3);
		col.add(p4);

		p2.setAge(200);
		System.out.println(col.remove(p2));	//导致哈希值不存在,equals方法返回false

		System.out.println("===============================");

		p2.setAge(12);	//重新修改为原来的
		System.out.println(col.remove(p2));	//重新计算的哈希值存在,equals方法返回true
	}
}
class Person{
	private int age;
	Person(int age){
		this.age = age;
	}
	public int getAge(){
		return age;
	}
	public void setAge(int age){
		this.age = age;
	}
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		return result;
	}
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		if (age != other.age)
			return false;
		return true;
	}
}

4.HashCode在集合中应用

        boolean contains(Object o) 当且仅当此 collection 至少包含一个满足 (o==null ? e==null : o.equals(e)) 的元素 e 时,返回 true。

public class TT {
	public static void main(String[] args) {
		List<Student> list = new ArrayList<Student>();
		Student s1 = new Student(20);
		Student s2 = new Student(18);
		Student s3 = new Student(22);
		Student s4 = new Student(20);
		
		list.add(s2);
		list.add(s3);
		list.add(s4);
		
		for(Object obj: list){
			System.out.println(((Student)obj).getAge()+" HashCode:"+obj.hashCode());
		}
		System.out.println(list.contains(s1));//true
		System.out.println(list.remove(s1));//true
		/*
		 * s1对象并未添加至集合中去,但是此处输出true,
		 * 即证明了一点,contains()会调用equals方法,由于s1与s4具有相同的HashCode,故输出为true
		 */
	}
}
class Student{
	private int age;
	Student(int age) {
		this.age = age;
	}
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		return result;
	}
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (age != other.age)
			return false;
		return true;
	}
	public int getAge() {
		return age;
	}
}

你可能感兴趣的:(equals,HashCode,哈希算法)