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 基础 基础数据类型与包装器类型 基础数据类型 java 中包含哪些基础数据类型,默认值分别是多少? 基础数据类型 byte short int long double float char ...

  2. 【Swift】学习笔记(一)——熟知 基础数据类型,编码风格,元组,主张

    自从苹果宣布swift之后,我一直想了解,他一直没有能够把它的正式学习,从今天开始,我会用我的博客来驱动swift得知,据我们了解还快. 1.定义变量和常量 var  定义变量,let定义常量. 比如 ...

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

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...

  4. day2(基础数据类型)

    一.基础数据类型操作 1.数字 int 数字主要是用于计算用的,使用方法并不是很多,就记住一种就可以: int.bit_length() -> int Number of bits necess ...

  5. c# CTS 基础数据类型笔记

    C#中的基础数据类型并没有内置于c#语言中,而内置于.net freamework. C#有15个预定义类型,其中13个是值类型,两个是引用类型(string和object) 一.值类型 值类型 数据 ...

  6. Python中的基础数据类型

    Python中基础数据类型 1.数字 整型a=12或者a=int(2),本质上各种数据类型都可看成是类,声明一个变量时候则是在实例化一个类. 整型具备的功能: class int(object): & ...

  7. day01——python初始、变量、常量、注释、基础数据类型、输入、if

    python的历史: 04年Django框架诞生了 内存回收机制是什么(面试题) python2:源码不统一,有重复的功能代码 python3:没有重复的功能代码 python是一个什么的编程语言 编 ...

  8. Java 基础数据类型

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

  9. PostgreSQL的基础数据类型分析记录-转

    src:http://www.codeweblog.com/postgresql%E7%9A%84%E5%9F%BA%E7%A1%80%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E ...

随机推荐

  1. Markdown常用快捷键

    Markdown使用的符号:井号,星号,大于号,中括号,竖线,横杠,波浪线,反引号 # ,*, > ,[],|,-,~,` 井号 + 空格:根据空格的个数显示各标题的大小 标题一 标题二 标题三 ...

  2. vs2012开发基于MFC的ActiveX控件

    1.新建工程 2.一直点击下一步,直到出现一下界面,注意红色标注选项,点击完成. 3.进入工程的属性界面,设置工程属性 4.添加对话框资源及其他控件,添加对话框类, 5.设置对话框属性 6.设置Dia ...

  3. tomcat安装启动startup.bat文件命令行界面出现乱码的问题解决

    进入tomcat安装界面,进入conf文件夹,找打logging.properties,打开进行编辑,在最后添加一句 java.util.logging.ConsoleHandler.encoding ...

  4. 小甲鱼Python3笔记

    000-愉快的开始 入门容易,学习难,代码量少. 跨平台: Windows, Mac OS, Linux, UNIX. 应用领域: 操作系统 WEB 3D动画 企业应用 云计算等等. 001-我和Py ...

  5. Java精确测量代码运行时间

    Java精确测量代码运行时间: --------------- long startTime = System.nanoTime(); //開始時間 for(int i = 0;i<10000; ...

  6. Dora.Interception,为.NET Core度身打造的AOP框架 [4]:与依赖注入框架的无缝集成

    Dora.Interception最初的定位就是专门针对.NET Core的AOP框架,所以在整个迭代过程中我大部分是在做减法.对于.NET Core程序开发来说,依赖注入已经成为无处不在并且“深入骨 ...

  7. [Swift]LeetCode949. 给定数字能组成的最大时间 | Largest Time for Given Digits

    Given an array of 4 digits, return the largest 24 hour time that can be made. The smallest 24 hour t ...

  8. [Swift]LeetCode1025. 除数博弈 | Divisor Game

    Alice and Bob take turns playing a game, with Alice starting first. Initially, there is a number N o ...

  9. Android device debug (adb) by Charge Only mode

    Android device debug by Charge Only mode Method 1 Connect devices to computer and execute lsusb Find ...

  10. android自动化必备之SDK

    进入到SDK包中,通过打开SDK manager.exe即可看到SDK管理界面,可能部分童靴发现一直在加载出不来,我们需要设置代理来解决: 选择工具栏上的Tools->Options打开如下窗口 ...