使用不同长度的一维列表对 Java 中的二维数组列表进行排序

Sorting a 2D arraylist in Java with different lengths of 1D lists

我一直在尝试使用自定义 Comparator 字典排序 二维 ArrayList。但是每个一维列表的长度都不同所以我没有得到预期的结果这里是我的代码:

List<ArrayList<Integer>> a = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> a1 = new ArrayList<Integer>();
ArrayList<Integer> a2 = new ArrayList<Integer>();
ArrayList<Integer> a3 = new ArrayList<Integer>();
ArrayList<Integer> a4 = new ArrayList<Integer>();

a1.add(1);

a2.add(1);
a2.add(3);

a3.add(1);
a3.add(2);
a3.add(3);

a.add(a1);
a.add(a2);
a.add(a3);

Collections.sort(a, new Comparator<ArrayList<Integer>>() {
    @Override
    public int compare(ArrayList<Integer> a, ArrayList<Integer> b) {
        if (a.get(0) < b.get(0))
            return 1;
        return -1;
    }
});
System.out.println(a);

所以输入是[[1], [1, 3], [1, 2, 3]]

我的输出是[[1, 2, 3], [1, 3], [1]]

预期输出为[[1],[1,2,3],[1,3]]

请指出错误和使代码工作所需的补充

您正在尝试定义自定义 Comparator 排序您的 2d 整数 ArrayList 比较两个 1d ArrayList 的两个 String 表示:例如 ArrayList [1][1, 3] 您将比较字符串 "1""13"。这可以使用如下所示的流和 String.valueOf 方法获得,我假设您没有空整数 ArrayList:

Collections.sort(a, new Comparator<List<Integer>>() {
    @Override
    public int compare(List<Integer> a, List<Integer> b) {
        String j1 = a.stream().map(String::valueOf).collect(Collectors.joining(""));
        String j2 = b.stream().map(String::valueOf).collect(Collectors.joining(""));

        return j1.compareTo(j2);
    }
});

这将产生您预期的有序输出。

首先确定要比较的列表中哪个较短。例如,您可以使用方法 Math.min(int a, int b) 来确定这一点。然后将第一个列表的每个元素与第二个列表的相应元素进行比较。如果它们 相等,则 return 本次比较的结果。如果都相等,比较列表的长度和 return 这个值。

List<List<Integer>> listOfLists = new ArrayList<>();
List<Integer> listOne = new ArrayList<>();
listOne.add(1);

List<Integer> listTwo = new ArrayList<>();
listTwo.add(1);
listTwo.add(2);
listTwo.add(3);

List<Integer> listThree = new ArrayList<>();
listThree.add(1);
listThree.add(3);

listOfLists.add(listOne);
listOfLists.add(listTwo);
listOfLists.add(listThree);
    
Collections.sort(listOfLists, new Comparator<List<Integer>>() {
    @Override
    public int compare(List<Integer> first, List<Integer> second) {
        int comp = 0;
        for(int i = 0; i < Math.min(first.size(), second.size()); i++){
            comp = Integer.compare(first.get(i), second.get(i));
            if(comp != 0){
                return comp;
            }
         }
         return Integer.compare(first.size(), second.size());
    }
});
System.out.println(listOfLists);

看来您需要按字典顺序排列。 Guava 库有实用方法可以帮助你:

import com.google.common.collect.Comparators;
...
Collections.sort(a, Comparators.lexicographical(Comparator.naturalOrder()));