Character与Unicode

Character 基本数据类型char  的包装类
Character 类型的对象包含一个 char 类型的字段  

该类提供了几种方法来确定字符的类别(小写字母、数字等),并将字符从大写转换为小写,反之亦然
Character在 jdk8中,   基于版本Unicode6.0.2 标准
Character 类的方法和数据是通过 UnicodeData 文件中的信息定义的,
该文件是 Unicode Consortium 维护的 Unicode Character Database 的一部分
此文件指定了各种属性,其中包括每个已定义 Unicode 代码点或字符范围的名称和常规类别
此文件及其描述可从 Unicode Consortium 获得,网址如下:
http://www.unicode.org

在Java中,char 数据类型(和 Character 对象封装的值)基于原始的 Unicode 规范
将字符定义为固定宽度的 16 位实体
也就是说 char表示UTF-16编码的代码单元
对于0号平面来说,一个码点使用一个代码单元
对于辅助平面,那么一个码点将会是两个代码单元
在Unicode简介中,我们有说到,一个字符在Unicode字符集中的二进制值称为代码点
在UTF-16编码中,0号平面内,一个码点16位表示,称之为一个代码单元
总结下就是:
Unicode字符集中,一个字符对应一个代码点
UTF-16中,16位数表示的是一个代码单元
那么在0 号平面内,一个代码单元就能够表示一个代码点
但是在辅助平面,一个代码点需要两个代码单元
java中的char就是UTF-16中的代码单元
所以说,一个char表示一个代码单元,可能并不是一个字符
实在理解不了的话,就可以记住,有些字符需要两个char表示,一个char可能仅仅是某个字符的一半
Unicode字符数据库(Unicode Character Database UCD  )
是由许多列出Unicode字符属性和相关数据的数据文件组成
可以查看http://www.unicode.org/ucd/  了解UCD的相关信息
查看
https://www.unicode.org/reports/tr44/#Property_Values
中的Property Value Lists章节
General Category Values以及Bidirectional Class Values章节了解
 
Character中定义了大量的常量,其实就是对于这两个章节信息的描述
 
可以简单地理解为是字符的属性
比如一个字符可能是大写字母,可能是小写字母这样子
比如getType方法就是专门用来返回属性的,根据这个属性进而可以推断出更多的信息就像下面的的例子这样
Unicode想要深入研究,也是一门学问,此处不再继续深入,精力有限
对于Character我们只需要记住
Character 类的方法和数据是通过 UnicodeData 文件中的信息定义的

char 数据类型(和 Character 对象封装的值)基于原始的 Unicode 规范
提供的方法和数据也是基于Unicode规范来的
他将字符定义为固定宽度的 16 位实体,也就是只能表示一个代码单元
而Unicode也可能是有两个代码单元组成
也就是一个代码单元可能完整的表示了一个代码点,也可能是一个代码点的一部分
除非你真的有必要对UTF-16中的代码单元进行操作,
否则最好不要在程序中使用char类型的原因
原因很简单,一个char并不一定能够代表一个字符,可能只是一半字符
接下来对Character的基础方法进行介绍,过于深入Unicode的方法不再说明
有兴趣的可以研究下

常用属性

