使用比较器对列表列表进行排序 [英] Sort a list of lists using comparator

查看:89
本文介绍了使用比较器对列表列表进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找使用比较器对列表列表进行排序(在ArrayLists上).顺序最大的地方.所有子列表的大小始终相同.

I am looking at sorting out a list of lists (on ArrayLists), using a comparator. Where the order is largest first. All sublists will always be of the same size.

例如,

[[4,5,6], [7,9,10], [4,7,8], [1,2,3], [7,9,12]]

这应该

[[7,9,12], [7,9,10], [4,7,8], [4,5,6], [1,2,3]]

我有类似的内容,但仅按每个列表中的第一项进行排序

I have something like this but only sorts by the first item in each list

List<List<Integer>> list = Arrays.asList(
                Arrays.asList(4,5,6),
                Arrays.asList(7,9,10), 
                Arrays.asList(4,7,8),
                Arrays.asList(1,2,3), 
                Arrays.asList(7,9,12));

list.sort((l1, l2) -> l2.get(0).compareTo(l1.get(0)));

哪个会产生:

[[7, 9, 10], [7, 9, 12], [4, 5, 6], [4, 7, 8], [1, 2, 3]]

如何编写比较器,如果前面的项目相等,则该比较器将按列表中的下一个项目进行排序?

How can I write a comparator, which sorts by the next item in the list if the item before is equal?

例如,[7、9、10],[7、9、12]应该继续比较两个7,然后比较两个9,然后是10和12.例如,[4、5、6],[4,7,8]应该继续比较两个4,然后将4和7停下来.

For example, [7, 9, 10], [7, 9, 12] should go onto compare the two 7, then the two 9 and then 10 and 12. For example, [4, 5, 6], [4, 7, 8] should go onto compare the two 4, and tthen the 4 and 7 and stop.

推荐答案

您可以这样定义比较器:

You can define a comparator as such:

Comparator<List<Integer>> comparator = (list1, list2) -> {
       for (int i = 0; i < list1.size(); i++) {
            int value = Integer.compare(list2.get(i), list1.get(i));
            if (value != 0)
                return value;
       }
       return 0;
};

或:

Comparator<List<Integer>> comparator = (list1, list2) -> 
IntStream.range(0, list1.size())
         .map(i -> Integer.compare(list2.get(i), list1.get(i)))
         .filter(value -> value != 0)
         .findFirst()
         .orElse(0);

然后排序:

list.sort(comparator);

更新:

您可以通过创建一个自定义的泛型函数(返回比较器,即:

You can further generalise this by creating a custom generic function that returns a comparator i.e.:

static <T extends Comparable<T>> Comparator<List<T>> comparator(){
       return (o1, o2) -> IntStream.range(0, o1.size())
                                   .map(i -> o2.get(i).compareTo(o1.get(i)))
                                   .filter(value -> value != 0)
                                   .findFirst()
                                   .orElse(0);
}

现在您可以这样做:

List<List<Integer>> integerList = Arrays.asList(
                Arrays.asList(4,5,6),
                Arrays.asList(7,9,10),
                Arrays.asList(4,7,8),
                Arrays.asList(1,2,3),
                Arrays.asList(7,9,12));

integerList.sort(comparator()); // sort list of integers descending

List<List<String>> stringList = Arrays.asList(
                Arrays.asList("a","b","c"),
                Arrays.asList("d","e","f"),
                Arrays.asList("g","h","i"));

stringList.sort(comparator()); // sort list of strings descending 

以此类推...

注意-我使用的是JDK 9+,所以我不知道在JDK 8之前的 版本中类型推断是否足够好.

Note - I am using JDK 9+ so I don't know if the type inference is good enough in versions prior to JDK 8.

这篇关于使用比较器对列表列表进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