代码改变世界

C#和Java中字符串的异同

2018-01-16 16:24  佳佳的博客  阅读(862)  评论(2编辑  收藏  举报

字符串

在底层上跟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#中有没有获取码点数量的方法。

感谢 @OpportunityLiu 的回复。可以使用 StringInfo 类获取码点数。

Internally, the methods of the StringInfo class call the methods of the CharUnicodeInfo class to determine character categories. Starting with the .NET Framework 4.6.2, character classification is based on The Unicode Standard, Version 8.0.0. For the .NET Framework 4 through the .NET Framework 4.6.1, it is based on The Unicode Standard, Version 6.3.0.

示例代码:

StringInfo si = new StringInfo(str);
Console.WriteLine(si.String); // Hello, ??!
Console.WriteLine(si.LengthInTextElements); // 9