【问题标题】:Best way to double sort in java using Collections.sort使用 Collections.sort 在 java 中双重排序的最佳方法
【发布时间】:2014-07-09 01:36:09
【问题描述】:

在 java 中我有一个自定义类,我将其排序如下:

public static void sortList(List<FishCategory> categories) {
    Collections.sort(categories, new Comparator<FishCategory>(){
        public int compare(FishCategory s1, FishCategory s2) {
            return s1.getName().compareTo(s2.getName());
        }
    });
}

但是像 sql 一样,你可以这样做:

select * from mytable
order by id, name

我想在 java 中进行双重排序。我想按这个排序(注意:我使用getParentId)作为第一个排序,然后我想像上面那样排序。

public static void sortList(List<FishCategory> categories) {
    Collections.sort(categories, new Comparator<FishCategory>(){
        public int compare(FishCategory s1, FishCategory s2) {
            return s1.getParentId().compareTo(s2.getParentId());
        }
    });
}

我不能在下一个会取消第一次排序的原因之后立即运行这两个函数。我需要按照 sql 的方式进行排序(即对已排序的组进行排序)。

所以我想先按.getParentId() 排序,然后是.getName()

有没有人知道一个容易做到这一点的好方法?

谢谢

【问题讨论】:

    标签: java android sorting


    【解决方案1】:

    编写一个测试两个字段的比较器,仅当第一个字段相等时才查询第二个字段。将其插入排序。完成。

    请注意,如果您想要更通用的多级排序解决方案,您还可以编写一个包含两个比较器(或比较器列表)的比较器。

    【讨论】:

      【解决方案2】:

      Comparator的简单修改:

      final int diff = s1.getParentId() - s2.getParentId();
      return diff != 0 ? diff : s1.getName().compareTo(s2.getName());
      

      如果getParentId()有区别,按方式排序。否则按getName()排序。

      正如by this comment by Pshemo 指出的那样,您可以使用以下内容来进行diff 初始化:

      = Integer.compare(s1.getParentId(), s2.getParentId());
      

      【讨论】:

      • getParentId 返回一个整数,比较不会取整数。
      • @omega 它自动装箱成为Integerjava.lang.Integer 指定了 compareto()
      • 我试过了。 Eclipses 抱怨说比较不适用于原始类型 int。
      • 好的,我正在使用您当前的答案并返回原始 int。
      • 不要使用s1.getParentId() - s2.getParentId(),除非您完全确定您只是减去正值。为了安全起见,最好使用Integer.compare(x, y),就像在这种情况下diff = Integer.compare(s1.getParentId(),s2.getParentId());
      【解决方案3】:

      由于 Java 8 Comparator 具有thenComparing 默认方法,您可以在其中添加下一个比较器,如果“原始”比较器确定值相等,则应使用该比较器。

      所以你的代码看起来像

      public static void sortList(List<FishCategory> categories) {
          Collections.sort(categories, new Comparator<FishCategory>(){
              public int compare(FishCategory s1, FishCategory s2) {
                  return s1.getParentId().compareTo(s2.getParentId());
              }
          }.thenComparing(new Comparator<FishCategory>(){
              public int compare(FishCategory s1, FishCategory s2) {
                  return s1.getName().compareTo(s2.getName());
              }
          }));
      
          Comparator.comparing(FishCategory::getParentId);
      }
      

      或者您可以使用Comparator.comparing 方法进一步简化它,该方法接受Function,该方法返回Comparable 字段,因此在您的情况下,您甚至可以使用lambdas 并编写类似

      public static void sortList(List<FishCategory> categories) {
          Collections.sort(categories, Comparator
                  .comparing(FishCategory::getParentId)
                  .thenComparing(Comparator.comparing(FishCategory::getName)));
      }
      

      【讨论】:

      • 花式 Java 8 Comparator 建设者! Java 7 是否有类似的替代方案?
      • 我实际上将它用于 android,根据这个 stackoverflow.com/questions/23318109/… 它说不支持 java 8,但这看起来仍然是一个很好的答案。
      【解决方案4】:

      首先使用parentId检查它,如果相等则比较名称

      请看下面的代码:

      public static void sortList(List<FishCategory> categories) {
          Collections.sort(categories, new Comparator<FishCategory>(){
              public int compare(FishCategory s1, FishCategory s2) {
                  int diff = s1.getParentId() - s2.getParentId();
                  if (diff != 0)
                      return diff;
                  return s1.getName().compareTo(s2.getName());
              }
          });
      }
      

      【讨论】:

      • s1.getParentId() - s2.getParentId() 是个坏主意,因为整数溢出
      猜你喜欢
      • 2010-10-14
      • 2015-11-17
      • 2012-07-15
      • 2018-09-14
      • 2018-10-11
      • 2011-02-25
      • 1970-01-01
      • 2011-05-19
      • 1970-01-01
      相关资源
      最近更新 更多