Java学习笔记6 - Unicode编码与UTF-16
2013-07-21 17:43
796 查看
一、UTF-16编码方法
Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。Unicode用数值0x000000-0x10FFFF来映射这些字符,最多可以容纳1114112个字符,或者说有1114112个代码点(code point)。代码点就是字符对应数值加上前缀U+,如U+0041就是字母A的代码点。UTF-8、UTF-16、UTF-32都是将数字转换到程序数据的转换格式。
1 代码点在U+0000到U+FFFF(注意U+D800到U+DBFF无定义)之间的字符(也叫做BMP, Basic Multilingual Plane),直接用两个字节表示。
2 代码点在U+10000到U+10FFFF(共有0xFFFFF个字符)之间的字符(也叫做增补字符集, supplementary characters),需要用四个字节表示。
前两个字节的范围是U+D800到U+DBFF(也叫高代理项, high-surrogates range),
后两个字节的范围是U+DC00到U+DFFF(也叫低代理项, low-surrogates range)。
转换方式如下:
2.1 将代码点对应数值减去0x10000,结果范围0x0000到0xFFFFF。
2.2 将结果的高10bit与0xD800做逻辑或运算,低10bit与0xDC00做逻辑或运算,
2.3 将两部分组合起来就是该字符值的UTF-16编码。
3 根据存储顺序的不同,UTF-16分为UTF-16LE和UTF-16BE,Windows和Linux一般使用UTF-16LE,而苹果操作系统使用UTF-16BE。
二、Java中的UTF-16
0 在JDK1.5之后Java才开始支持增补字符集,由JSR 204(Unicode Supplementary Character Support)实现。
1 Java中使用char(两个字节)作为表示字符的代码单元(code unit)。因此,Java中单个char是无法表示增补字符的,而且位于U+D800到U+DBFF和U+DC00到U+DFFF的char被视为无定义字符。
2 在Java平台中,char[]、String、StringBuilder和StringBuffer类中采用了UTF-16编码,BMP字符用一个char表示,增补字符使用一对char表示。
3
Java使用代码点(Unicode code point)这个概念来表示范围在U+0000与U+10FFFF之间的字符值,代码单元(Unicode code unit)表示用于作为UTF-16编码的代码单元的 16位char值。因此,在Character类的API中,可以看到很多包含codePoint的方法。
4 String类中有关方法的分析
4.1 在String中,索引值指的是代码单元,所以增补字符在String中占两个位置。
4.2 int length()方法返回的是代码单元的数量,如果字符串中含有增补字符,该方法返回的值并非实际的字符数。
4.3 char charAt(int index)方法直接返回索引出的char值,不管该char是否为增补字符代理项。
4.4 int codePointAt(int index)方法,这个方法实际上是调用Character.codePointAtImpl()方法实现,源码如下
static int codePointAtImpl(char[] a, int index, int limit) {
char c1 = a[index++];
if (isHighSurrogate(c1)) {
if
4000
(index < limit) {
char c2 = a[index];
if (isLowSurrogate(c2)) {
return toCodePoint(c1, c2);
}
}
}
return c1;
}
所以,当index和index+1均小于length(),且index的char在高代理范围内,就返回增补字符的代码点,否则返回index的char值。
4.5 int codePointBefore(int index),实际上调用Character.codePointBeforeImpl()方法。
static int codePointBeforeImpl(char[] a, int index, int start) {
char c2 = a[--index];
if (isLowSurrogate(c2)) {
if (index > start) {
char c1 = a[--index];
if (isHighSurrogate(c1)) {
return toCodePoint(c1, c2);
}
}
}
return c2;
}
所以,当index-1和index-2均非负,且index-2的char在高代理范围内,index-1的char在低代理范围内,则返回增补字符的代码点,否则返回index-1的char值。
4.6 int codePointCount(int beginIndex, int endIndex),调用Character.codePointCountImpl()
static int codePointCountImpl(char[] a, int offset, int count) {
int endIndex = offset + count;
int n = 0;
for (int i = offset; i < endIndex; ) {
n++;
if (isHighSurrogate(a[i++])) {
if (i < endIndex && isLowSurrogate(a[i])) {
i++;
}
}
}
return n;
}
所以,该方法可以真正计算出字符串中的字符数量。
4.7 offsetByCodePoints(int index, int codePointOffset)这个方法主要是计算从index开始,接下来第codePointOffset个代码点的下标。
4.8 int indexOf(int ch),其他相关方法,如lastIndexOf()等,原理类似。
如果ch的大小在0x0000到0xFFFF之间时,返回值是第一次满足charAt(k) == ch时的k值
如果ch的大小超过0xFFFF,返回值是第一次满足codePointAt(k) == ch的k值
如果都不满足,返回-1
Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。Unicode用数值0x000000-0x10FFFF来映射这些字符,最多可以容纳1114112个字符,或者说有1114112个代码点(code point)。代码点就是字符对应数值加上前缀U+,如U+0041就是字母A的代码点。UTF-8、UTF-16、UTF-32都是将数字转换到程序数据的转换格式。
1 代码点在U+0000到U+FFFF(注意U+D800到U+DBFF无定义)之间的字符(也叫做BMP, Basic Multilingual Plane),直接用两个字节表示。
2 代码点在U+10000到U+10FFFF(共有0xFFFFF个字符)之间的字符(也叫做增补字符集, supplementary characters),需要用四个字节表示。
前两个字节的范围是U+D800到U+DBFF(也叫高代理项, high-surrogates range),
后两个字节的范围是U+DC00到U+DFFF(也叫低代理项, low-surrogates range)。
转换方式如下:
2.1 将代码点对应数值减去0x10000,结果范围0x0000到0xFFFFF。
2.2 将结果的高10bit与0xD800做逻辑或运算,低10bit与0xDC00做逻辑或运算,
2.3 将两部分组合起来就是该字符值的UTF-16编码。
3 根据存储顺序的不同,UTF-16分为UTF-16LE和UTF-16BE,Windows和Linux一般使用UTF-16LE,而苹果操作系统使用UTF-16BE。
二、Java中的UTF-16
0 在JDK1.5之后Java才开始支持增补字符集,由JSR 204(Unicode Supplementary Character Support)实现。
1 Java中使用char(两个字节)作为表示字符的代码单元(code unit)。因此,Java中单个char是无法表示增补字符的,而且位于U+D800到U+DBFF和U+DC00到U+DFFF的char被视为无定义字符。
2 在Java平台中,char[]、String、StringBuilder和StringBuffer类中采用了UTF-16编码,BMP字符用一个char表示,增补字符使用一对char表示。
3
Java使用代码点(Unicode code point)这个概念来表示范围在U+0000与U+10FFFF之间的字符值,代码单元(Unicode code unit)表示用于作为UTF-16编码的代码单元的 16位char值。因此,在Character类的API中,可以看到很多包含codePoint的方法。
4 String类中有关方法的分析
4.1 在String中,索引值指的是代码单元,所以增补字符在String中占两个位置。
4.2 int length()方法返回的是代码单元的数量,如果字符串中含有增补字符,该方法返回的值并非实际的字符数。
4.3 char charAt(int index)方法直接返回索引出的char值,不管该char是否为增补字符代理项。
4.4 int codePointAt(int index)方法,这个方法实际上是调用Character.codePointAtImpl()方法实现,源码如下
static int codePointAtImpl(char[] a, int index, int limit) {
char c1 = a[index++];
if (isHighSurrogate(c1)) {
if
4000
(index < limit) {
char c2 = a[index];
if (isLowSurrogate(c2)) {
return toCodePoint(c1, c2);
}
}
}
return c1;
}
所以,当index和index+1均小于length(),且index的char在高代理范围内,就返回增补字符的代码点,否则返回index的char值。
4.5 int codePointBefore(int index),实际上调用Character.codePointBeforeImpl()方法。
static int codePointBeforeImpl(char[] a, int index, int start) {
char c2 = a[--index];
if (isLowSurrogate(c2)) {
if (index > start) {
char c1 = a[--index];
if (isHighSurrogate(c1)) {
return toCodePoint(c1, c2);
}
}
}
return c2;
}
所以,当index-1和index-2均非负,且index-2的char在高代理范围内,index-1的char在低代理范围内,则返回增补字符的代码点,否则返回index-1的char值。
4.6 int codePointCount(int beginIndex, int endIndex),调用Character.codePointCountImpl()
static int codePointCountImpl(char[] a, int offset, int count) {
int endIndex = offset + count;
int n = 0;
for (int i = offset; i < endIndex; ) {
n++;
if (isHighSurrogate(a[i++])) {
if (i < endIndex && isLowSurrogate(a[i])) {
i++;
}
}
}
return n;
}
所以,该方法可以真正计算出字符串中的字符数量。
4.7 offsetByCodePoints(int index, int codePointOffset)这个方法主要是计算从index开始,接下来第codePointOffset个代码点的下标。
4.8 int indexOf(int ch),其他相关方法,如lastIndexOf()等,原理类似。
如果ch的大小在0x0000到0xFFFF之间时,返回值是第一次满足charAt(k) == ch时的k值
如果ch的大小超过0xFFFF,返回值是第一次满足codePointAt(k) == ch的k值
如果都不满足,返回-1
相关文章推荐
- java 字符集与编码 unicode、utf-8、utf-16
- java乱码 java使用的编码是utf-8还是utf-16还是unicode
- Java学习笔记·Servlet parameter参数传递utf-8文字编码正常显示
- Unicode中的UTF-8, UTF-16, UTF-16LE, UTF-16BE编码及转换 | Java基础
- 字符编码笔记:ASCII、Unicode、UTF-8、UTF-16、UCS、BOM、Endian
- 字符编码终极笔记:ASCII、Unicode、UTF-8、UTF-16、UCS、BOM、Endian
- 黑马程序员java基础学习日记——做题遇到GBK查资料发现了个有趣的文章——ASCII、Unicode、GBK和UTF-8字符编码的区别联系
- 各种编码UNICODE、UTF-8、ASCII学习笔记
- ASCII,Unicode,UTF-8,UTF-16 学习笔记
- 字符编码笔记:ASCII,Unicode和UTF-8
- JAVA字符编码系列一:Unicode,GBK,GB2312,UTF-8概念基础
- java学习笔记16——抽象类
- 字符编码笔记:ASCII,Unicode和UTF-8
- 字符编码:ASCII、Unicode、UTF-8、UTF-16、UCS、BOM、Endian
- (转)字符编码笔记:ASCII,Unicode和UTF-8
- 字符编码笔记:ASCII,Unicode和UTF-8
- Java的中文处理学习笔记:Hello Unicode
- JAVA字符编码系列二:Unicode,ISO-8859,GBK,UTF-8编码及相互转换
- 字符编码笔记:ASCII,ANSI,Unicode和UTF-8
- Unicode编码及其实现:UTF-16、UTF-8,and more