【问题标题】:Sort a Set in reverse order以相反的顺序对集合进行排序
【发布时间】:2014-03-06 00:28:05
【问题描述】:

为新手问题道歉,但是以相反的顺序获得Set(比如LinkedHashSet)的正确方法是什么?对于Collections,有Collections.reverse(Collection c),但是对于带有有序元素(如LinkedHashSet)的Set,如何做到这一点?

【问题讨论】:

  • A Set 没有订单。你能澄清一下吗?此外,reverse 采用 List
  • 好吧...我的意思是LinkedHashSet(已订购)。扭转它的最佳方法是什么?我是否需要获取迭代器并对其进行迭代,还是有更聪明的方法?
  • @SotiriosDelimanolis 在 Java 中,TreeSets 将他们的项目按排序顺序保存。要以相反的顺序获取元素,您可以使用descendingSet() 方法。对于LinkedHashSet,请参阅此答案:stackoverflow.com/questions/10741902/…
  • 一个LinkedHashSet 不是有序它是Linked。如果您想以相反的插入顺序遍历项目,请使用Iterator
  • @BoristheSpider 这真的取决于你所说的“有序”。 TreeSet 维护“排序”顺序,而 LinkedHashSet 维护插入顺序(因此确实具有可预测的迭代顺序。)

标签: java


【解决方案1】:

集合通常没有排序,因此为了保持排序,在将集合排序为列表后,您需要使用 Set 的已知迭代顺序实现,例如 LinkedHashSet

List list = new ArrayList(set);
Collections.sort(list, Collections.reverseOrder());
Set resultSet = new LinkedHashSet(list);

您也可以将 TreeSet 与比较器一起使用,但这不如上面的 ArrayList 方法快。

【讨论】:

  • 对于较大的数据集,这会不会是低效的(内存方面)(因为您最终会在内存中拥有相同的数据两次)?我的输入是Set,而不是List
  • Java Collections API 似乎不允许常量空间排序或任意集合。您可能需要将自己限制在 SortedSet API 中才能从我所知道的情况中得到预期。
【解决方案2】:
public class LargestArray {
public static void main(String[] args) {

    ArrayList<Integer> al = new ArrayList<>();
    Set<Integer> set = new TreeSet<>();
    set.add(10);
    set.add(20);
    set.add(7);
    set.add(4);
    set.add(1);
    set.add(2);
    set.add(3);
    set.add(4);
    System.out.println("after Sorting");
    for(int i : set) {
        System.out.print("  " + i);
    }
    al.addAll(set);
    set.clear();
    Collections.reverse(al);
    System.out.println();
    System.out.println("After Reverse");
    for (int i : al) {
        System.out.print(" " + i);
    }

}

}

输出 = 排序后 1 2 3 4 7 10 20 反转后 20 10 7 4 3 2 1

【讨论】:

    【解决方案3】:

    看看这个

    http://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html#descendingSet()

    如果你使用 TreeSet,你可以通过调用 descendingSet 来获得相反的顺序。

    【讨论】:

    • 在我添加它们之后TreeSet 不会重新订购它们(并混淆顺序)...?
    • 不,这就是为什么需要比较器来维持顺序的原因。如果没有正确实现比较器,那么是的,您的订单可能会很奇怪。
    • OP 正在使用LinkedHashSet - 这维护了插入顺序。将项目放入TreeSet 显然会破坏这一点。除非你提供了一个明确的排序比较器——这在某种程度上破坏了对象。
    • 啊,这是在编辑中添加的。我很惊讶 LinkedHashSet 没有反向迭代器,因为文档说实现是由双向链表支持的。
    • 这确实是在我添加帖子后一分钟或两分钟添加的。对此感到抱歉。
    【解决方案4】:

    我会用一个例子来解释你。为了更好地理解,在代码中间添加了注释。

    public class ReverseLinkedHashSet {
    
        public static void main(String[] args) {
    
            // creating a LinkedHashSet object which is
            // of type String or any. Will take a example of String.
            HashSet<String> cars = new LinkedHashSet<String>();
    
            // adding car elements to LinkedHashSet object as below
            cars.add("Toyato");
            cars.add("Hundai");
            cars.add("Porshe");
            cars.add("BMW");
    
            // Iterating using enhanced for-loop to see the order.
            System.out.println("Insertion Order: Iterating LinkedHashSet\n");
            for(String car : cars) {
                System.out.println(car);
    
            // Output will be as below  
            //Toyato
            //Hundai
            //Porshe
            //BMW
            }
    
            // Now convert to ArrayList to rearrange to reverse
            // the linkedHashset
            List<String> listOfCars = new ArrayList<String>(cars);
    
            // to reverse LinkedHashSet contents
            Collections.reverse(listOfCars);
    
            // reverse order of LinkedHashSet contents
            // can be done as below
            System.out.println("\n\n\nReverse Order of LinkedHashSet\n");
            for(String car : listOfCars) {
                System.out.println(car);
    
            // Output will be as below  
            //BMW
            //Porshe
            //Hundai
            //Toyato    
            }
        }
    }
    

    另外,我建议不要在没有充分理由的情况下使用LinkedhashSet。对于复杂的应用程序,它会降低性能。请改用HashSet

    【讨论】:

      【解决方案5】:

      Java 8,我使用下面的解决方案,

      Set<String> setTest = new HashSet<>();
      
      setTest.add("1");
      setTest.add("2");
      setTest.add("3");
      
      List<String> list = new ArrayList<>(setTest);
      list.sort(Collections.reverseOrder());
      Set<String> result = new LinkedHashSet<>(list);
      
      for (String item: result) {
          System.out.println("---> " + item);
      }
      
      Result:
      
      ---> 3
      ---> 2
      ---> 1
      

      为我工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-11-11
        • 1970-01-01
        • 2013-08-07
        • 1970-01-01
        • 2017-03-29
        • 2011-03-30
        • 1970-01-01
        相关资源
        最近更新 更多