我有下面的测试用例,只有第一个断言通过了。为什么?
@Test
public void test() {
String i1 = "i";
String i2 = "İ".toLowerCase();
System.out.println((int)i1.charAt(0)); // 105
System.out.println((int)i2.charAt(0)); // 105
assertTrue(i2.startsWith(i1));
assertTrue(i2.endsWith(i1));
assertTrue(i1.endsWith(i2));
assertTrue(i1.startsWith(i2));
}
回复后更新
我正在尝试以不区分大小写的方式使用 startsWith
和 endsWith
,这样,下面的表达式应该返回 true。
"ALİ".toLowerCase().endsWith("i");
我猜 C# 是不同的和 Java .
发生这种情况是因为小写 ©
(“拉丁大写字母
i with dot above") 转换为两个字符:"拉丁小写字母 i
"和 "combining dot above"。
这解释了为什么它以 i
开头,但不以 i
结尾(而是以组合变音符号结尾)。
在土耳其语言环境中,根据土耳其语言学规则,小写字母 İ
会简单地变成“拉丁文小写字母 i
”,因此您的代码可以正常工作。
这里有一个测试程序可以帮助弄清楚发生了什么:
class Test {
public static void main(String[] args) {
char[] foo = args[0].toLowerCase().toCharArray();
System.out.print("Lowercase " + args[0] + " has " + foo.length + " chars: ");
for(int i=0; i<foo.length; i++) System.out.print("0x" + Integer.toString((int)foo[i], 16) + " ");
System.out.println();
}
}
这是我们在配置为英语的系统上运行它时得到的结果:
$ LC_ALL=en_US.utf8 java Test "İ"
Lowercase İ has 2 chars: 0x69 0x307
这是我们在为土耳其语配置的系统上运行它时得到的结果:
$ LC_ALL=tr_TR.utf8 java Test "İ"
Lowercase İ has 1 chars: 0x69
这甚至是 API 文档为 String.toLowerCase(Locale) 使用的具体示例,这是您可以用来获取特定语言环境(而不是系统默认语言环境)中的小写版本的方法。