java中如何保存unicode字符

java中如何保存unicode字符

什么是Unicode编码

Unicode编码是国际组织制定的旨在容纳全球所有字符的编码方案,在Unicode编码出来之前,各个国家都有自己的不同标准:美国的ASCII、西欧的ISO

8859-1、俄罗斯的KOI-8、中国的GB

18030和BIG-5等。但是标准太多就会产生问题,首先,同一个代码值,可能在不同的编码机制中对应不同的字母;其次,不同的编码标准对应的编码长度可能有所不同。例如有些常用的字符采用单字节编码,而另外一些字符则需要两个或多个字节编码。

Unicode的出现,解决了上述问题,它为世界上的所有字符都分配了一个唯一的数字编号,这个编号范围为

0x000000 ~

0x10FFFF,有110多万,每个字符对应一个唯一的编号,这个编号表示为16进制,在前面加上U+。例如:"马"的Unicode是U+9A6C。Unicode就相当于是一张表,记录了字符与编号之间的联系。

如何使用Unicode编码表

现在国际组织已经做好了Unicode的编码表,那么各个程序中需要用多少个字节来保存字符呢?这个问题需要各个程序设计专家们解决。

最简单的方式当然是采用定长编码,直接使用32bit的码元,与Unicode中的编码范围一一对应,这便是UTF-32编码方案。

java中采用UTF-16的编码方案

java中使用的是UTF-16的编码方案,即用2字节(16bit)来保存字符,2字节去一一对应Unicode的数字编号显然是不可能。那么java中是如何实现的,首先引入一些概念。

1. 码点:Unicode中的数字编号,一个数字编号就是一个码点 2. 代码平面:

Unicode中的编号可以分成17个部分,分别是: + 0x000000 ~ 0x00FFFF

(经典字符) + 0x010000 ~ 0x01FFFF (辅助字符) + 0x020000 ~ 0x02FFFF

(辅助字符) + ................... + 0x0F0000 ~ 0x0FFFFF (辅助字符) +

0x100000 ~ 0x10FFFF (辅助字符) 3.

代码单元:代码单元均由4个16进制数构成:U+xxxx。由于UTF-16是变长编码,所以一个码点可能对应一个代码单元,也可能对应两个代码单元

首先经典的字符平面(0x0000 ~

0xFFFF)可以由16bit一一对应,但是经典字符中,还有2048个位置(0xD800 ~

0xDFFF)是空缺的,即什么都没有对应。因此这2048个位置就可以拿出来组合成其他的码点,还剩下多少个码点没法表示:个码点。2048刚好可以拆分成1024

+

1024,而1024又刚好是,因此这空缺的2048个位置就可以拆开成两部分,使用两个代码单元来组合表示其他的码点。

具体来说是0xD800 ~ 0xDBFF为第一个代码单元,0xDC00 ~

0xDFFF为第二个代码单元。

例如:"🍷"符号在java中就占用两个代码单元,打印上述的length(),得到的结果是2。

12345678910public class Test{ public static void main(String[] args) { String hello = "🍷hello"; System.out.println(hello.length()); // length()函数输出的是代码单元,因此输出结果为 7 // 如果想要输出有多少个码点,可以用codePointCount int len = hello.codePointCount(0, hello.length()); System.out.println(len); // 6 }}

因此:在java中强烈建议不在要程序中使用char类型,除非确实需要处理UTF-16代码单元。

对于string(包含emoji表情)的遍历,应该采用如下方式:

1234567891011121314151617181920public class Test{ public static void main(String[] args) { String hello = "🍷hello"; // 如果使用charAt会输出如下结果 for (int i = 0; i < hello.length(); i++) { System.out.println(hello.charAt(i)); } //输出: ? ? h e l l o // 采用如下方式进行遍历 // 1. 首先将所有字符的码点保存到一个整数数组中 int[] codePoints = hello.codePoints().toArray(); // 2. 遍历所有码点,并查表将其转换成字符 for(int i = 0; i < codePoints.length; i++) { String str = Character.toString(codePoints[i]); System.out.println(str); } // 输出:🍷 h e l l o }}

相关推荐

《淘宝》口令使用方法
365天稳定更新

《淘宝》口令使用方法

📅 06-28 👀 920
如何赚钱发财?快速赚钱的10种方法
bet3365标准版

如何赚钱发财?快速赚钱的10种方法

📅 09-28 👀 4728
金立5g手机价格表大全(金立最新款手机的售价是多少)
i54200h现在还够用吗 i54200h处理器怎么样?
体育平台送365彩金

i54200h现在还够用吗 i54200h处理器怎么样?

📅 07-13 👀 1808