TreeSet 里可以插入重复元素嘛

yingShisscWang 2011-12-07 02:37:25
1)通常set中不能插入重复元素(几乎所有的人都这么说),但是到底什么是重复元素?(和equals方法和hashcode返回值有关嘛)
2)所有的Set实现都是如此嘛,比如HashSet或者TreeSet都是如此嘛?
3)下面的代码是关于一个自定义类VO,我实例化了两个VO,让他们的equals方法,和hashcode方法返回值相同.但是他们还是插入了两次.


public static void main(String[] args){
Set aset = new TreeSet();
VO avo1 = new VO(1);
VO avo2 = new VO(3);

if(avo1.equals(avo2)){
System.out.println("equals:" + true);
}

if(avo1.hashCode() == avo2.hashCode()){
System.out.println("hashcode:" + true);
}

aset.add(avo1);
aset.add(avo2);

Iterator it = aset.iterator();
while(it.hasNext()){
VO show = (VO)it.next();
System.out.println(show.toString());
}
}




public class VO implements Comparable{
private int name;


public VO(int name){
this.name = name;
}

@Override
public boolean equals(Object obj) {
VO vo = (VO)obj;//比较余数
if(this.hashCode() - vo.hashCode()==0){
return true;
}
return false;
}

@Override
public int hashCode() {
// TODO Auto-generated method stub
return name%2;//取余数
}

@Override
public int compareTo(Object obj) {

return this.name - ((VO)obj).name;
}

@Override
public String toString() {
// TODO Auto-generated method stub
return "name:" + name;
}


}



返回结果如下
equals:true
hashcode:true
name:1
name:3




...全文
1029 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
yingShisscWang 2011-12-07
  • 打赏
  • 举报
回复
貌似确实是通过compareto方法进行比较的.
doc上还有这么一句话Comparable or Comparator for a precise definition of consistent with equals
在Treeset中的对象由于继承了Comparable接口,插入TreeSet的对象遵循原则:compareto方法必须和equals一致,也就是说如果compareto是0,则表示equals必须为true
qybao 2011-12-07
  • 打赏
  • 举报
回复
LZ可以在你的equals,hashCode和compareTo方法分别打印一些信息,然后你调用Set的add方法后,看看有哪些方法会被调用
huntor 2011-12-07
  • 打赏
  • 举报
回复
TreeSet/TreeMap 使用的是 Comparable compareTo 或 Comparator compare 方法比较。
你没看过TreeSet/TreeMap的javadoc吗?
qybao 2011-12-07
  • 打赏
  • 举报
回复
一般Set会比较equals和hashCode
而TreeSet还会比较compareTo,先调用compareTo并通过二分法将元素排列以后,再调用equals和hashCode来判断和当前排列位置的元素是否一致,所以,如果一开始的排列就把所谓的相同元素(equals和hashCode相同)分在不同的位置,那么可以保存所谓的相同元素,否则,不行
luckyc2008 2011-12-07
  • 打赏
  • 举报
回复
Set集合中存放的是对象的引用,并且没有重复的对象。
源码add方法的注释:用equals来比较的,比较的是对象
* <tt>(e==null ? e2==null : e.equals(e2))</tt>.
* If this set already contains the element, the call leaves the set
* unchanged and returns <tt>false</tt>. In combination with the
* restriction on constructors, this ensures that sets never contain
* duplicate elements.
yingShisscWang 2011-12-07
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 creso 的回复:]
Java code
public static void main(String[] args) {
TreeSet<Integer> tree = new TreeSet<Integer>();
tree.add(1);
tree.add(1);
for (Integer i : tree) {
……
[/Quote]
我不同意你的观点,如果将我的代码改成如下也只插入一次,但是明显地址是不同的.



public static void main(String[] args){
Set aset = new TreeSet();
VO avo1 = new VO(1);
VO avo2 = new VO(1);

aset.add(avo1);
aset.add(avo2);

Iterator it = aset.iterator();
while(it.hasNext()){
VO show = (VO)it.next();
System.out.println(show.toString());
}
}

以上这段代码avo1和avo2的地址肯定是不同的,为什么却只输出了1次
creso 2011-12-07
  • 打赏
  • 举报
回复
	public static void main(String[] args) {
TreeSet<Integer> tree = new TreeSet<Integer>();
tree.add(1);
tree.add(1);
for (Integer i : tree) {
System.out.println(i);
}
}

很明显不可以,输出只有一个1,
引用类型保存的是地址,两个对象的地址不同(部分除外,如String),LZ可以用==对比下地址是否相同

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