首页 > 解决方案 > 带有自定义比较器的 TreeSet() 的异常行为

问题描述

我在下面的程序中所做的是,我使用自定义比较器创建了一个名为“alls”的 TreeSet,它比较两个列表,如果它们相等,则返回 0,否则返回 1。但是如果我将两个相同的列表添加到 TreeSet然后 TreeSet 接受两个相同的列表。但它不应该包含两个相同的列表,因为我已经定义了一个这样的比较器。

   List<Integer> a1 = new ArrayList<Integer>() {{add(1);add(2);add(3);add(4);}};
    List<Integer> a2 = new ArrayList<Integer>() {{add(1);add(1);}};
    List<Integer> a3 = new ArrayList<Integer>() {{add(2);add(1);}};
    List<Integer> a4 = new ArrayList<Integer>() {{add(3);add(1);}};
    List<Integer> a5 = new ArrayList<Integer>() {{add(4);add(1);}};
    List<Integer> a6 = new ArrayList<Integer>() {{add(5);add(1);}};
    
    Comparator b1 = (l1,l2)->{if(l1.equals(l2)) return 0; else return 1;};
    Collection<List<Integer>> alls = new TreeSet(b1);
    alls.add(a1);
    alls.add(a1);
    alls.add(a1);
    alls.add(a2);
    alls.add(a3);
    alls.add(a1);
    alls.add(a4);
    alls.add(a6);
    alls.add(a5);
    alls.add(a2);
    alls.add(a1);

当我尝试打印我的 TreeSet(name alls) 时,会显示以下输出:

1 2 3 4

1 1

2 1

1 2 3 4

3 1

5 1

4 1

您可以看到 [1 2 3 4] 两次插入到我的 TreeSet(其名称为 alls)中,但之后没有插入。

这怎么可能?我虽然 TreeSet 和我的自定义比较器不允许重复。此外,如果它允许为什么不在我的程序中进一步插入相同的元素

标签: javalistcollectionssettreeset

解决方案


您的比较器不起作用

Collection<List<Integer>> alls = new TreeSet(b1);
alls.add(a1);
alls.add(a2);
alls.add(a3);

你的实现对两个不同的列表进行排序,第二个总是更大,因为return 1你的树看起来像:

a1 <- a3 -> a2

现在让我们添加 a1 :

Collection<List<Integer>> alls = new TreeSet(b1);
alls.add(a1);
alls.add(a2);
alls.add(a3);
alls.add(a1);

a1 <- a3 ? a1 -> a2 结果 a1 更大
a1 <- a3 -> a2 ?a1 结果 a1 更大
a1 <- a3 -> a2 -> a1

您的树现在已经复制了 a1。
解决方案:使用Comparator评论中提到的正确内容


推荐阅读