import java.util.HashSet;
import java.util.Set;
public class Test {
public static void main(String[] args) throws Exception{
Set set = new HashSet();
Point p1 = new Point("lisi","nanjing");
Point p2 = new Point("wangwu","shanghai");
Point p3 = new Point("zhaoliu","beijing");
set.add(p1);
set.add(p2);
set.add(p3);
System.out.println(set.size());
p1.name = "zhangsan";
set.remove(p1);
System.out.println(set.size());
}
}
class Point{
public String name;
public String address;
public Point(String name,String address){
this.name = name;
this.address = address;
}
public int hashCode() {
return name.hashCode()*address.hashCode();
}
}
我往HashSet集合中添加3个元素,后来想减少一个,为什么还是3个元素呢? 作者: 柴乔军 时间: 2013-2-21 09:19 本帖最后由 柴乔军 于 2013-2-21 10:07 编辑
Set set = new HashSet();
Point p1 = new Point("lisi","nanjing");
Point p2 = new Point("wangwu","shanghai");
Point p3 = new Point("zhaoliu","beijing");
set.add(p1);
set.add(p2);
set.add(p3);
System.out.println(set.size());//集合中已存入3个Point对象
p1.name = "zhangsan";//你将集合外的Point对象p1的name属性改为"zhangsan"
set.remove(p1);//你要删除集合中和p1值一样的元素,但集合中并不存在name="zhangsan"这样的元素(存在name="lisi"),所以是无法删除的
System.out.println(set.size());//上面没删除集合中任一值,所以这集合还存有3个值作者: 张晋瑜 时间: 2013-2-22 19:59
我仔细的调试了一下这个小程序。 首先,2楼的回答是错误的,就算再重写一个equals()方法也没用,因为楼主所写的Point类的hashCode()方法的缘故已经找不到p1了(确实会内存泄露,这只是后果)。为什么找不到,因为根据楼主的hashCode()方法计算hash码是与属性相关的。 其次,我觉得3、4楼的答案更正确。 最后,对于这个小程序,我遇到了另外一个问题,想向大家请教:
对这个小程序做个小修改,就是Point中equals()、hashCode()都不重写
import java.util.HashSet;
import java.util.Set;
public class Test {
public static void main(String[] args) throws Exception{
Set set = new HashSet();
Point p1 = new Point("lisi","nanjing");
Point p2 = new Point("wangwu","shanghai");
Point p3 = new Point("zhaoliu","beijing");
set.add(p1);
set.add(p2);
set.add(p3);
System.out.println(set.size());
p1.name = "zhangsan";
set.remove(p1);
System.out.println(set.size());
}
}
class Point{
public String name;
public String address;
public Point(String name,String address){
this.name = name;
this.address = address;
}
}
我发现结果是正确的,大家有什么看法说说吧,当能重写这两个方法是有必要的,大家说说看应该怎么重写?作者: 唐长智 时间: 2013-2-23 00:42 本帖最后由 唐长智 于 2013-2-23 01:09 编辑
楼主纠结的是HashSet的remove()方法和hashcode(),equals()之间的关系。
那么就要从HashSet各个方法的底层调用说起了。
先说remove();
HashSet的remove()方法的底层调用的是map集合的remove()方法。
//这是HashSet remove()的源码
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
map集合的remove方法则是
如果此映射包含从满足 (key==null ? k==null :key.equals(k)) 的键 k 到值 v 的映射关系,则移除该映射关系。
V remove(Object key);