Java字符编码、码点与代码单元_字符编码单元-程序员宅基地

技术标签: java  # Java基础  后端  

一、字符编码

1、Unicode

Unicode万国码国际码统一码单一码)是计算机科学领域里的一项业界标准。它对世界上大部分的文字系统进行了整理、编码,使得电脑可以用更为简单的方式来呈现和处理文字。

Unicode 为世界上所有字符都分配了一个唯一的数字编号,这个编号范围从 0x000000 到 0x10FFFF (十六进制),有 110 多万,每个字符都有一个唯一的 Unicode 编号,这个编号一般写成 16 进制,在前面加上 U+。例如:“马”的 Unicode 是U+9A6C。Unicode 就相当于一张表,建立了字符与编号之间的联系。

所以Unicode**本身只规定了每个字符的数字编号是多少,并没有规定这个编号如何存储。**因此才有了多种字符编码的存储方案,比较常见就是国际通用字符编码utf-8。

2、utf-8、utf-16和utf-32区别

UTF-32是一种定长编码,使用1个32bit的码元,其值与Unicode编码值相等

UTF-16也是一种变长编码,对于一个Unicode字符被编码成1至2个码元,每个码元为16位。在基本多语言平面内的码位UTF-16编码使用1个码元且其值与Unicode是相等的(不需要转换),但在辅助平面内的码位在UTF-16中被编码为一对16bit的码元(即32bit,4字节)

UTF-8是一种变长编码,对于一个Unicode的字符被编码成1至4个字节。Unicode编码与UTF-8的编码的对应关系:

Unicode编码 UTF-8编码(二进制)
U+0000 – U+007F 0xxxxxxx
U+0080 – U+07FF 110xxxxx 10xxxxxx
U+0800 – U+FFFF 1110xxxx 10xxxxxx 10xxxxxx
U+10000 – U+10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

一个字节的uft8表示的unicode 码范围为(0 ~0x7F)
两个字节长度的uft8 表示的unicode码范围为(0x80 ~ 0x07FF)
三个字节长度的uft8 表示的unicode码范围为(0x0800 ~ 0xFFFF)
四个字节长度的uft8 表示的unicode码范围为( 0x10000 ~ 0x10FFFF)

二、码点和代码单元

1、码点和代码单元

Java中char数据类型是一个采用UTF-16编码表示Unicode码点的代码单元,最常用的Unicode字符使用一个代码单元就可以表示,而辅助字符则需要一对代码单元表示。

通俗理解是有些Unicode字符可以用一个char值表示,表示一个码点,一个代码单元;但另外的Unicode字符则需要两个char值来表示,即辅助字符需要用两个char值,但表示一个码点,两个代码单元。

2、实战理解

字符串中如果有一些非常规字符的话,使用charAt会导致结果不正确

public class Test {
    
    public static void main(String[] args) {
    
        String test="Hello";
        System.out.println(test);
        System.out.println(test.length());//得到的是代码单元的数量7, 占两个代码单元
        System.out.println(test.codePointCount(0,test.length()));//得到的是码点的数量6

        System.out.println((int)test.charAt(2));//返回第三个的代码单元:得到H的int型

        int index=test.offsetByCodePoints(0,1);//得到第二个码点位置
        int cp=test.codePointAt(index);//得到该位置码点int型表示
        System.out.println(cp);
    }
}

3、遍历字符串

对于无非常规字符的字符串,我们可以使用charAt来遍历(代码单元遍历);而对于非常规字符的字符串,我们就只能遍历码点来实现

public class Test {
    
    public static void main(String[] args) {
    
    // 也可以实现反向遍历
    // if(Character.isSurrogate(test.charAt((i)))) i--;
       String test = "Hello";
        for (int i = 0; i < test.length(); ) {
    
            int cp = test.codePointAt(i);
            if (Character.isSupplementaryCodePoint(cp)) i += 2;
            else i++;
            System.out.print((char) cp);
        }
    }
}

第二种方法

public class Test {
    
    public static void main(String[] args) {
    
        String test="Hello";
        int [] codePoints=test.codePoints().toArray();
        for(int i=0;i<codePoints.length;i++){
    
            System.out.println((char)codePoints[i]);
        }
        //将码点数组转换成字符串
        String str=new String(codePoints,0,codePoints.length);
        //Hello
        System.out.println(str);
    }
}

《Java核心技术卷一》

https://blog.csdn.net/hongsong673150343/article/details/88584753

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lemon_TT/article/details/122197511

智能推荐

shell中的单引号和双引号理解_shell脚本双引号没了-程序员宅基地

文章浏览阅读5.4k次,点赞3次,收藏4次。问题描述: 最近在写shell脚本的时候,涉及到一个使用shell脚本发送json数据的问题,就是发送的json数据双引号不见了,导致数据格式不正确,收到了错误的响应。后来仔细查看了资料才发现自己之前对shell单引号和双引号的理解有一些问题,在此记录一些现象和结果。问题解析: 1.首先,我这边使用的..._shell脚本双引号没了

Python安全攻防-从入门到入狱-程序员宅基地

