你的想法是正确的,当独享拥有同一hashcode的时候他们会在同一段以hash值标识的内存中以链的形式存放
这样就不是很好了 但是HashSet的性能就是因为底层是使用hash算法来提高性能的
下面是我看完张孝祥老师的高新技术在CSDN上写的博客:
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;
- }
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + x;
- result = prime * result + y;
- return result;
- }
- @Override
- public 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没有删除成功,导致内存泄露!!
所以楼主思想是对的 就是如果这样做就让HashSet失去了使用的价值了 |