【问题标题】:How to print a java Set of Sets elements in sorted order?如何按排序顺序打印 Java Set of Sets 元素?
【发布时间】:2020-03-04 20:46:24
【问题描述】:

在我的程序中,我有一个HashSet<HashSet<Integer>>,然后在我的程序结束时,我使用以下语句打印内容,

System.out.println("Groups: " + allSets.toString());

它告诉我这个,

Groups: [[17], [19], [2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21], [11], [13]]

我的回答是好的,但我希望看到它排序之类的,

Groups: [[2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21], [11], [13], [17], [19]]

我将按排序顺序将所有单个编号的集合插入到集合中,并且我必须在末尾插入大集合。

我尝试使用TreeSet,但它不起作用,(got some exceptions)。

我使用List 而不是Set 解决了我的问题,

我想知道,有什么方法可以通过使用 Set 获得相同的有序输出吗?

【问题讨论】:

  • 所以,要明确一点:您想单独对集合进行排序,然后根据集合的最小元素将集合排序为一个组?
  • 单个集合已排序,我只需要在第一个位置插入大集合,我不能在集合中。所以我用 List 解决了它。

标签: java list set


【解决方案1】:

您可以使用TreeSet 作为外部集合,您只需要给它一个有效的比较器。我会推荐类似的东西

SortedSet<SortedSet<Integer>> outerSet = new TreeSet<SortedSet<Integer>>(
  Comparator.comparingInt(SortedSet::first));

(假设 Java 8)。

【讨论】:

    【解决方案2】:
         HashSet<HashSet<Integer>> allSets = new HashSet<>();
         List<Set<Integer>> out=allSets.stream().
                                sorted((x, y) -> x.iterator().next() - y.iterator().next()).
                                collect(Collectors.toList());
    

    【讨论】:

    • 它也可以,但更正一个“ List> out ”,否则会显示错误。
    【解决方案3】:

    很遗憾,我无法对答案发表评论。但接受的答案并不准确。 在 java 中使用 Tree 时,你应该非常小心比较器。 一旦你的比较器返回 0,它就假定对象是相等的,所以不会被添加到树中。

    如果您的集合预期包含所有唯一数字,请忽略此答案!

    否则: Louis Wasserman 提出的比较器只比较第一个元素!所以万一 尝试下一个代码来测试它:

            SortedSet<Integer> s1 = new TreeSet<>(Arrays.asList(13, 14, 15, 16, 17));
            SortedSet<Integer> s2 = new TreeSet<>(Arrays.asList(13, 19));
            SortedSet<Integer> s3 = new TreeSet<>(Arrays.asList(13, 133));
            SortedSet<Integer> s4 = new TreeSet<>(Arrays.asList(110, 13));
            SortedSet<Integer> s5 = new TreeSet<>(Collections.singletonList(13));
            SortedSet<Integer> s6 = new TreeSet<>(Arrays.asList(13,16));
            SortedSet<Integer> s7 = new TreeSet<>(Arrays.asList(13,17));
            SortedSet<SortedSet<Integer>> s = new TreeSet<SortedSet<Integer>>(
                    Comparator.comparingInt(SortedSet::first));
            s.addAll(Arrays.asList(s1, s2, s3, s4, s5, s6, s7));
            System.out.println(s);
    

    这将是:

    [[13, 14, 15, 16, 17]]
    

    这是你所期待的吗?

    http://tpcg.io/HQONOhVV

    如果您想使用 TreeSet,您需要更严格的比较器,例如: (按大小递减比较,然后按项目逐个比较相同大小)

    new TreeSet<>(((Comparator<Set<Integer>>) (o1, o2) -> o2.size() - o1.size()).thenComparing((o1, o2) -> {
                    Iterator<Integer> i1 = o1.iterator();
                    Iterator<Integer> i2 = o2.iterator();
                    while (i1.hasNext() && i2.hasNext()) {
                        Integer n1 = i1.next();
                        Integer n2 = i2.next();
                        if (!n1.equals(n2)) {
                            return n1 - n2;
                        }
                    }
                    return 0;
                }));
    

    您可能希望更改比较顺序(按大小,然后按项目。

    http://tpcg.io/1FjcQ2XA

    【讨论】:

    • 当集合不相交时,接受的答案是准确的,这似乎是 OP 的用例。
    • 好吧,你可能是对的,但我仍然建议 OP 编写一堆单元测试来检查接受的答案是否满足他的需求。它可能需要一些调整。
    • Kaya3 是对的,在我的情况下,集合是不相交的。感谢马赫诺指出。 +1。
    【解决方案4】:

    我正在假设您将“值”按排序顺序放入集合中,HashSet 本身不保留插入顺序,但您可以使用文档中的LinkedHashSet

    此实现与 HashSet 的不同之处在于,它维护一个双向链表,贯穿其所有条目。这个链表定义了迭代顺序,也就是元素被插入到集合中的顺序(insertion-order)。”

    您可以在打印期间使用此行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-01
      • 1970-01-01
      相关资源
      最近更新 更多