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 一个很诡异的重复性判断问题
虽然不大一样,你也可以参考下。