【问题标题】:Sort List<List<Integer>> in Java [duplicate]Java中的排序列表<List<Integer>> [重复]
【发布时间】:2021-10-20 19:12:20
【问题描述】:

我正在尝试以 List&lt;List&lt;Integer&gt;&gt; 的字典方式进行排序。但我无法实现目标,也不知道问题出在哪里。

List<List<Integer>> result = new ArrayList<List<Integer>>();

    result.add(Arrays.asList(1, 3, 76, 99));
    result.add(Arrays.asList(1, 2, 84, 92));
    result.add(Arrays.asList(1, 1, 76, 99));

    java.util.Collections.sort(result, (item1, item2) -> {

        if (item1.get(0) > item2.get(0) || item1.get(1) > item2.get(1) || item1.get(2) > item2.get(2)
                || item1.get(3) > item2.get(3)) {
            return 1;
        } else {
            return -1;
        }
    });

预期输出: [[1, 1, 76, 99], [1, 2, 84, 92], [1, 3, 76, 99]]

但我得到了 [[1, 3, 76, 99], [1, 2, 84, 92], [1, 1, 76, 99]]

我希望索引最小的数字会排在第一位。在示例中,所有三个列表的第一个位置都有 1,因此没有变化。在第二个位置,第三个列表有 1,这是三个列表中的最小值,因此第三个列表将移动到第一个。然后考虑到第 2 和第 3 个列表的第 2 项 2 较低,因此第二个列表将保持在第 2 个位置。

【问题讨论】:

  • 字典顺序”是什么意思?字典顺序是在Strings 上定义的,而不是ints。
  • item1.get(0) &gt; item2.get(0) || item1.get(1) &gt; item2.get(1) 对于[[0, 2], [1, 1]] 将是真的,因为后半部分是真的。此外,您缺少相等 (0) 的路径。
  • 如果输入是向后的,是否要翻转-11?如果所有数字都相同怎么办?你应该返回0 吗?你有更好的例子吗?
  • @Turing85 您可以将字典顺序应用于任何有序元素序列。例如,参见 Guava 的 Ordering.lexicographical()
  • 我希望索引最小的数字会排在第一位。在示例中,所有三个列表的第一个位置都有 1,因此没有变化。在第二个位置,第三个列表有 1,这是三个列表中的最小值,因此第三个列表将移动到第一个。然后考虑到第 2 和第 3 个列表的第 2 项 2 较低,因此第二个列表将保持在第 2 个位置。

标签: java


【解决方案1】:

你的条件是错误的。当item1.get(0) &lt; item2.get(0) 时,您只需继续进行短路比较,而不是返回-1。此外,任何时候你有一个不返回 0 的比较器,我都会自动怀疑。

一个简单的解决方法是使用循环:

for(int i = 0; i < 4; i++) {
    int i1 = item1.get(i);
    int i2 = item2.get(i);
    if(i1 < i2) {
        return -1;
    } else if(i1 > i2) {
        return 1;
    }
}
return 0;

您可以将循环简化为

for(int i = 0; i < 4; i++) {
    int d = item1.get(i) - item2.get(i);
    if(d != 0) {
        return d;
    }
}
return 0;

【讨论】:

    【解决方案2】:

    您可以根据MatinS answer 以通用方式进行操作:

    class ListComparator<T extends Comparable<T>> implements Comparator<List<T>> {
    
      @Override
      public int compare(List<T> o1, List<T> o2) {
        for (int i = 0; i < Math.min(o1.size(), o2.size()); i++) {
          int c = o1.get(i).compareTo(o2.get(i));
          if (c != 0) {
            return c;
          }
        }
        return Integer.compare(o1.size(), o2.size());
      }
    
    }
    

    那么排序就简单了

    List<List<Integer>> listOfLists = ...;
    
    Collections.sort(listOfLists, new ListComparator<>());
    

    【讨论】:

    • 为什么是Integer.compare(o1.size(), o2.size()); 而不是o1.size() - o2.size()?你最终会执行一大堆不必要的装箱/拆箱。
    • 另外,感谢您找到副本。此处的正确回答是将问题标记为关闭。
    • @MadPhysicist Integer::compare 将两个ints 作为参数,因此不执行装箱。该算法 - 如所写 - 执行 0(取消)装箱操作。
    • 在这种情况下,它比我所拥有的更灵活。顺便说一句,您需要compare 以避免差异不适合整数的灾难性极端情况。由于 size >= 0 总是,保证一个简单的差异就足够了
    【解决方案3】:

    根据 Mad Physicist 的回答,这里有一个更通用的解决方案和用法:

    public final class SortingListOfListExample {
    
      public static void main(final String[] args) {
        final List<List<Integer>> result = new ArrayList<>();
    
        result.add(List.of(1, 3, 76, 99));
        result.add(List.of(1, 2, 84, 92));
        result.add(List.of(1, 1, 76, 99));
    
        System.out.println(result);
    
        result.sort(new ListComparator<>());
    
        System.out.println(result);
      }
    
      private static final class ListComparator<T extends Comparable<T>> implements Comparator<List<T>> {
    
        @Override
        public final int compare(final List<T> list1, final List<T> list2) {
          final int minSize = Math.min(list1.size(), list2.size());
    
          for(int i = 0; i < minSize; i++) {
            // Be wary of nulls.
            final int compareResult = list1.get(i).compareTo(list2.get(i));
    
            if(compareResult != 0) {
              return compareResult;
            }
          }
    
          return Integer.compare(list1.size(), list2.size());
        }
    
      }
    
    }
    
    

    【讨论】:

    • 糟糕,没有看到 Benjamin RD 的答案。我的基本一样……
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-05
    • 1970-01-01
    • 1970-01-01
    • 2021-07-16
    • 2020-08-19
    相关资源
    最近更新 更多