去掉上面说到的通用类别常量信息,还有以下属性
无符号二进制形式表示 char 值的位数 public static final int SIZE = 16;
无符号二进制形式表示 char 值的字节数 public static final int BYTES = SIZE / Byte.SIZE;
表示基本类型 char 的 Class 实例 public static final Class<Character> TYPE = (Class<Character>) Class.getPrimitiveClass("char");
常量值是 char 类型的最小值,即 '\u0000' public static final char MIN_VALUE = '\u0000';
常量值是 char 类型的最大值,即 '\uFFFF' public static final char MAX_VALUE = '\uFFFF'
Unicode代码点的最小值 public static final int MIN_CODE_POINT = 0x000000;
Unicode代码点的最大值 public static final int MAX_CODE_POINT = 0X10FFFF;
UTF-16 编码中的 Unicode 高代理项代码单元的最小值 public static final char MIN_HIGH_SURROGATE = '\uD800';
UTF-16 编码中的 Unicode 高代理项代码单元的最大值 public static final char MAX_HIGH_SURROGATE = '\uDBFF';
UTF-16 编码中的 Unicode 低代理项代码单元的最小值 public static final char MIN_LOW_SURROGATE  = '\uDC00'
UTF-16 编码中的 Unicode 低代理项代码单元的最大值 public static final char MAX_LOW_SURROGATE  = '\uDFFF'
代理项的最小值
也就是高代理项的最小值
public static final char MIN_SURROGATE = MIN_HIGH_SURROGATE;
代理项的最大值
也就是低代理项的最大值
public static final char MAX_SURROGATE = MAX_LOW_SURROGATE;
增补代码点的最小值
也就是除了0号平面的第一个值
public static final int MIN_SUPPLEMENTARY_CODE_POINT = 0x010000
可用于与字符串相互转换的最大基数 public static final int MAX_RADIX = 36;
可用于与字符串相互转换的最小基数 public static final int MIN_RADIX = 2
可以看得出来,即使去掉了那些通用类别的常量,剩下的信息仍旧是对Unicode编码的描述
只要看过了前文的Unicode的简介,很好理解

构造方法

Character(char) 只有一种形式的构造方法
直接设置value的值

常用方法

比较

compare(char, char)
看起来可能会有人觉得奇怪,怎么还能直接减法?
其实char不就是一个UTF-16的代码单元么,他不就是一个十六进制数么
如下图所示,0x0058 - 0x002B 得到的值的十进制就是45

比较的也就是前后顺序了
compareTo(Character) 实例方法
借助于静态方法

valueOf    

系列 包装 基本类型 为 对象
valueOf系列一直都是将基本类型包装为对象类型,此处也是如此
Character也是有缓存的

XXXValue 

获取 基本类型值
charValue() 直接返回基本类型数据

toString

借助于String.valueOf方法包装转换

equals

重写了equals方法,比较的是实际的对象中的value值

hashcode

直接返回value的int值

  

reverseBytes

public static char reverseBytes(char ch)
character也有翻转字节转换的方法
再剩下就是Unicode更加强相关的方法了,简单介绍下

getType

获取字符在Unicode中的属性类别信息
再次强调,一个char只是一个代码单元,本质是16位   所以参数类型为char时,显然不能支持辅助平面内的字符
显然,int的范围完全足够,可以支持BMP和辅助平面
获取到的属性信息在不少针对于Unicode的处理中,将会很有用
比如

toChars

将指定的代码点,保存到char数组
一个是保存到指定数组,一个是创建一个新的数组
public static
int toChars(int codePoint, char[] dst, int dstIndex)
保存到指定的数组的指定位置
如果0号平面内   dst[dstIndex] 中存储相同的值,并返回 1
如果辅助平面   dst[dstIndex]高代理 dst[dstIndex+1]低代理返回2
public static
char[] toChars(int codePoint)
返回一个char数组保存指定代码点

codePointCount

返回代码点的数量,两种形式
codePointCount(CharSequence, int, int)
codePointCount(char[], int, int)
时刻记住,char是代码单元,一个代码点可能一个或者两个代码单元

offsetByCodePoints

计算偏移指定个个数的代码点后的索引
还是那句话,char是代码单元,一个代码点可能一个或者两个代码单元
如果一个代码点一个代码单元,偏移多少个,那么下标索引就是往后移动多少个了
可惜,一个代码点可能一个也可能两个代码单元
所以才有了这个方法
以第一个方法为例
就是说,给你一个数组,  然后又给了你start 和count,在这个子数组的范围内
从index这个下标开始(显然index应该位于start和start+count之间的,否则越界异常)
往后数codePointOffset 个代码点,然后看看到底下标序号是多少,返回给调用者
返回的值可能就是index+codePointOffset  也可能大于index+codePointOffset
public static int offsetByCodePoints(char[] a,
                                     int start,
                                     int count,
                                     int index,
                                     int codePointOffset)