文章浏览阅读1.8w次,点赞43次,收藏246次。Python安全攻防-从入门到入狱_python安全攻防

混合云的容量扩展与功能添加-程序员宅基地

文章浏览阅读61次。1.使用混合云来增加数据中心容量“混合云”这个术语已经在IT操作团队中普遍使用,但并不是每个人对此都意见一致。基本上,混合云是指任何情况下,企业的部分应用程序在企业的数据中心运行,另一部分在一个公共云或多个公共云(如AWS,Microsoft Azure或Google云平台)中运行。同时,私有云是企业将云类型架构和功能并入自己的私有数据中心。这里的..._基于共有云快速扩展

网络——奈奎斯特定理和香农定理-程序员宅基地

文章浏览阅读7.7k次,点赞21次,收藏54次。在宽带受限且有噪声的信道中,为了不产生误差,信息的数据传输速率有上限值。那么,信道的极限数据传输速率就为:W∗log2(1+S/N)W*log_2(1+S/N)W∗log2​(1+S/N)其中,W 为带宽,单位是Hz,S/N 是信噪比(没有单位)注意:若题目中给出信噪比包含单位dB(分贝),则需要先进行转化例如,电话系统的典型参数是信道带宽为3000Hz,信噪比为30dB,则该系统的最大数据传输速率为多少?【分析】 由 10∗log10(S/N)=30dB10*log_10(S/N) = 30_奈奎斯特定理

flutter 旋转指定角度的动画组件_flutter 旋转角度-程序员宅基地

文章浏览阅读3.9k次。import 'package:flutter/material.dart';/// 旋转动画,旋转指定角度 动画 + Transform.rotate() 实现class RotateContainer extends StatefulWidget{ final double endAngle; // 旋转角度 final bool rotated; //是否旋转 ..._flutter 旋转角度

tsl加密算法_【TLS】关于TLS中密码套件说明-程序员宅基地

文章浏览阅读1.2k次。TLS主要包含两部分协议,一部分是Record Protocol,描述了数据的格式,另一部分是Handshaking Protocols,描述了握手过程。握手的目的有两个,一个是保证通信的双方都是自己期待的对方,任何一方都不可能被冒充,另一个是交换加密密码,使得只有通信的双方知道这个密码,而别人不知道。前一个就是我们常说的认证,而后一个就是密码交换。认证是通过证书来达到的,而密码交换是通过证书里面..._谷歌支持的tsl密码套间

随便推点

关于sublime3的使用-程序员宅基地

文章浏览阅读40次。一、安装Package Control使用Ctrl+`快捷键或者通过View->Show Console菜单打开命令行,粘贴如下代码:importurllib.request,os; pf ='Package Control.sublime-package'; ipp =sublime.installed_packages_path(); urllib.request.inst...

uni-app 打包 ios 测试包,通过 testFlight 分发测试_uniapp testflight-程序员宅基地

文章浏览阅读5.2k次。uni-app 打包 ios 测试包,通过 testFlight 分发测试_uniapp testflight

php7 libevent扩展,php7下安装event扩展-程序员宅基地

文章浏览阅读66次。一·、安装支持库libevent,需要编译高版本(这里以最新版本release-2.1.8-stable为例)wget -c https://github.com/libevent/libevent/releases/download/release-2.1.8-stable/libevent-2.1.8-stable.tar.gz -P /usr/local/srccd /usr/local/s..._mac php7 pecl libevent

RabbitMQ:SpringBoot+RabbitMQ的简单实现之Topic模式_springboot rabbitmq 消费者如何写topic模式的-程序员宅基地

文章浏览阅读1.1k次。RabbitMQ:SpringBoot+RabbitMQ的简单实现之Topic模式1.在pom中添加springboot对amqp的支持&amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt; &amp;lt;artifactId&amp;gt;spring-boot-starter-amqp&a_springboot rabbitmq 消费者如何写topic模式的

微信小程序——使用excel-export导出excel_excel_export('a1:r18', 'store') excel_export('a20:-程序员宅基地

文章浏览阅读8.3k次,点赞3次,收藏41次。背景在学习微信小程序的过程中,需要导出excel文件数据,可是却没有后台服务器,所以只能够想着使用纯前端去导出excel 使用插件:excel-export导出思想将数据封装成excel文件 将excel文件上传到云存储中 将云存储的excel文件以图片的格式下载到本地 修改图片文件后缀为xlsx,成为excel文件操作将数据封装成excel文件;将excel文件上传到云存储中 建立云函数(我的云函数名称:uploadexportfile),打开云函数终端,安装excel-expo_excel_export('a1:r18', 'store') excel_export('a20:r34', 'agent')

element-ui中跑马灯的使用_elementplus走马灯获取当前-程序员宅基地

文章浏览阅读2.2w次,点赞10次,收藏13次。&lt;template&gt; &lt;div id="app"&gt; &lt;el-carousel :interval="5000" arrow="always"&gt; &lt;el-carousel-item v-for="(img,index) in imgList" :key="index"&gt; _elementplus走马灯获取当前