Java中区域设置的不区分大小写的比较

时间:2017-05-15 21:09:05

标签: java localization linguistics

考虑以下Java代码,比较包含German grapheme ß

的小字符串
String a = "ß";
String b = a.toUpperCase();

assertTrue(a.equalsIgnoreCase(b));

比较失败,因为“ß”.toUpperCase()实际上等于“SS”,最终导致equalsIgnoreCase()中的检查失败。 toUpperCase()的Javadocs明确地提到了这个案例,但是我不明白为什么这不会去ẞ,the capital variant of ß

更一般地说,我们应该如何进行不区分大小写的比较,可能跨越不同的区域。我们应该始终使用toUpper()equalsIgnoreCase(),但不要同时使用两者吗?

问题似乎是equalsIgnoreCase()的实施包括以下检查:anotherString.value.length == value.length,它似乎与toUpper()的{​​{3}}不兼容,其状态为:< / p>

  

由于大小写映射并不总是1:1的char映射,因此得到   字符串的长度可能与原始字符串的长度不同。

1 个答案:

答案 0 :(得分:3)

Java Collator类专为不同的区域设置敏感文本比较操作而设计。由于“大写”的概念在区域设置之间变化很大,Collator使用称为比较 strength 的更细粒度的模型。提供了四个级别,它们如何影响比较是与语言环境相关的。

以下是将Collator与德语区域设置一起使用的示例,用于对字母ß进行不区分大小写的比较:

Collator germanCollator = Collator.getInstance(Locale.GERMAN);
int[] strengths = new int[] {Collator.PRIMARY, Collator.SECONDARY,
                             Collator.TERTIARY, Collator.IDENTICAL};

String a = "ß";
String b = "ß".toUpperCase();

for (int strength : strengths) {
    germanCollator.setStrength(strength);
    if (germanCollator.compare(a, b) == 0) {
        System.out.println(String.format(
                "%s and %s are equivalent when comparing differences with "
                + "strength %s using the GERMAN locale.",
                a, b, String.valueOf(strength)));
    }
}

代码打印出来

ß and SS are equivalent when comparing differences with strength 0 using the GERMAN locale.
ß and SS are equivalent when comparing differences with strength 1 using the GERMAN locale.

这意味着德语语言环境在PRIMARYSECONDARY强度比较中认为这两个字符串相等。