JAVA和Nginx 教程大全

网站首页 > 精选教程 正文

java 核心技术-12版 卷Ⅰ- 3.6.6 码点与代码单元

wys521 2024-11-28 09:00:32 精选教程 21 ℃ 0 评论

3.6.6 码点与代码单元

Java字符串是一个char 值序列。从3.3.3节已经看到,char 数据类型是采用UTF-16编码表示Unicode码点的一个代码单元。最常用的Unicode字符串可以用一个代码单元表示,而辅助字符需要一对代码单元表示。

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

String greeting =“Hello”;

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

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

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

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

char first = greeting.chatAt(0);// H

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

要想得到第 i 个码点,可以使用以下语句:

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

int cp = greeting.codePointAt(index);

为什么会对代码单元如此大惊小怪?请考虑下面这个句子

String sentence = “is the set of octonions.”;

使用UTF-16编码表示字符(U+1D546)需要两个代码单元。调用 char ch = sentence.charAt(1)

返回的不是一个空格,而是的第二个代码单元。为了避免这个问题,不要使用char 类型。这太底层了。

注释:不要以为可以忽略代码单元在U+FFFF以上的奇怪字符,喜欢 emoji 表情符号的用户可能会在字符串中加入类似(U+1F37A,啤酒杯)的字符

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

int cp = sentence.codePointAt(i);

i += Character.charCount(cp);

可以使用以下语句实现反向遍历:

i--;

if(Character.isSurrogate(sentence.charAt(i))) i--;

int cp = sentence.codePointAt(i);

显然,这很麻烦。更容易的办法是使用 codePoints 方法,它会生成 int 值的一个“流”,每个int 值对应一个码点。(流在卷2中介绍)可以将流转为一个数组(见3.10节)再完成遍历。

int[] codePoints = str.codePoints().toArray();


反之,要把一个码点数组转为一个字符串,可以使用构造器(我们将在第4章详细讨论构造器和 new 操作符)。

String str = new String(codePoints,0,codePoints.length);

要把单个码点转换为一个字符串,可以使用 Character.toString(int)方法:

int codePoint = 0x1F37A;

str = Character.toString(codePoint);

注释:虚拟机不一定把字符串实现为代码单元序列。在Java9中使用了一个更紧凑的表示。只包含单字节代码单元的字符串使用byte数组实现,所有其他字符串使用char 数组。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表