public static int offsetByCodePoints(CharSequence seq,
                                     int index,
                                     int codePointOffset)

codePointAt

获取指定位置的代码点
基本逻辑,如果第一个代码单元的值在高代理区,下一个索引还小于数组的长度,并且下一个索引的地方是低代理区,那么返回这个代码点
否则,就是单纯的返回这个代码单元
说白了就是我能力范围内就给你,否则就给你我有的那一半 第三个limit是范围,其他的范围默认就是数组内

public static int codePointAt(char[] a, int index)
public static int codePointAt(CharSequence seq, int index)
public static int codePointAt(char[] a, int index, int limit )
看下下面这个例子,0x1f310上面也看到了,使用两个代码单元
chars保存了他的两个代码单元
chars1 只有一个元素,那就是0x1f310 的高代理位

codePointBefore

codePointBefore  和 codePointAt几乎是一回事情,只不过是指定位置的前面
如果指定位置前面一个 index-1 处是一个低代理,而且更前面的一个index-2 是一个数组内的有效数据
那么,就返回代码点
否则就返回一个单元
start相当于限定了数组的范围,本来index-2>=0 就好了 现在index-2需要 >=start了
public static int codePointBefore(CharSequence seq,int index)
public static int codePointBefore(char[] a, int index)
public static int codePointBefore(char[] a, int index,  int start )

charCount

public static int charCount(int codePoint)
确定表示指定字符(Unicode 代码点)所需的 char 值的数量。如果指定字符等于或大于 0x10000,则该方法返回的值为 2。否则,该方法返回的值为 1
从代码可以看得出来,他就是直接查看代码点的值简单的计算
并没有确认是否是有效字符

toLowerCase  / toUpperCase /toTitleCase

都是使用取自 UnicodeData 文件的大小写映射信息将字符(Unicode 代码点)进行参数转换
lowCase就是转换为小写
UpperCase就是转换为大写
TitleCase就是首字母大写
又是两个版本的参数,一个char 一个int 还是老样子,char不支持辅助平面

toLowerCase(char)
toLowerCase(int)
toUpperCase(char)
toUpperCase(int)
toTitleCase(char)
toTitleCase(int)

代码点获取

public static char highSurrogate(int codePoint) 返回代码点的高代理
如果不是辅助平面的字符,返回未知char
public static char lowSurrogate(int codePoint) 返回代码点的低代理
如果不是辅助平面的字符,返回未知char

代理位信息判断

public static boolean isSurrogate(char ch) 是否代理部分
public static boolean isSurrogatePair(char high, char low) 是否是代理对
public static boolean isHighSurrogate(char ch) 是否是高代理
public static boolean isLowSurrogate(char ch) 是否是低代理

代码点信息的校验

public static boolean isValidCodePoint(int codePoint)  是否是合法的代码点
确定指定的代码点是否为从 0x0000 到 0x10FFFF 范围之内的有效 Unicode 代码点值
public static boolean isBmpCodePoint(int codePoint) 是否位于0号平面,是的话就可以使用一个char表示了
public static boolean isSupplementaryCodePoint(int codePoint) 是否位于辅助平面 辅助平面必然需要使用两个char

toCodePoint(char, char)

public static int toCodePoint(char high,char low)
将指定的代理项对转换为其增补代码点值。该方法没有验证指定的代理项对
如有必要,调用者必须使用 isSurrogatePair 验证它
就是高代理 低代理的合并

isXXX   系列

