在Java中,什么是代码点与代码单元?
代码点(Code Point):在 Unicode 代码空间中的一个值,取值 U+0000 至 U+10FFFF,代表一个字符。
其中U+0000到U+FFFF为基本字符,U+10000到U+10FFFF为增补字符。
代码单元(Code Unit):在具体编码形式中的最小单位。比如 UTF-16 中一个 code unit 为 16 bits,UTF-8 中一个 code unit 为 8 bits。
对应关系:
一个 code point 可能由一个或多个 code unit(s) 表示。在 U+10000 之前的 code point 可以由一个 UTF-16 code unit 表示,U+10000 及之后的 code point 要由两个 UTF-16 code units 表示。
这也是为什么Java不提倡使用char类型的原因了。
在 Java 中一个 Unicode 字符是使用 UTF-16 编码的 char 进行表示的,也就是一个 char 只能表示 U+0000~U+FFFF 的 Unicode 基本字符(BMP)。因此在 Java 中需要表示 U+10000~U+10FFFF 的字符需要使用 一对代理字符进行表示,高代理字符的范围为 U+D800~U+DBFF,低代理字符的范围为 U+DC00~U+DFFF。比如表示 U+10400 的字符需要两个 char(U+D801, U+DC00)才能表示,这时的代码点长度为 1,而代码单元长度为
2。
在Java中:
String.length()表示代码单元长度
String.codePointCount()表示代码点长度
String.chatAt(int index)表示返回代码单元
String.codePointAt(int index)表示返回代码点
测试:
/** * Created by N3verL4nd on 2016/11/11. */ public class HelloWorld { public static void main(String[] args){ String str = "u03C0 uD835uDD6B"; System.out.println("str="+str+" "+"str.length="+str.length()+" "+ "str.codePointCount="+str.codePointCount(0, str.length())); for (int i = 0; i < str.length(); i++){ System.out.println("str.charAt("+i+")="+str.charAt(i)); } for(int i = 0;i < str.codePointCount(0, str.length()); i++) { System.out.printf("str.codePointAt(" + i + ")=%c(%#4x) ", str.codePointAt(i), str.codePointAt(i)); } // String str = "你好吗ABC"; // int i = 0; // while (i < str.length()) // { // int cp = str.codePointAt(i); // System.out.println(cp); // if (Character.isSupplementaryCodePoint(cp)){ // i += 2; // } // else{ // i++; // } // } } }
输出:
参考:
http://www.blogjava.net/zhenandaci/archive/2009/01/05/249866.html
http://blog.csdn.net/weizhaozhe/article/details/3909079#html
http://www.letiantian.me/2015-03-02-character-encoding/