码迷,mamicode.com
首页 > 编程语言 > 详细

Java中unicode增补字符(辅助平面)相关用法简介

时间:2016-05-06 12:25:52      阅读:493      评论:0      收藏:0      [点我收藏+]

标签:

前言    

Java从1.5版本开始,加入了unicode辅助平面的支持。本文在JDK1.6上测试。

    相关的API主要在Character和String类里。以下这段话是Character的文档说明摘抄。

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

    

    Character 类在对象中包装一个基本类型 char 的值。Character 类型的对象包含类型为 char 的单个字段。 此外,该类提供了几种方法,以确定字符的类别(小写字母,数字,等等),并将字符从大写转换成小写,反之亦然。 字符信息基于 Unicode 标准,版本 4.0。 Character 类的方法和数据是通过 UnicodeData 文件中的信息定义的,该文件是 Unicode Consortium 维护的 Unicode Character Database 的一部分。此文件指定了各种属性,其中包括每个已定义 Unicode 代码点或字符范围的名称和常规类别。 此文件及其描述可从 Unicode Consortium 获得,网址如下: http://www.unicode.org 。char 数据类型(和 Character 对象封装的值)基于原始的 Unicode 规范,将字符定义为固定宽度的 16 位实体。Unicode 标准曾做过修改,以允许那些其表示形式需要超过 16 位的字符。合法代码点 的范围现在是从 U+0000 到 U+10FFFF,即通常所说的 Unicode 标量值。(请参阅 Unicode 标准中 U+n 表示法的定义。) 从 U+0000 到 U+FFFF 的字符集有时也称为 Basic Multilingual Plane (BMP)。代码点大于 U+FFFF 的字符称为增补字符。Java 2 平台在 char 数组以及 String 和 StringBuffer 类中使用 UTF-16 表示形式。在这种表现形式中,增补字符表示为一对 char 值,第一个值取自高代理项 范围,即 (\uD800-\uDBFF),第二个值取自低代理项 范围,即 (\uDC00-\uDFFF)。 所以,char 值表示 Basic Multilingual Plane (BMP) 代码点,其中包括代理项代码点,或 UTF-16 编码的代码单元。int 值表示所有 Unicode 代码点,包括增补代码点。int 的 21 个低位(最低有效位)用于表示 Unicode 代码点,并且 11 个高位(最高有效位)必须为零。除非另有指定,否则与增补字符和代理项 char 值有关的行为如下: 只接受一个 char 值的方法无法支持增补字符。它们将代理项字符范围内的 char 值视为未定义字符。例如,Character.isLetter(‘\uD840‘) 返回false,即使是特定值,如果在字符串的后面跟着任何低代理项值,那么它将表示一个字母。 接受一个 int 值的方法支持所有 Unicode 字符,其中包括增补字符。例如,Character.isLetter(0x2F81A) 返回 true,因为代码点值表示一个字母(一个 CJK 象形文字)。 在 Java SE API 文档中,Unicode 代码点 用于范围在 U+0000 与 U+10FFFF 之间的字符值,而 Unicode 代码点 用于作为 UTF-16 编码的代码单元的 16 位 char 值。有关 Unicode 技术的详细信息,请参阅 Unicode Glossary。 

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

    可以看出,增补字符是用一个长度为2的char数组表示的,分别表示高代理项和低代理项。用法可以参考如下的例子

例一

    codePointAt方法的源码如下:

<span style="font-family:SimSun;font-size:14px;">    public static int codePointAt(char[] a, int index) {
	return codePointAtImpl(a, index, a.length);
    }</span>
<span style="font-family:SimSun;font-size:14px;">    static int codePointAtImpl(char[] a, int index, int limit) {
        char c1 = a[index++];
        if (isHighSurrogate(c1)) {
            if (index < limit) {
                char c2 = a[index];
                if (isLowSurrogate(c2)) {
                    return toCodePoint(c1, c2);
                }
            }
        }
        return c1;
    }</span>
<span style="font-family:SimSun;font-size:14px;">    public static int toCodePoint(char high, char low) {
        return ((high - '\uD800') << 10)
            + (low - '\uDC00') + 65536;
    }</span>

可以看出,如果是输入增补字符数组,那么,当传入索引是0的时候,就会返回整个增补字符的码点,当传入索引是1的时候,就会返回增补字符数组中第二个字符的码点。

<span style="font-family:SimSun;font-size:14px;">public static void main(String[] args) {
        char[] c = Character.toChars(Integer.parseInt("1D306", 16));//1D306是一个辅助平面字符
        System.out.println(Character.codePointAt(c, 0));//输出119558,这个是1D306对应的10进制值
        System.out.println(Character.codePointAt(c, 1));//输出57094,这个是c[1]对应字符的10进制值
    }</span>

当传入的字符数组是都是基本平面的字符时,直接返回传入的索引对应的基本平面字符的码点。

<span style="font-family:SimSun;font-size:14px;">    public static void main(String[] args) {
        char[] c = {'a', 'b', '测', '试'};
        System.out.println(Character.codePointAt(c, 0));//97
        System.out.println(Character.codePointAt(c, 1));//98
        System.out.println(Character.codePointAt(c, 2));//27979
        System.out.println(Character.codePointAt(c, 3));//35797
        System.out.println((char) 97);//a
        System.out.println((char) 98);//b
        System.out.println((char) 27979);//测
        System.out.println((char) 35797);//试
    }</span>

例二

String类的length和codePointCount方法,在处理增补字符时,返回的数据是不一样的,而对于基本平面来说,返回值都是一样的。
length返回字符串长度,codePointCount放回代码点数量。
<span style="font-family:SimSun;font-size:14px;">    public static void main(String[] args) {
        char[] c = Character.toChars(Integer.parseInt("1D306", 16));//1D306是一个辅助平面字符
        System.out.println(Character.codePointAt(c, 0));//输出119558,这个是1D306对应的10进制值
        System.out.println(Character.codePointAt(c, 1));//输出57094,这个是c[1]对应字符的10进制值
        System.out.println(new String(c).codePointAt(0));//输出119558,这个是1D306对应的10进制值
        System.out.println(new String(c).codePointAt(1));//输出57094,这个是c[1]对应字符的10进制值
        String str = "abcdefg" + new String(c);
        System.out.println(str.length());//9
        System.out.println(str.codePointCount(0, str.length()));//8
    }</span>
上面的例子,字符串长度是9,因为字符U+1D306需要一个长度为2的字符数组来表示,而实际上代码点只有1个,所以会分别返回9和8。



Java中unicode增补字符(辅助平面)相关用法简介

标签:

原文地址:http://blog.csdn.net/gjb724332682/article/details/51324036

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!