【问题标题】:Sort a list of strings in java in alphabetical order按字母顺序对java中的字符串列表进行排序
【发布时间】:2021-07-05 19:16:18
【问题描述】:

我有一个包含这种格式的字符串的列表:

List<String> ids = new ArrayList<>();

ids.add("B-7");
ids.add("B-5");
ids.add("A-3");
ids.add("B-8");
ids.add("B-1");
ids.add("B-6");
ids.add("B-2");
ids.add("B-3");
ids.add("B-10");
ids.add("A-1");
ids.add("B-4");
ids.add("B-9");
ids.add("A-2");

我需要对其进行排序以获得此输出,(遍历列表):

A-1
A-2
A-3
B-1
B-2
B-3
B-4
B-5
B-6
B-7
B-8
B-9
B-10

我正在使用:

List<String> sortedIds = ids.stream().sorted().collect(Collectors.toList());

但是,我的输出:

A-1
A-2
A-3
B-1
B-10   -- Error
B-2
B-3
B-4
B-5
B-6
B-7
B-8
B-9

【问题讨论】:

标签: java list sorting


【解决方案1】:

您需要一个客户 Comparator&lt;String&gt;sorted() 中间操作中使用

List<String> sorted = ids.stream().sorted((o1, o2) -> {
    String[] first = o1.split("-");
    String[] second = o2.split("-");

    int lettersComparison = first[0].compareTo(second[0]);
    if (lettersComparison != 0) {
        return lettersComparison;
    }

    Integer firstNumber = Integer.valueOf(first[1]);
    Integer secondNumber = Integer.valueOf(second[1]);
    return firstNumber.compareTo(secondNumber);
}).toList();

哪些输出

[A-1, A-2, A-3, B-1, B-2, B-3, B-4, B-5, B-6, B-7, B-8, B-9, B-10]

也就是说,如果您只想对现有的 List 进行排序,我建议不要为此使用 Stream,因为它在性能和创建新对象方面有开销。

您可以使用list.sort(comparator) 并使用与上述相同的Comparator&lt;String&gt;

ids.sort((o1, o2) -> {
    String[] first = o1.split("-");
    String[] second = o2.split("-");

    int lettersComparison = first[0].compareTo(second[0]);
    if (lettersComparison != 0) {
        return lettersComparison;
    }

    Integer firstNumber = Integer.valueOf(first[1]);
    Integer secondNumber = Integer.valueOf(second[1]);
    return firstNumber.compareTo(secondNumber);
});

【讨论】:

    【解决方案2】:

    默认的Comparator 将按字典顺序运行。您需要分别比较字符串部分和整数部分。类似的东西

    Collections.sort(ids, (a, b) -> {
        String[] at = a.split("-");
        String[] bt = b.split("-");
        int c = at[0].compareTo(bt[0]);
        if (c != 0) {
            return c;
        }
        return Integer.valueOf(Integer.parseInt(at[1])).compareTo(Integer.parseInt(bt[1]));
    });
    

    【讨论】:

      【解决方案3】:

      您可以使用Comparator.comparingComparator.thenComparing 创建自定义Comparator

      List<String> sortedIds = ids.stream().sorted(
          Comparator.comparing((String s) -> s.substring(0, s.indexOf('-')))
          .thenComparingInt(s -> Integer.parseInt(s.substring(s.indexOf('-') + 1))))
          .collect(Collectors.toList());
      

      【讨论】:

      • 顺便说一句,在 Java 16 及更高版本中,最后一行可以是 .toList()
      【解决方案4】:

      试试这个。

      List<String> ids = Arrays.asList(
          "B-7", "B-5", "A-3", "B-8", "B-1", "B-6", "B-2",
          "B-3", "B-10", "A-1", "B-4", "B-9", "A-2");
      
      Collections.sort(ids,
          Comparator.comparingInt(String::length)
          .thenComparing(Function.identity()));
      
      System.out.println(ids);
      

      输出

      [A-1, A-2, A-3, B-1, B-2, B-3, B-4, B-5, B-6, B-7, B-8, B-9, B-10]
      

      【讨论】:

      • 非常聪明!但是如果B-05 呢?
      【解决方案5】:

      这是另一种方式。我倾向于先拆分,然后在排序后粘合在一起,而不是在比较器中不断拆分。

      List<String> result = ids.stream().map(s -> s.split("-"))
              .sorted(Comparator.comparing((String[] a) -> a[0])
                      .thenComparingInt(
                              a -> Integer.parseInt(a[1])))
              .map(a -> String.join(",", a))
              .collect(Collectors.toList());
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-01-25
        • 2017-02-23
        • 1970-01-01
        • 1970-01-01
        • 2017-10-04
        • 1970-01-01
        • 2015-07-23
        • 1970-01-01
        相关资源
        最近更新 更多