【问题标题】:Sort collection by two different properties按两个不同的属性对集合进行排序
【发布时间】:2015-01-21 19:08:35
【问题描述】:

我有一个具有多个属性的类,我希望对其进行排序。目前我正在按Name 排序,如下所示:

Collections.sort(rowItems, new Comparator() {

    public int compare(Object o1, Object o2) {
        SearchRowItem p1 = (SearchRowItem) o1;
        SearchRowItem p2 = (SearchRowItem) o2;
        return p1.getName().compareToIgnoreCase(p2.getName());
    }

});

但我还想按LastName 对Name 进行第二次排序(所以如果名称相同,则按LastName 第二次排序)。如何将下面的代码与我的第一个排序组合以获得我描述的结果?

Collections.sort(rowItems, new Comparator() {

    public int compare(Object o1, Object o2) {
        SearchRowItem p1 = (SearchRowItem) o1;
        SearchRowItem p2 = (SearchRowItem) o2;
        return p1.getLastName().compareToIgnoreCase(p2.getLastName());
    }

});

【问题讨论】:

    标签: java sorting comparator


    【解决方案1】:

    一个简单的Comparator 首先比较name 然后lastName 将与Collections.sort 方法一起使用。

    来自JavaDoc:

    比较它的两个参数的顺序。返回负整数、零或正整数,因为第一个参数小于、等于或大于第二个参数。


    所以,这里是 Comparator 的示例,它比较两个属性:

    Collections.sort(rowItems, new Comparator<SearchRowItem>() {
        @Override
        public int compare(final SearchRowItem o1, final SearchRowItem o2) {
            int compare = o1.getName().compareToIgnoreCase(o2.getName());
            if (compare != 0) {
                return compare;
            }
            return o1.getLastName().compareToIgnoreCase(o2.getLastName());
        }
    });
    

    但是,还有其他选择。 Java 8 引入了流,可以很好地集成排序。与Comparator.comparing 和thenCompare 的新方法一起,可以像这样创建一个不错的流。

    final List<SearchRowItem> collect = rowItems.stream()
            .sorted(
                    Comparator.comparing(SearchRowItem::getName, String::compareToIgnoreCase)
                              .thenComparing(SearchRowItem::getLastName, String::compareToIgnoreCase))
            .collect(Collectors.toList());
    

    注意,后者不会对原来的List进行排序,而是创建一个新的排序列表。

    【讨论】:

    • 谢谢你这么详细的回答,它帮助我真正理解了排序比较。
    【解决方案2】:

    如果getName() 返回 0,则意味着两个对象具有相同的名称 - 只有这样您才应该使用 getLastName():

    Collections.sort(rowItems, new Comparator() {
    
        @Override
        public int compare(Object o1, Object o2) {
            SearchRowItem p1 = (SearchRowItem) o1;
            SearchRowItem p2 = (SearchRowItem) o2;
            int nameComp =  p1.getName().compareToIgnoreCase(p2.getName());
            if (nameComp != 0) {
                return nameComp;
            }
            return p1.getLastName().compareToIgnoreCase(p2.getLastName());
        }
    });
    

    编辑:
    上面的答案遵循OP的风格。但是,如果可能,您应该使用泛型来清理代码:

    Collections.sort(rowItems, new Comparator<SearchRowItem>() {
    
        @Override
        public int compare(SearchRowItem p1, SearchRowItem p2) {
            int nameComp =  p1.getName().compareToIgnoreCase(p2.getName());
            if (nameComp != 0) {
                return nameComp;
            }
            return p1.getLastName().compareToIgnoreCase(p2.getLastName());
        }
    });
    

    【讨论】:

      【解决方案3】:

      在第一次比较中检查是否相等

      public int compare(Object o1, Object o2) {
                  SearchRowItem p1 = (SearchRowItem) o1;
                  SearchRowItem p2 = (SearchRowItem) o2;
                  int compare = p1.getName().compareToIgnoreCase(p2.getName());
                  if (compare == 0) {
                    compare = p1.getLastName().compareToIgnoreCase(p2.getLastName());
                  }
                  return compare;
              }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-05-31
        • 2017-03-29
        • 1970-01-01
        • 2020-04-02
        • 2019-10-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多