考虑以下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映射,因此得到 字符串的长度可能与原始字符串的长度不同。
答案 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.
这意味着德语语言环境在PRIMARY
和SECONDARY
强度比较中认为这两个字符串相等。