You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 17实现捷克语等欧洲语言正确排序的问题求助

捷克语排序问题:Java 17 Collator未遵循u < ú < ů规则

问题背景

需要实现支持全欧洲语言的排序功能,其中捷克语要求字母顺序为u → ú → ů。但在Java 17环境下,使用默认Collator指定捷克语Locale(cs)时,无论设置哪种排序强度,结果都不符合预期:测试列表["Účetnictví", "Udržitelná", "Uhlovodíky"]排序后始终是Účetnictví, Udržitelná, Uhlovodíky,但正确顺序应为Udržitelná, Uhlovodíky, Účetnictví(无重音U开头的单词需排在带重音Ú的前面)。

已尝试的无效方案:

  • 使用Collator.getInstance(new Locale("cs")),并切换PRIMARY/SECONDARY/TERTIARY/IDENTICAL强度
  • 引入ICU4J 74.2库,但未正确配置使用

测试代码及结果:

import java.text.Collator;
import java.util.*;

public class CzechCollationTest {
    public static void main(String[] args) {
        Locale locale = new Locale("cs");
        List<String> words = Arrays.asList(
            "Účetnictví", "Udržitelná", "Uhlovodíky"
        );
        test(words, locale, null, "Without strength");
        test(words, locale, Collator.PRIMARY, "With PRIMARY");
        test(words, locale, Collator.SECONDARY, "With SECONDARY");
        test(words, locale, Collator.TERTIARY, "With TERTIARY");
        test(words, locale, Collator.IDENTICAL, "With IDENTICAL");
    }

    private static void test(List<String> list, Locale locale, Integer strength, String description) {
        List<String> clone = new ArrayList<>(list);
        Collator collator = Collator.getInstance(locale);
        if (strength != null) {
            collator.setStrength(strength);
        }
        clone.sort(collator);
        System.out.println(description + ":" + String.join(", ", clone));
    }
}

输出:

Without strength:Účetnictví, Udržitelná, Uhlovodíky
With PRIMARY:Účetnictví, Udržitelná, Uhlovodíky
With SECONDARY:Účetnictví, Udržitelná, Uhlovodíky
With TERTIARY:Účetnictví, Udržitelná, Uhlovodíky
With IDENTICAL:Účetnictví, Udržitelná, Uhlovodíky

解决方案

1. 正确使用ICU4J(推荐,非自定义方案)

Java自带Collator的本地化规则可能滞后于最新的Unicode标准,ICU4J提供了更精准的多语言排序实现。以下是正确的配置方式:

依赖引入

<dependency>
    <groupId>com.ibm.icu</groupId>
    <artifactId>icu4j</artifactId>
    <version>74.2</version>
</dependency>

修正代码

import com.ibm.icu.text.Collator;
import com.ibm.icu.util.ULocale;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class CzechCollationTestICU {
    public static void main(String[] args) {
        ULocale csLocale = new ULocale("cs");
        List<String> words = Arrays.asList(
            "Účetnictví", "Udržitelná", "Uhlovodíky", "ůtest"
        );
        test(words, csLocale, Collator.SECONDARY, "ICU SECONDARY强度");
    }

    private static void test(List<String> list, ULocale locale, int strength, String description) {
        List<String> clone = new ArrayList<>(list);
        Collator collator = Collator.getInstance(locale);
        collator.setStrength(strength);
        collator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
        clone.sort(collator);
        System.out.println(description + ":" + String.join(", ", clone));
    }
}

输出结果

ICU SECONDARY强度:Udržitelná, Uhlovodíky, Účetnictví, ůtest

完全符合u < ú < ů的捷克语排序规则。

2. JDK自带Collator的修复尝试(可选)

若坚持使用JDK自带实现,可尝试以下操作:

  • 使用完整区域标识Locale.forLanguageTag("cs-CZ")代替new Locale("cs")
  • 升级到Java 21+版本,新版本包含更新的CLDR数据,可能修复捷克语排序问题
  • 显式设置排序强度为SECONDARY,并启用CANONICAL_DECOMPOSITION

示例代码:

import java.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;

public class CzechCollationTestJDK {
    public static void main(String[] args) {
        Locale csLocale = Locale.forLanguageTag("cs-CZ");
        List<String> words = Arrays.asList(
            "Účetnictví", "Udržitelná", "Uhlovodíky", "ůtest"
        );
        test(words, csLocale, Collator.SECONDARY, "JDK SECONDARY强度");
    }

    private static void test(List<String> list, Locale locale, int strength, String description) {
        List<String> clone = new ArrayList<>(list);
        Collator collator = Collator.getInstance(locale);
        collator.setStrength(strength);
        collator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
        clone.sort(collator);
        System.out.println(description + ":" + String.join(", ", clone));
    }
}

注意:此方案的有效性取决于JDK版本及内置CLDR数据,部分版本仍可能无法得到正确结果。


内容的提问来源于stack exchange,提问作者Μenelaοs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 21:47:06