按两个不同的属性排序集合

时间:2015-01-21 19:08:36

标签: java sorting comparator

我有一个具有多个属性的类,我希望它按顺序排序。目前我按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());
    }

});

3 个答案:

答案 0 :(得分:5)

首先比较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.comparingthenCompare一起,可以像这样创建一个很好的流。

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

请注意,后者不对原始List进行排序,而是创建新的排序列表。

答案 1 :(得分:3)

如果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());
    }
});

答案 2 :(得分:2)

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

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;
        }