Java中的字符串,代码点和代码单元

在Java字符串处理时,在使用length和charAt方法时,应该格外小心,因为length返回的是UTF-16编码表示下的代码单元数量,而非我们所认为的字符的个数,charAt方法返回的是指定位置处的代码单元,而非我们所认为的字符。

至于为什么都是“代码单元”而非字符,这和Unicode字符集的增补相关。

要想获得字符串中的字符的个数,应当使用aString.codePointCount(0, aString.length());要想获得指定位置处的字符,使用aString.codePointAt(i);需要注意codePointAt的返回值,是int而非char。

枚举字符串的正确方法:

for (int i = 0; i < aString.length();) {
int character = aString.codePointAt(i);
if (Character.isSupplementaryCodePoint(character)) i += 2;
else ++i;
}

将codePoint转换为char[]可调用Character.toChars方法,然后可进一步转换为字符串:

String s=Character.toChars(codePoint);

========================

   Java字符串由char序列组成。从前面已经看到,字符数据类型是一个采用UTF-16编码表示Unicode代码点的代码单元。大多数的常用Unicode字符使用一个代码单元就可以表示,而辅助字符需要一对代码单元表示。

    length方法将返回采用UTF-16编码表示的给定字符串所需要的代码单元数量。例如:

        Stringgreeting = "Hello";

        int n = greeting.length();// is 5

    要想得到实际的长度,即代码点数量,可以调用:

        int cpCount =greeting.codePointCount(0, greeting.length());

    调用s.charAt(n)将返回位置n的代码单元,n介于0~s.length()-1之间。例如:

        char first =greeting.charAt(0); // first is 'H'

        char last =greeting.charAt(4); // last is 'o'

    要想得到第i个代码点,应该使用下列语句

        int index =greeting.offsetByCodePoints(0, i);

        int cp =greeting.codePointAt(index);

    注释:Java以独特的风格对字符串中的代码单元计数:字符串中的第一个代码单元位置为0。这种习愤起源于C,这样处理主要出于技术上的原因。具体理由似乎已经淡忘,而麻烦却保留了下来。但是,许多程序员习惯于这种风格,因而Java设计者也就将其保留了下来。

    为什么会对代码单元如此大惊小怪?请考虑下列语句:

    Ƶis the set of integers

    使用UTF-16编码表示Ƶ需要两个代码单元。调用char ch =sentence.charAt(1);返回的不是空格,而是第二个代码单元Z。为了避免这种情况的发生,请不要使用char类型。这太低级了。

    如果想要遍历一个字符串,并且依次査看每一个代码点,可以使用下列语句:

        int cp =sentence.codePointAt(i);

        if (Character.isSupplementaryCodePoint(cp))i += 2;

        else i++;

    非常幸运,codePointAt方法能够辨别一个代码单元是辅助字符的第一部分还是第二部分,并能够返回正确的结果。也就是说,可以使用下列语句实现回退操作:

        i--;

        int cp =sentence.codePointAt(i);

        if (Character.isSupplementaryCodePoint(cp))i--;

参考文章

深入学习Java中的字符串,代码点和代码单元 - VinoZhu - 博客园

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

失业找工作中

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值