昨天帮同学写了一个Set去重的代码,往里面存入List,如果按照List中的元素是否相同进行去重,却发现当元素过多时有无法去重的情况。代码如下:
Set<List<Integer>> set = new TreeSet<List<Integer>>(new Comparator<List<Integer>>() {
@Override
public int compare(List<Integer> o1, List<Integer> o2) {
return o1.size()==o2.size()&&o1.containsAll(o2)?0:1;
}
});
当元素不多时,的确可以达到去重的效果,但是当元素过多时,就不能去重了。如下面这个用例:
set.add(Arrays.asList(new Integer[]{2,-2,0}));
set.add(Arrays.asList(new Integer[]{0,2,-2}));
set.add(Arrays.asList(new Integer[]{-4, 0, 4}));
set.add(Arrays.asList(new Integer[]{0, -4, 4}));
set.add(Arrays.asList(new Integer[]{-1, -2, 3}));
set.add(Arrays.asList(new Integer[]{1, -4, 3}));
set.add(Arrays.asList(new Integer[]{1, -1, 0}));
set.add(Arrays.asList(new Integer[]{1, 2, -3}));
set.add(Arrays.asList(new Integer[]{0, -3, 3}));
set.add(Arrays.asList(new Integer[]{0, -4, 4}));
set.add(Arrays.asList(new Integer[]{0, 2, -2}));
set.add(Arrays.asList(new Integer[]{0, 1, -1}));
set.add(Arrays.asList(new Integer[]{-1, -3, 4}));
set.add(Arrays.asList(new Integer[]{-1, -2, 3}));
set.add(Arrays.asList(new Integer[]{-1, 2, -1}));
set.add(Arrays.asList(new Integer[]{-1, 0, 1}));
执行结果:
[-4, 0, 4]
[-1, 0, 1]
[-1, 2, -1]
[-1, -3, 4]
[-1, -2, 3]
[0, 1, -1]
[0, 2, -2]
[0, -4, 4]
[0, -3, 3]
[1, 2, -3]
[1, -1, 0]
[1, -4, 3]
[2, -2, 0]
明显没去重。原因是在compare方法中没有返回-1,就可能存在在树的左边和树的右边同时存在同一个元素的情况。大概如下图所示(随手一画),大概就是树的左右都可能出现同一个元素,因为没有比较到。
解决方法:用下面的代码重写compare方法:
@Override
public int compare(List<Integer> l1, List<Integer> l2) {
Collections.sort(l1);
Collections.sort(l2);
if(l1.equals(l2)) {
return 0;
} else {
if(l1.isEmpty())
return 1;
if(l2.isEmpty())
return -1;
int i = 0;
while (l1.get(i).equals(l2.get(i))) i++;
if(l1.get(i) > l2.get(i))
return 1;
else
return -1;
}
即可得到正确结果。