JAVA的String的实现
2019独角兽企业重金招聘Python工程师标准>>>
一。Unicode和UTF-16
要说String必然跑不掉Unicode。简单说Unicode是一种字符集,说白了就是每个字符分配了一个数字与之对应。其范围是U+0000到U+10FFFF。
再来说两个概念叫代码点(Code Point)和代码单元(Code Unit)。
代码点:指的就是Unicode的中每个字符对应的数值,范围在U+0000到U+10FFFF之间。
代码单元:就是用来表示unicode的数值时采用的编码的最小单位,UTF-8就是8位即一个字节,UTF-16就是2个字节,UTF-32就是4个字节。
UTF-8的代码单元是一个字节,要存储Unicode就必须采用一定编码方式即
000000 - 00007F | 0zzzzzzz(00-7F) | 1个字节 |
000080 - 0007FF | 110yyyyy(C0-DF) 10zzzzzz(80-BF) | 2个字节 |
000800 - 00FFFF | 1110xxxx(E0-EF) 10yyyyyy 10zzzzzz | 3个字节 |
010000 - 10FFFF | 11110www(F0-F7) 10xxxxxx 10yyyyyy 10zzzzzz | 4个字节 |
UTF-16的代码单元是两个字节,编码方式
000000 - 00FFFF | xxxxxxxx xxxxxxxx yyyyyyyy yyyyyyyy | 2个字节 |
010000 - 10FFFF | 110110yyyyyyyyyy 110111xxxxxxxxxx | 4个字节 |
二。String内部的实现。
String中实际数据的存储就是Unicode的UTF-16的编码形式。所以代码单元是2个字节,这也符合char的大小。现在有个很明显的问题就是Unicode的范围是U+0000到U+10FFFF,而一个char没法表示U+10000到U+10FFFF之前的数值,为了解决这个问题就采用了上面介绍的两个char来组合表示这个范围的值。
分拆的规则是10000到10FFFF,按照最大值算一共占了20位,高10位的值加上0xD800后存在一个char中,低10位的值加上0xDC00存在一个char中,这样两个char组合起来表示一个超过10000的unicode编码值。即 U+0000到U+FFFF用一个char表示,这部分叫基本多语言平面(BMP Basic Multilingual Plane)。ps:绕口得绕死了。U+10000到U+10FFFF用两个char表示,这部分叫辅助平面(Supplementary Planes)。
看似上面解释的很好,其实还有一个问题。当遇到一个2个char组成的Unicode编码时,怎么知道何时解析成一个,何时解析成两个单独的Unicode编码。其实就是说 如果存在一个char的和两个char在表示的时候 如果存在重复前缀的时候该怎么区分出来?例如如果一个char值是 '\uD869',两个char的是'\uD869'和'\uDEA5',就会出现无法唯一解析的问题,是把'\uD869'和'\uDEA5'当成两个单独的unicode来解析呢?还是当成一个整体的unicode来解析呢?其实这个问题unicode在制定编码的时候就考虑了,解决方案就是Unicode标准规定U+D800到U+DFFF的值不对应于任何字符。这样只要遇到在U+D800和U+DFFF之间的char,就知道下一个char跟这个是一体的,不能分别拆开解析,必须两个char一起解析。
知道上面这些后其实对于String的底层存储就比较容易理解了。String内部是定义了几个主要的基本数据类型。
private final char value[]; //存储unicode值,不过是以UTF-16编码的方式存储。
private final int offset; //对于第一个字符与数组的偏移量。
private final int count; //String中代码点的个数。
private int hash; //缓存Hash值
转载于:https://my.oschina.net/u/944165/blog/220758
JAVA的String的实现相关推荐
- Java / Android String.format 的使用
String类的format()方法用于创建格式化的字符串以及连接多个字符串对象. 自己使用的地方1 拼接字符串 2 ,多语言文字顺序不同问题,例如中文:距离到公司还有30分钟, 时间是接口获取的, ...
- java.lang.NullPointerException: Attempt to invoke virtual method ‘boolean java.lang.String.equals(j
今天切正式环境出现的空指针 记录一下 下面是错误 java.lang.NullPointerException: Attempt to invoke virtual method 'boolean j ...
- java string改变的影响_为什么Java的string类要设成immutable(不可变的)
最流行的Java面试题之一就是:什么是不可变对象(immutable object),不可变对象有什么好处,在什么情况下应该用,或者更具体一些,Java的String类为什么要设成immutable类 ...
- Android java传递string类型数据给C
本文接着实现<Android java传递int类型数据给C>的还未实现的方法: public native String sayHelloInC(String s); 先贴一个工具方法, ...
- Java 之String、StringBuffer 和 StringBuilder 三者区别介绍
String:字符串常量,字符串长度不可变,StringBuffer:字符串变量(Synchronized,即线程安全),StringBuilder:字符串变量(非线程安全). String Stri ...
- 2.Java中String,StringBuilder以及StringBuffer的关系与区别
String StringBuffer StringBuilder String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且浪费大量 ...
- java中String new和直接赋值的区别
Java中String new和直接赋值的区别 对于字符串:其对象的引用都是存储在栈中的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期(new出来的)才 ...
- java中String的常用方法
java中String的常用方法 1.length() 字符串的长度 例:char chars[]={'a','b'.'c'}; String s=new String(chars); int len ...
- java中String,int,Integer,char、double类型转换
java中String,int,Integer,char.double类型转换----https://www.cnblogs.com/kangyu222/p/5866025.html 转载于:http ...
- JDK1.8源码(三)——java.lang.String 类
String 类也是java.lang 包下的一个类,算是日常编码中最常用的一个类了,那么本篇博客就来详细的介绍 String 类. 1.String 类的定义 public final class ...
最新文章
- Ansible02-实施playbook
- C#和.Ne学习第五天
- CI框架下nginx重写规则
- Objective-c官方文档 怎么自定义类
- 即时通信软件开发的年轻开发者曾注意到
- python3-曲线拟合(polyfit/polyval)
- Delphi XE8 TStyleBook的使用
- EXCEL-数据透视表、日数据整理成月数据
- 自定义拍照时 拍照界面_拍照时图片比例怎么选?比构图还要提前一步的摄影攻略要做好...
- 观察 :人工智能与伦理道德
- 如何搭建一个属于自己的网站
- 六一小学生计算机创新活动总结,小学科技创新活动总结4篇
- houdini 节点批量改名
- IDM下载器免费高质量的Win下载工具无使用限制
- python写几个好玩的程序_怎么用python编写好玩的程序
- 1035 插入与归并(C++)
- 黑莓安全丑闻:加拿大警方2010年就能随意解密用户信息
- c0000218 Unknown Hard Error的解决
- 迭代法的收敛条件及收敛阶
- 2021年安全员-B证及安全员-B证模拟试题