HashCode分析

来源:互联网 发布:软件行业分析 编辑:程序博客网 时间:2024/05/21 22:48

HashSet添加元素的时候会判断是否重复,而判断两个元素重复的条件是它们的equals方法返回true并且hashCode值相等。

在hash算法会将集合来分成一个一个区域的,添加的元素的时候也会计算出hash值来决定将元素放进哪个区域。

 

例如:区域1.  区域2. 区域3.

 

如果一个对象只是重写了equals方法并没有重写hashCode方法的时候会出现这么一种情况,如果有一个对象a1 = A(4,5)计算出hashcode被添加进集合区域1中了,另一个对象a2 = A(4,5)再次被添加进集合的时候,可能会计算出hashcode值对应在区域3中,那么它调用equals方法比较区域三中对象时候相同,结果没有相同的,a2成功添加进集合了,这就有问题了,就是因为hash算法是对象只比较自己所在区域的对象,所以我们在写代码的时候会约定当当两个对象的equals方法返回true的时候,他们的hashcode值也应该相等。

 

加入一个对象添加进入集合当中就不要修改其内部参与计算hashcode的属性了,如果修改了,这个对象就跑到别的内存中了,就删除不掉了,会引发内存泄露。

例如以下代码:

public class Test04 {public static void main(String[] args) {Collection<Point> coll = new HashSet<Point>();Point p1 = new Point(3, 3);Point p2 = new Point(4 ,5);Point p3 = new Point(8 ,9);coll.add(p1);coll.add(p2);coll.add(p3);p1.y = 8;coll.remove(p1);System.out.println(coll.size());}}class Point{public int x;public int y;public Point(int x,int y){this.x = x;this.y = y;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + x;result = prime * result + y;return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Point other = (Point) obj;if (x != other.x)return false;if (y != other.y)return false;return true;}}


 

上述代码将p1,p2,p3加入集合当中,集合大小是3,这里的p1对象添加进集合后被修改了x值导致了p1对象找不到了,remove方法后打印集合的大小还是3,说明p1没有删除成功,导致内存泄露!!

 

 

原创粉丝点击