Java 有这样的字母顺序吗?

Does Java have an alphabetical order like this?

与本例 https://www.duden.de/rechtschreibung/Regen_Niederschlag 一样,单词按以下方式排序: “regelwidrig, Regelwidrigkeit, Regelzeit, regen, Regen, Regenabflussrohr, Regenanlage, regenarm, Regenbö, Regenbogen...” 也就是说,它是一种比 Collections.Sort() 自动执行的“更不区分大小写”的排序。小写字母出现在大写字母之前,例如“regen, Regen”。

ArrayList<String> regen = new ArrayList<String>( );
for(String x : new String[]{"regelwidrig", "Regelwidrigkeit", "Regelzeit",
        "regen", "Regen", "Regenabflussrohr",
        "Regenanlage", "regenarm", "Regenbö", "Regenbogen"}) {
        regen.add(x);
}

Collections.sort(再生)响应:

[Regelwidrigkeit, Regelzeit, Regen, Regenabflussrohr, Regenanlage, Regenbogen, Regenbö,
regelwidrig, regen, regenarm]// lowercase at the end

我可以为此实现一个比较器,但我宁愿使用一行代码来获得这种排序方式。如: Collections.SomeMethod(再生);或 Collections.Sort(再生, some_extra_parameter); 但不幸的是,经过深入 google 搜索,我还没有找到。

只用一行“Comparator.comparing”

List<String> regen = new ArrayList<String>( );
for(String x : new String[]{"regelwidrig", "Regelwidrigkeit", "Regelzeit",
        "regen", "Regen", "Regenabflussrohr",
        "Regenanlage", "regenarm", "Regenbö", "Regenbogen"}) {
        regen.add(x);
}

Collections.sort(regen, Comparator.comparing(s -> s.toLowerCase()));
System.out.println(regen);

结果将是:

regelwidrig、Regelwidrigkeit、Regelzeit、regen、Regen、Regenabflussrohr、Regenanlage、regenarm、Regenbogen、Regenbö

  • 您可以使用 String.CASE_INSENSITIVE_ORDER 以 case-insensitive 方式对字符串进行排序。

  • 如果您同时还想进一步指定当前比较器认为相等的元素顺序(就像 String.CASE_INSENSITIVE_ORDER"Regen""regen") 然后你可以使用 Comparator#thenComparing 方法并传递给它 Comparator 它将按照你想要的方式对那些相等的元素进行排序。

    • 假设您还想将 "Regen", "regen" 排序为 "regen", "Regen"(lower-case 在 upper-case 之前),您可以简单地用 Comparator.reverseOrder() 反转它们的自然顺序。

因此您的代码可以如下所示:

regen.sort(String.CASE_INSENSITIVE_ORDER.thenComparing(Comparator.reverseOrder()));

演示:

ArrayList<String> regen = new ArrayList<String>(
        Arrays.asList("regelwidrig", "Regelwidrigkeit", "Regelzeit",
            "Regen", "regen", "Regenabflussrohr",
            "Regenanlage", "regenarm", "Regenbö", "Regenbogen")
);

regen.sort(String.CASE_INSENSITIVE_ORDER.thenComparing(Comparator.reverseOrder()));
System.out.println(regen);

结果:[regelwidrig, Regelwidrigkeit, Regelzeit, regen, Regen, Regenabflussrohr, Regenanlage, regenarm, Regenbogen, Regenbö]

(注意 "Regen""regen" 换了件)

字符串按自然排序方式排序的原因是因为这些字符的 ASCII 值在 UPPERCASE 中的值低于 lowercase。在这种情况下,所有单词都以“R”开头,大写字母“R”的 ASCII 值为 82(十六进制 52),而小写字母“R”为 114(十六进制 72)。出于这个原因,Regen 将在 regen 之前按自然顺序排序(在 Java 中)。

所以,使用普通 Java

public static void main(String[] args) {
    List<String> words = Arrays.asList(new String[]{"regelwidrig", "Regelwidrigkeit", "Regelzeit", "regen", "Regen", "Regenabflussrohr", "Regenanlage", "regenarm", "Regenbö", "Regenbogen"});
    Collections.sort(words);
    System.out.println(words);
}

会输出

[Regelwidrigkeit, Regelzeit, Regen, Regenabflussrohr, Regenanlage, Regenbogen, Regenbö, regelwidrig, regen, regenarm]

如您所见,所有单词均以“R”开头,但排序会将所有大写单词排在以小写字母开头的单词之前。

正如@Pshemo 在他的回答中指出的那样,您可以(应该)对您的比较器帐户进行编码以区分大小写并根据需要颠倒小写字母与大写字母的顺序。

整理器

使用 Collator class 进行 locale-sensitive String 比较。

具体来说,Java 支持德语 collators:

Collator collator = Collator.getInstance(Locale.GERMAN);
regen.sort(collator);

示例:

List<String> inputs = new ArrayList <>(
    List.of( "regelwidrig", "Java", "Regelwidrigkeit", "Regelzeit", "regen", "Regen", "Regenabflussrohr", "Regenanlage", "regenarm", "Regenbö", "Regenbogen" )
);
inputs.sort( java.text.Collator.getInstance( Locale.GERMAN ) ) ;

[Java, regelwidrig, Regelwidrigkeit, Regelzeit, regen, Regen, Regenabflussrohr, Regenanlage, regenarm, Regenbö, Regenbogen]