Set集合中有TreeSet和HashSet....里面添加的对象不能重复....但是奇怪的是我在HashSet中添加2个相同对象,竟然都打印了出来.:代码见下:import java.util.*;public class HashSetTest { public static void main(String[] args) {
HashSet hs = new HashSet(); hs.add(new WrappedString("aardvark"));
hs.add(new WrappedString("aardvark")); //System.out.println(hs.size()); for (Iterator it = hs.iterator(); it.hasNext();) {
System.out.println(it.next());
}
}
}class WrappedString {
String s; public WrappedString(String s) {
this.s = s;
} public int hashCode() {
return s.hashCode();
} public boolean equals(Object o) {
WrappedString ws = (WrappedString)o; //强转
//另一种可行方法,暂时注释它
// if (s == o)
// return true;
// if (!(o instanceof WrappedString)) //WrappendString 是不是 o 的实例
// return false;
//
// if (s.equals(ws.s)) {
// return true;
// } else {
// return false;
// }
return s == ws.s &&s.equals(ws.s);
} public String toString() {
return s;
}}我发现当添加的是基础数据类型.如Integer.Double等HashSet不会重复,但是一旦添加String 等引用数据类型或对象时它会打印重复对象....当然我重写了hashCode()和equals后就正常了...在这里我想问的是 为什么要重写那2个方法...为什么TreeSet不重写打印就是正常的呢.如果说是因为我自定义的类没有覆盖那2个方法,但是String 类型.应该重写了那2个方法的哦.还有即使是我自定义的对象.它应该也是一个Object,应该重写了那2个方法的啊...为什么要自己手动的在HashSet中重写那2个方法才会完全正确呢....希望高手 老师些 能给一个详细的解答
HashSet hs = new HashSet(); hs.add(new WrappedString("aardvark"));
hs.add(new WrappedString("aardvark")); //System.out.println(hs.size()); for (Iterator it = hs.iterator(); it.hasNext();) {
System.out.println(it.next());
}
}
}class WrappedString {
String s; public WrappedString(String s) {
this.s = s;
} public int hashCode() {
return s.hashCode();
} public boolean equals(Object o) {
WrappedString ws = (WrappedString)o; //强转
//另一种可行方法,暂时注释它
// if (s == o)
// return true;
// if (!(o instanceof WrappedString)) //WrappendString 是不是 o 的实例
// return false;
//
// if (s.equals(ws.s)) {
// return true;
// } else {
// return false;
// }
return s == ws.s &&s.equals(ws.s);
} public String toString() {
return s;
}}我发现当添加的是基础数据类型.如Integer.Double等HashSet不会重复,但是一旦添加String 等引用数据类型或对象时它会打印重复对象....当然我重写了hashCode()和equals后就正常了...在这里我想问的是 为什么要重写那2个方法...为什么TreeSet不重写打印就是正常的呢.如果说是因为我自定义的类没有覆盖那2个方法,但是String 类型.应该重写了那2个方法的哦.还有即使是我自定义的对象.它应该也是一个Object,应该重写了那2个方法的啊...为什么要自己手动的在HashSet中重写那2个方法才会完全正确呢....希望高手 老师些 能给一个详细的解答
你add两次,如果size是2,则说明加上了,是1则说明没有加上。2.是不是同一个对象,不可主观臆测,要看那些关于equal等方法的说明,关于hashCode方法的说明。
你这里分明是两个对象,而不是一个的。
equals和hashCode方法...但是真的很不明白为什么要重写..而其他的对象添进去却不重写
2个abc字符串常量都在 内存常量池,所以它返回来的相对物理地址 一样....所以要自己去写hashCode 计算它的散列码值
让它返回不一样的值...然后重写 hashCode 的时候又必然要去重写equals方法???effective java 这本书有点深哦 里面确实有讲到为什么有时候要重写equals方法...但是小弟确实难以理解那本书...
看来这个问题要先放一下了
tree 需要 compreTo 或者实现 Compareable 接口
boolean add(E o)
如果 set 中尚未存在指定的元素,则添加此元素(可选操作)。更正式地说,如果此 set 没有包含满足下列条件的元素 e,则向 set 中添加指定的元素 o:(o==null ? e==null :o.equals(e))。如果此 set 已经包含指定的元素,则该调用不改变此 set 并返回 false。结合构造方法上的限制,这就可以确保 set 永远不包含重复的元素。
set 不包含满足 e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素
hs.add(new WrappedString("aardvark"));
此处问题
你ADD的是两个对象,虽然他们内部的值是相同的,但是对于HASHSET而言是不同的OBJECT,所以都被添加了.
NEW 永远会产生新的对象,而不会去查找原来栈中是否已经有该对象
package test;
import java.util.*; public class HashSetTest { public static void main(String[] args) {
HashSet hs = new HashSet(); hs.add(new String("aardvark"));
hs.add(new String("aardvark")); //System.out.println(hs.size()); for (Iterator it = hs.iterator(); it.hasNext();) {
System.out.println(it.next());
}
}
} 这样也不是只打针出一个吗,不知道你为什么要转来转去的,目标是什么不是很清楚