Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么String.endsWith和String.startWith不一致?_Java_String_Character Encoding_Locale - Fatal编程技术网

Java 为什么String.endsWith和String.startWith不一致?

Java 为什么String.endsWith和String.startWith不一致?,java,string,character-encoding,locale,Java,String,Character Encoding,Locale,我有下面的测试用例,只有第一个断言通过。为什么? @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));

我有下面的测试用例,只有第一个断言通过。为什么?

@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");

我猜和是不同的。

İ
是Unicode字符,是一个长度为1的Java字符串

“İ”.toLowerCase()
返回一个长度为2的Java字符串:

  • Unicode字符(普通的
    i
  • Unicode字符

这是因为没有像“
”上面有点的拉丁文小写字母I”
这样的字符。它在Unicode中不存在。

执行
toLowerCase()
函数后,字符串长度为2而不是1;该字符的小写版本由两个字符表示:

000> "İ".length()
===> 1
000> "İ".toLowerCase().length()
===> 2
其小写表示形式中的第一个字符是小写拉丁语
i
,而第二个字符是变音符号:

000> "İ".toLowerCase().charAt(0)
===> i
000> "İ".toLowerCase().charAt(1)
===> ̇

因此,小写字符串确实以“
i
”开头,但不以它结尾。

之所以会出现这种情况,是因为小写的
İ
(“拉丁大写字母 在英语语言环境中,i和上面的点)变成两个字符:“拉丁文小写字母
i
”和“合并上面的点”

这解释了为什么它以
i
开头,而不是以
i
结尾(它以组合变音符号结尾)

在土耳其语言环境中,小写
code>根据土耳其语言学规则,简单地变成“拉丁小写字母
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();
  }
}
以下是我们在为Turkish配置的系统上运行时得到的结果:

$ LC_ALL=tr_TR.utf8 java Test "İ"
Lowercase İ has 1 chars: 0x69

这甚至是API文档使用的特定示例,您可以使用该方法获取特定区域设置中的小写版本,而不是系统默认区域设置。

您的测试失败,因为您使用了错误的方法

String i2=“İ”
是i的土耳其语大写形式,如果您不提供转换的区域设置,则该方法将失败

使用区域设置可能会有所帮助:)

输出将是

105

105

真的

真的

真的

真的


你能不能把你的问题改一下,这样你就不会做
toLowerCase()
?什么是字符
toLowerCase()
outputs?请查看我的更新
println
sNow尝试打印
i1.length()
i2.length()
。确定长度不同:)我再次更新了我的问题。不接受字符串作为参数,也不返回布尔值,因此无法计算为true。如果我不知道区域设置,该怎么办?
$ LC_ALL=tr_TR.utf8 java Test "İ"
Lowercase İ has 1 chars: 0x69
public static void main(String[] args) {

    String i1 = "i";
    String i2 = "İ".toLowerCase(Locale.forLanguageTag("tr-TR"));

    System.out.println((int)i1.charAt(0)); // 105
    System.out.println((int)i2.charAt(0)); // 105

    System.out.println(i2.startsWith(i1));
    System.out.println(i2.endsWith(i1));
    System.out.println(i1.endsWith(i2));
    System.out.println(i1.startsWith(i2));
}