isXXX系列就是校验XXX的信息是否为真
大多两个版本,一个是char 一个是int
还是老样子,char仅仅支持0号平面
小写?
isLowerCase(char)
isLowerCase(int)
大写?
isUpperCase(char)
isUpperCase(int)
首字母大写?
isTitleCase(char)
isTitleCase(int)
数字?
isDigit(char)
isDigit(int)
被定义为 Unicode 中的字符?
isDefined(char)
isDefined(int)
字母?
isLetter(char)
isLetter(int)
字母或数字?
isLetterOrDigit(char)
isLetterOrDigit(int)
是否能够作为 Java 标识符中的首字符?
isJavaIdentifierStart(char)
isJavaIdentifierStart(int)
是否能够作为 Java 标识符中的首字符以外的字符?
isJavaIdentifierPart(char)
isJavaIdentifierPart(int)
是否允许作为 Unicode 标识符中的首字符?
isUnicodeIdentifierStart(char)
isUnicodeIdentifierStart(int)
是否允许作为 Unicode 标识符中的首字符以外的字符?
isUnicodeIdentifierPart(char)
isUnicodeIdentifierPart(int)
是否是 Java 标识符或 Unicode 标识符中可忽略的一个字符?
isIdentifierIgnorable(char)
isIdentifierIgnorable(int)
空白字符?
isSpaceChar(char)
isSpaceChar(int)
Java 标准是否为空白字符?
isWhitespace(char)
isWhitespace(int)
ISO 控制字符?
isISOControl(char)
isISOControl(int)
字母?
isAlphabetic(int)   
中日越韩文字?
isIdeographic(int)
依据 Unicode 规范是否对称?

isMirrored(char)
isMirrored(int)
isAlphabetic 和 isLetter 类似,  但是类型范围有差别
isAlphabetic范围更大
UPPERCASE_LETTER   LOWERCASE_LETTER   TITLECASE_LETTER   MODIFIER_LETTER   OTHER_LETTER  LETTER_NUMBER   
UPPERCASE_LETTER   LOWERCASE_LETTER   TITLECASE_LETTER   MODIFIER_LETTER   OTHER_LETTER   

返回使用指定基数的   字符 ch/Unicode 代码点 的数值
public static int digit(char ch, int radix)
public static int digit(int codePoint, int radix)
确定使用指定基数的特定数字的字符表示形式 public static char forDigit(int digit, int radix)
返回给定字符的 Unicode 方向属性
public static byte getDirectionality(char ch)
public static byte getDirectionality(int codePoint)
返回指定的 Unicode 字符/Unicode 代码点 表示的int值
public static int getNumericValue(char ch)
public static int getNumericValue(int codePoint)
返回指定字符codePoint的Unicode名称,如果代码点未被分配,则返回null public static String getName(int codePoint)
感受下getName

总结

Java中的char 也就是Character中包装的数据
他们是UTF-16中的代码单元
一个Unicode字符集的数值叫做一个代码点
所以一个字符可能是一个char也可能是两个char
所以,除非真的有必要,希望对UTF16的代码单元进行处理,不要使用char类型,使用其他的高级类型比如String
char就是Unicode UTF-16在程序中的应用
想要理解char就必须理解Unicode和UTF16
Character中的定义的变量以及方法,大多都是和他们息息相关的

