码点(code point)和代码单元(code unit),以及String对象中操作码点和代码单元

一个码点是信息原子的单元。文本是一连串的码点。每一个码点是一个由标准的Unicode编码规定的数字;
一个代码单元是一个用来存储编码码点的一部分的单元。在UTF-8中,一个代码单元是8位;在UTF-16中,一个代码单元是16位。
单独的一个代码单元可能代表一个完整的码点,也可能是一个码点的一部分。
例如,一个雪人字符(☃),是一个Unicode码点,也就是一个Unicode编码所代表的符号,在UTF-8中用3个代码单元表示,在UTF-16中用一个代码单元表示。

String对象中操作码点和代码单元

 

     length()方法是获取给定字符串所需的代码单元数量。charAt(i)方法是获取位置i的代码单元,i介于0~s.leng()-1之间。

     “?”符号 在Unicode中编码中,对应的十六进制编码为:1d546。“?”符号 在Java中的代码单元为:"\uD835\uDD46"。

// 以此打印码点
private static void showCodePoint(){
    //String str01="\u1D546";
    String str01="\uD835\uDD46";
    try {
        // 将Unicode字符转为UTF-8格式
        byte[] b = str01.getBytes("UTF-8");
        String rb = new String(b,"UTF-8");
        // 为rb拼接一些内容
        rb = rb+"abc";
        // 打印rb的内容
        System.out.println(rb);
        // 打印rb的代码单元长度
        System.out.println(rb.length());
        // 打印rb的码点长度
        int codePointLen = rb.codePointCount(0, rb.length());
        System.out.println(codePointLen);
        System.out.println("*******************");
        // 根据码点长度,遍历各个码点
        for(int i=0;i<codePointLen;i++){
            // 码点的偏移量
            int index = rb.offsetByCodePoints(0, i);
            System.out.println(index);
            // 码点的十进制表示
            int cp = rb.codePointAt(index);
            // 码点的十六进制表示
            String cpHex = Integer.toHexString(cp);
            System.out.println(cp+" , "+cpHex);
        }
    } catch (Exception e) {
        System.err.println(e);
    }
}

上面的代码,打印出的结果如下:

?abc

5

4

*******************

0

120134 , 1d546

2

97 , 61

3

98 , 62

4

99 , 63

【正向操作】遍历一个字符串,并依次参看每一个码点:

// 遍历一个字符串并查看每一个码点
private static void printCodePoint(){
    String str01="\uD835\uDD46";
    String str02 = str01+"hello"+str01+"World";
    int i=0;
    // 判断i是否小于str02的代码单元长度
    while(i<str02.length()){
        System.out.println("i: "+i);
        // 码点的十进制表示
        int cp = str02.codePointAt(i);
        // 码点的十六进制表示
        String cpHex = Integer.toHexString(cp);
        System.out.println(cp+" , "+cpHex);
        // 判断是否为补充码点,如果是补充码点就加2,如果不是补充码点就加1
        if(Character.isSupplementaryCodePoint(cp)) i+=2;
        else i++;
    }
}

【回退操作】从后往前操作,遍历字符串,并查看每一个码点

// 从后往前操作,遍历字符串,并查看每一个码点
private static void fromLastLoopCodePoint(){
    String str01="\uD835\uDD46";
    String str02 = str01+"hello"+str01+"World";
    // 代码单元的长度
    int codeUtilLen=str02.length();
    for(int i=codeUtilLen;i>0;){
        i--;
        if(Character.isSurrogate(str02.charAt(i))) i--;

        System.out.println("i: "+i);
        // 码点的十进制
        int cp = str02.codePointAt(i);
        //码点的十六进制
        String cpHex = Integer.toHexString(cp);
        System.out.println(cp+" , "+cpHex);
    }
}

上面块代码打印的结果如下:

正向遍历                                回退操作
i: 0                                      i: 13
120134 , 1d546                            100 , 64
i: 2                                      i: 12
104 , 68                                  108 , 6c
i: 3                                      i: 11
101 , 65                                  114 , 72
i: 4                                      i: 10
108 , 6c                                  111 , 6f
i: 5                                      i: 9
108 , 6c                                  87 , 57
i: 6                                      i: 7
111 , 6f                                  120134 , 1d546
i: 7                                      i: 6
120134 , 1d546                            111 , 6f
i: 9                                      i: 5
87 , 57                                   108 , 6c
i: 10                                     i: 4
111 , 6f                                  108 , 6c
i: 11                                     i: 3
114 , 72                                  101 , 65
i: 12                                     i: 2
108 , 6c                                  104 , 68
i: 13                                     i: 0
100 , 64                                  120134 , 1d546

 

  • 8
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值