C#和Java中字符串的异同

Posted by 佳佳 on 2018-01-16 IT .NET

字符串

在底层上跟C#类似,每个字符串的实例都不可修改。当修改字符串变量时,是将变量指向新的字符串实例,而不是修改原本的实例。Java中也有字符串池机制。

注意:使用 == 运算符比较字符串时,跟C#有根本上的差别。在Java中这里的 == 操作符相当于C#中的 Object.ReferenceEquals(strA, strB) 方法。

Java中比较字符串要使用 equals 方法,忽略大小写比较时使用 equalsIgnoreCase 方法。

码点和代码单元

Java字符串由char值序列组成。char数据类型是一个采用UTF-16编码表示Unicode码点的代码单元。大多数常用Unicode字符使用一个代码单元就可以表示,而辅助字符需要一对代码单元表示。length 方法将返回采用UTF-16编码表示的给定字符串所需要的代码单元数量。

String str = "Hello, \uD842\uDFB7!";
System.out.println(str); // Hello, 𠮷!
int n = str.length();
System.out.println(n); // 10

int cpCount = str.codePointCount(0, str.length());
System.out.println(cpCount); // 9

这里跟C#有相当大的不同,看一下下面的C#示例代码。

string str = "Hello, 𠮷!";
Console.WriteLine(str); // Hello, ??!
Console.WriteLine(str.Length); // 10
Console.WriteLine(Encoding.UTF8.GetByteCount(str)); // 12
Console.WriteLine(Encoding.GetEncoding("GB2312").GetByteCount(str)); // 10
Console.ReadLine();

字符串 "Hello, 𠮷!" 中英文字母、标点符号和空格总共占了8个字节,剩下的一个汉字(𠮷)就比较特殊了。将这个字复制到Java的IDE中会自动变成两个Unicode码(\uD842\uDFB7),可以看出它占了4个字节。

  • Java中的 length 方法和 C#中的 Length 属性的值是一致的,返回的都是代码单元的数量。
  • Java中可以通过 codePointCount 方法获取码点的数量,C#中的字符串没有对应的方法,而通过 Encoding.UTF8.GetByteCount 方法获取的是字节数, Encoding.GetEncoding("GB2312").GetByteCount 方法获取的也是代码单元数量,都不是码点数量。不知道C#中有没有获取码点数量的方法。