文章目录
- 字符串
- 一.String概述
- 二.创建String对象的两种方式
- 三.Java的内存模型
- 四.字符串的比较
- 五.StringBuilder的基本操做
- 六.StringJoiner概述
- 七.字符串相关类的底层原理
字符串
一.String概述
1.String是Java定义好的一个类,定义在java.long
包中,所以使用的时候不需要导包
2.Java程序中的所有字符串文字(例如"abc")都被是为此类的对象
3.字符串的内容不可变
,它的对象在创建后,不能被更改
4.字符串和任意类型相加得到的结果都是字符串
例如:“abc” + true = “abctrue”
5.常见的对字符串的处理有:
比较,替换,截取,查找,切割,检索,加密,打乱内容,大小写转换
二.创建String对象的两种方式
1.直接赋值
String name = “123”;
2.new
String str = new String();
String str = new String("abc");
//传递一个字符数组,根据字符数组的内容再创建一个新的字符串对象
//需求:修改字符串的内容(注意:字符串内容不可变) abc ---> Qbc
//abc-->{'a','b','c'}-->{'Q','b'.'c'}-->Qbc
char[] chs = {'a','b','c'};
String str = new String(chs);
byte[] bytes = {97,98,99,100};
String str = new String(bytes);
System.out.println(str);//abcd
//这里并不是把数字进行拼接,而是通过数字到ASCII码表里去查对应的字母,然后把字母进行拼接
三.Java的内存模型
字符串常量池
只有通过赋值
的方式创建的字符串对象才在串池
中
从jdk1.7开始串池由方法区转到了堆内存中
当使用字符串直接赋值
时,系统会检查
该字符串在串池
中是否存在
存在:复用
不存在:创建新的
所以,采用直接赋值的方式
创建String对象的好处一个是代码简单
,一个是节约内存
四.字符串的比较
==号比较(对字符串来说,比较的是地址值)
比较基本数据类型,比较的是数据值
比较引用数据类型,比较的是地址值
对字符串来说比较的是内容
注意:
1.equals()方法,不能
比较基本数据类型
只能
比较引用数据类型,
默认比较的是地址值
如果想要比较内容
,需要对equals()方法进行重写
这里,对字符串来说比较的是内容,原因在于,String类已经对equals()方法重写好了
2.键盘录入的字符串,sc.next();—>是new 出来的
String中常用方法:
五.StringBuilder的基本操做
StringBuilder可以看成是一个容器
,创建之后里面的内容是可变的
作用:提高字符串的操做效率
过去使用String类型进行字符串拼接,就会不断的产生新的内容
比如:
比如,s1和s2拼接后产生"aaabbb",然后再拿"aaabbb"再和s3进行拼接依次类推,这样的话,会产生一些无用的字符串,占用内存
所以这并不是我们想要的
所以,我们可以采用StringBuilder
达到我们想要的效果,如下
StringBuilder构造方法:
StringBuilder常用方法:
因为StringBuilder是Java已经写好的类,Java在底层对它做了一些特殊处理,打印对象不是地址值而是属性值
六.StringJoiner概述
1.StringJoiner和StringBuilder一样,也可以看成是一个容器
,创建之后里面的内容是可变的
2.作用:提高字符串的操做效率,而且代码编写特别简洁,但目前很少有人用
3.JDK8出现的
StringJoiner构造方法:
StringJoiner成员方法:
总结:
1.String
表示字符串的类,定义了很多操做字符串的方法
2.StringBuilder
一个可变的操做字符串的容器
可以高效的拼接
字符串,还可以将容器里的内容反转
3.StringJoiner
JDK8出现的一个可变的操做字符串的容器,可以高效,方便的操做字符串,在拼接的时候可以指定间隔符,开始符号,结束符号
七.字符串相关类的底层原理
扩展底层原理1:字符串存储的内存原理
1.直接赋值会复用字符串常量池里面的
2.new出来的不会复用,而是开辟一个新的空间
扩展底层原理2:==比较的是什么
1.基本数据类型:比较数据值
2.引用数据类型:比较地址值
但是,无论比较字符串还是其他引用数据类型都不用==,而是用equals()方法
扩展底层原理3:字符串拼接的底层原理
1.等号右边没有变量
触发字符串的优化机制,在编译的时候已经是最终结果了
等同于 String s = “abc”;
2.等号右边有变量
在JDK8以前都是在堆内存中创建一个StringBuilder容器,然后将变量和字符串进行拼接,然后调用toString()方法转为String对象
一个"+"号,堆内存中有两个对象
JDK8字符串拼接的底层原理
先去预估最终字符串的长度,并创建一个数组,数组里存放最终字符串的元素,最终把数组转为字符串
但是这里的预估也是需要时间的,比如有多行变量都需要进行拼接
则每一行都需要进行预估,然后创建数组,创建字符串对象
所以得出结论:如果有多个字符串变量进行拼接,不要直接"+",因为在底层会创建很多的对象,浪费时间,降低性能
所以使用StringBuilder-append()/StringJoiner-add()
扩展底层原理4:StringBuilder提高效率原理图
所有要拼接的内容都会往StringBuilder中放,不会创建很多无用的空间,节约内存
StringBuilder的容量是有上限的
扩展底层原理5:StringBuilder源码分析
StringBuilder在刚开始创建的时候,底层会创建一个字节数组
默认容量:16
长度:实际装了多少
容量:最多能装多少
添加"abc",实际存储的是他们的ASCII码值
如果添加的数据长度超过16,则扩容
扩容:老容量 * 2 + 2
如果添加的数据超过老容量 * 2 + 2,则以实际数据长度为准