[十一]基础数据类型之Character相关推荐

  1. Java 基础数据类型

    Java 提供的基础数据类型(也称内置数据类型)包含:整数类型.浮点类型.字符类型.布尔类型. 整数类型 整数类型变量用来表示整数的数据类型.整数类型又分为字节型(byte).短整型(short).整 ...

  2. 第 1-2 课:你不知道的基础数据类型和包装类 + 面试题

    基本数据类型 Java 基础数据按类型可以分为四大类:布尔型.整数型.浮点型.字符型,这四大类包含 8 种基础数据类型. 布尔型:boolean 整数型:byte.short.int.long 浮点型 ...

  3. python容量变化类型有哪些_python基础数据类型补充以及编码的进阶

    一. 基础数据类型补充内容 1.1 字符串 字符串咱们之前已经讲了一些非常重要的方法,剩下还有一些方法虽然不是那么重要,但是也算是比较常用,在此给大家在补充一些,需要大家尽量记住. #captaliz ...

  4. java基础数据类型包装类

    基础数据类型包装类 当一个程序要求交互式输入一个int类型的年龄时,从文本框中输入的结果肯定是String类型的.要在程序中进行相关操作,它必须先转换为int类型.因此可以使用数据类型的转换或强制转换 ...

  5. 袁老师Py西游攻关之基础数据类型

    Py西游攻关之基础数据类型 数据类型 计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值.但是,计算机能处理的远不止数值,还可以处理文本.图形.音频.视频.网页等各种各 ...

  6. 初识mysql数据字段属性_MySQL数据库~~~~初识、基础数据类型

    一 数据库初识 1.1 什么是数据库 数据库(DataBase,简称DB),简而言之可视为电子化的文件柜----存储电子文件的处所,用户可以对文件中的数据运行新增,截取,更新,删除等操作. 所谓数据库 ...

  7. 基础数据类型之集合和深浅copy,还有一些数据类型补充

    集合 集合是无序的,不重复的数据集合,它里面的元素是可哈希的(不可变类型),但是集合本身是不可哈希(所以集合做不了字典的键)的.以下是集合最重要的两点: 去重,把一个列表变成集合,就自动去重了. 关系 ...

  8. Python 基础三:基础数据类型和字符串的常用函数操作

    基础数据类型 数字int 数字主要用于计算,有加减乘除等操作,下面介绍一种使用方法 #bit_length(),将十进制数转换成二进制数的二进制数位数 v = 9 data = v.bit_lengt ...

  9. js基础--数据类型检测的相关知识

    欢迎访问我的个人博客:www.xiaolongwu.cn 前言 最近工作有点忙,好几天都没更新技术博客了. 周末起床打开有道云笔记,发现自己的博客todolist里躺了一堆只有名字的文件. 话不多说, ...

最新文章

  1. MindSpore技术理解(上)
  2. android socket_盘点Android常用Hook技术
  3. PostgreSQL在何处处理 sql查询之六十六
  4. java里 currenttime_java 获取当前时间LocalDateTime currentTimeMillis java.util.Date
  5. 纯CSS3画出小黄人并实现动画效果
  6. sql两个数字之差取最接近的_从零学DAX/Sql/Python030203SQL数据分类汇总续篇
  7. Node.js + Express + handlebars搭建个人网站(1)
  8. 一个实际的例子学习 SAP BTP Java 应用的 @Before 注解使用方式
  9. oracle中execute函数,oracle Execute Immediate(sql语句)
  10. Spring-jdbc:JdbcTemplate使用简介
  11. Sublime Text 3 快捷键总结(详细版本)
  12. 辽源a货翡翠,张掖a货翡翠
  13. 关于决策树,你一定要知道的知识点!
  14. word分页保存_搞定office丨Word快捷技巧第3弹!
  15. [BZOJ5286][HNOI2018]转盘(线段树)
  16. 有人把李白杜甫一生的旅行足迹做了地图,发现了大事!
  17. 免费建立一个自己的网站
  18. BUAA_4:Kevin·Feng的正确@姿势
  19. 201871010132——张潇潇《面向对象程序设计JAVA》第二周学习总结
  20. Google SEO 搜索中心

热门文章

  1. 如何为机器视觉系统选择合适的图像采集卡
  2. linux运维人员必会运维工具
  3. 点击头像单独把图片拉取出来.然后再次点击回到初始效果
  4. 集合视图UICollectionView 介绍及其示例程序
  5. 验证组播的TTL阀值
  6. 如何编写数据库存储过程?
  7. Malformed server response 解决方案
  8. Fresco源码分析之Hierarchy
  9. 测试mktime和localtime_r性能及优化方法
  10. linux下的sort、uniq、join的使用