【问题标题】:Generic comparator to sort Java Collections (List, Set)用于对 Java 集合(列表、集合)进行排序的通用比较器
【发布时间】:2011-08-02 05:33:34
【问题描述】:

我需要一些通用比较器,它可以接受 List 或 Set 的实例作为参数,以及顺序方向参数(ASC、DESC),然后返回排序后的集合。我似乎在互联网上找不到这个例子,而且我很着急。我知道我没有以适当的方式提出问题,因为我没有任何代码可以开始,但我非常着急。集合将包含实现可比较和日期的对象。

非常感谢任何示例和实现。 谢谢。

【问题讨论】:

  • 我能理解您对列表进行排序,但不是对集合进行排序。 Java 确实有一个SortedSet,但您实际上并没有对它们进行排序,它们只是在您遍历它们时按排序顺序显示它们的项目。你到底想让这个“比较器”做什么?

标签: java generics collections comparator


【解决方案1】:

Collections 类有一个reverseOrder 方法,它返回一个泛型类型T 的比较器,它应该满足您对DESC 比较器的要求。如果您将 Collection 传递给 Collections.sort() 方法,它会自动使用 ASC 排序。

此外,当涉及以无序方式维护“唯一”元素的“集合”时,“排序”并没有多大意义(我的意思是,您可以将 TreeSet 用于排序集合,但这是另一回事) .一个简单的解决方法是从Set 中创建一个List 并将其传递给Collections.sort

【讨论】:

    【解决方案2】:

    使用GenericComparator.java,您将能够对以下数据类型进行排序 Integer、String、Long、Double、Float 和 Date。

    升序

    Collections.sort(persons, new GenericComparator("name", true));
    

    降序

    Collections.sort(persons, new GenericComparator("name", false));
    

    Detailed information here!

    【讨论】:

    • 请告诉我您投反对票的原因。以便我提供解释或改进我的答案,谢谢。
    【解决方案3】:

    这可以作为一个基本的启动示例,从您的要求开始:

    // Create a list
    String[] strArray = new String[] {"z", "a", "C"};
    List list = Arrays.asList(strArray);
    
    // Sort
    Collections.sort(list);
    // C, a, z
    
    // Case-insensitive sort
    Collections.sort(list, String.CASE_INSENSITIVE_ORDER);
    // a, C, z
    
    // Reverse-order sort
    Collections.sort(list, Collections.reverseOrder());
    // z, a, C
    
    // Case-insensitive reverse-order sort
    Collections.sort(list, String.CASE_INSENSITIVE_ORDER);
    Collections.reverse(list);
    // z, C, a
    

    【讨论】:

      【解决方案4】:

      您必须使用以下代码调用您的比较器。

      Collection.sort(myList,new MyComparatorClass());
      

      然后您必须创建自己的比较器类,它将按升序或降序对对象 bean 执行排序。在该类中,您可以比较要执行排序的属性。这里我对名称执行排序.

      public class MyComparator  implements Comparator {
      
          public int compare(Object o1, Object o2) {
            return o1.getName().compareTo(o2.getName());
          }
      
      }
      

      【讨论】:

        【解决方案5】:

        定义一个Comparator 接口 喜欢

        public interface Comparator<T> {
          int compare(T o1, T o2);
          boolean equals(Object obj);
        }
        

        编写标识要比较的类 例如日期对象

        public class DateOrderComparator implements Comparator
        

        用于排名比较器

        public class RankCodeComparator implements Comparator
        

        等等……

        【讨论】:

          【解决方案6】:

          这是我的 Java 8 通用比较器。您可以比较函数 f(T) -> R 上的任何 T,例如人 (T) 的出生日期 (R)。由于 f 可以是对 T 的 getter 的方法引用,因此很容易在 T 的任何属性(字段)上进行比较。它适用于空 T 和空 R(您决定空值是第一个还是最后一个),以及升序/降序排列。由于它使用 R 的自然排序,因此后者也必须实现 Comparable。请参阅代码末尾的用法示例。

          public class CompareUtil {
          
              public static enum Nulls {FIRST, LAST};
              public static enum Order {ASCENDING, DESCENDING};
          
              /** Return a Comparator of T on a function f(T) -> R */
              public static <T, R extends Comparable<? super R>> Comparator<T> comparatorOf(
                      Function<T, R> function,
                      Order order,
                      Nulls nulls) {
          
                  Comparator<R> rComparator = Comparator.naturalOrder();
          
                  if (order == Order.DESCENDING) {
                      rComparator = rComparator.reversed();
                  }
                  rComparator = (nulls == Nulls.FIRST)? 
                          Comparator.nullsFirst(rComparator) :
                              Comparator.nullsLast(rComparator);
          
                  Comparator<T> tComparator = 
                          Comparator.comparing(
                                  function, rComparator);
          
                  tComparator = (nulls == Nulls.FIRST)? 
                          Comparator.nullsFirst(tComparator) :
                              Comparator.nullsLast(tComparator);
          
                  return tComparator;
              }
          
          //Example: construct a comparator that compares Events on event-date
          //in descending date order, putting any nulls at the end of the result set
          Comparator<Event> c = comparatorOf(Event::getDate, Order.DESCENDING, Nulls.LAST);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-02-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-10-20
            • 2013-11-13
            • 2022-08-18
            • 2021-06-16
            相关资源
            最近更新 更多