【问题标题】:Java sort string both alphabetically and keep ASCII orderJava按字母顺序排序字符串并保持ASCII顺序
【发布时间】:2020-02-20 11:13:21
【问题描述】:

名单是:Arrays.asList("Za", "ab", "AB", "Sa", "1ab", "Ab", "!Ab");

如果我使用stream().sorted(),那么顺序是:!Ab 1ab AB Ab Za ab --> Za 不应该在 ab 前面。

如果我使用sorted(String.CASE_INSENSITIVE_ORDER)那么顺序是!Ab 1ab ab AB Ab Za --> 这次AB在ab后面。

有没有什么办法可以结合这两个规则,所以我们的列表按字母顺序排序并且大写大于小写?


添加示例1AB - A0B - AbD - aBD - abd1 - ZAB 按字母顺序排序(Z 永远不会在 a 前面)并且数字 > 大写 > 小写 (AbD > aBD)

【问题讨论】:

  • 是的,通过创建您自己的Comparator

标签: java sorting java-stream


【解决方案1】:

问题是abAB是相等的;因此它们本身在结果中是无序的。 所以添加一个正常的比较,因为大写字母在小写字母之前。

list.stream()
    .sorted(String.CASE_INSENSITIVE_ORDER
            .thenComparing(Comparator.naturalOrder()))

评论后

list.stream()
    .sorted(String.CASE_INSENSITIVE_ORDER
            .thenComparing(Comparator.reverseOrder()))

【讨论】:

  • 我注意到下面的测试用例aB, a0B, AoB, 0AB, ab2 将导致订单失败——这次AoB 落后于aB。除了比较自定义Comparator中两个字符串的每个字符之外,有什么办法吗?
  • 我添加了一个倒序的版本。不完全确定这是您想要的。
  • 感谢 Joop,但 reverseOrder() 将把 AoB 放在 ab2 后面。我创建了一个自定义比较器,将两个字符串放入两个字符数组中,然后使用Character.codePointAt() 比较每个字符。我认为这种订单没有开箱即用的 java api,但它很受欢迎。
【解决方案2】:

像这样写一个比较器类:

import java.util.Comparator;

public class CustomComparator implements Comparator<String> {

    @Override
    public int compare(String o1, String o2) {
        int result = o1.compareToIgnoreCase(o2);
        if(result==0)
            result = o1.compareTo(o2);
        return result;
    }

}

然后在调用排序函数的地方,传递一个比较器的对象:

stream().sorted(new CustomComparator());

【讨论】:

  • 如果你想反转大小写排序,即aA之前,只需像这样反转第二个比较:if(result==0) result = o2.compareTo(o1);
【解决方案3】:

您可以在Java7中使用以下代码来实现这一点

 List<String> list = Arrays.asList("Za", "ab", "AB", "Sa", "1ab", "Ab", "!Ab");

  Comparator<String> comparator = new Comparator<String>() {

  @Override
  public int compare(String o1, String o2) {
      int compare = o1.toLowerCase().compareTo(o2.toLowerCase());
            if(compare==0)
                compare = o1.compareTo(o2);
            return compare;
      }

  };

 Collections.sort(list,comparator);
 System.out.println(list);

在 Java8 中使用此代码

List<String> list = Arrays.asList("Za", "ab", "AB", "Sa", "1ab", "Ab", "!Ab");

Stream<String> stream = list.stream()
                             .sorted(String.CASE_INSENSITIVE_ORDER
                                  .thenComparing(Comparator.naturalOrder()));

stream.forEach(s -> System.out.print(s + " ")); 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多