Java_集合_HashCode

来源:互联网 发布:js json对象转url参数 编辑:程序博客网 时间:2024/05/16 04:42

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方法返回falseSystem.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));//trueSystem.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;}}
原创粉丝点击