日期:2014-05-20  浏览次数:20661 次

TreeSet集合排序问题
需求是数组去重,但是要保留原来的顺序,例如:

原始数组是{4,2,4,6,1,2,4,7,8}
  得到结果{4,2,6,1,7,8}
我想用TreeSet集合,然后自定义一个比较器,可是结果却是错误的,代码如下:

import java.util.*;
public class Text {


public static void main(String[] args) {
int[] s={4,2,4,6,1,2,4,7,8};
for(int x:quChong(s))
System.out.print(x+" ");

}
public static int[] quChong(int[] arr){
TreeSet<Integer> a=new TreeSet(new MyCompare());
for(int x=0;x<arr.length;x++){
a.add(arr[x]);
}
System.out.println(a);
int[] i=new int[a.size()];
int temp=0;
for(Integer j:a){

i[temp++]=j;
}
return i;
}
   

}

//自定义比较器,使元素按照存入的先后顺序存储
class MyCompare implements Comparator{
public int compare(Object o1,Object o2){
int num;
Integer i1=(Integer)o1;
Integer i2=(Integer)o2;
num=i1.compareTo(i2);
if(num==0)
return 0;
return 1;
}
}


结果是 4 2 6 1 4 7 8 ,有重复元素。我没弄明白问题出在哪里了,请大家帮忙看看
而且,测试的时候看到新添加进集合的元素并没有跟所有已有元素比较

请大家看看这个自定义比较器有问题么

------解决方案--------------------
引用:
我打印了它们比较的顺序。。。觉得有点乱 没搞明白
不好意思,虽然前面对比后返回大于0时不再比较是对的,不过有一个对方没有说明,就是它的大小并不按顺序放进去的,而是用红黑树结构来存的,当它存了数据后发现树不平衡时会旋转,貌似就算弄成逆序也未必可以完全去重,粗略画几步给你看一下:旋转后颜色忘记了,不知道有没有弄错,如果不懂红黑树的话得自己去学习一下了
------解决方案--------------------
为了这个问题专门去查了一个小时!
TreeSet是用TreeMap实现的,而TreeMap又是用红黑树实现的,红黑树又是一个加了条件的排序树。在你的代码中,comparator只会返回1(或-1),这就是说在插入数据的时候,只会沿着右子树(或左子树)的方向检索,并且在插入的过程中,树自身不断的调整,从而导致新添加的元素A根本没有没有机会去跟与A相等的B进行比较,从而导致了无法去重,如果楼主想彻底搞明白这个问题,请自己去模拟下红黑树的插入过程。

------解决方案--------------------
ItEye上我也曾参与讨论过一个类似的问题

treeSet 一个很诡异的重复性判断问题

虽然不大一样,你也可以参考下。