字符串原理
扩展底层原理1:字符串存储的内存原理
- 直接赋值会复用字符串常量池中的
- new出来不会复用,而是开辟一个新空间
扩展底层原理2:==号比较的到底是什么?
- 基本数据类型比较数据值
- 引用数据类型比较地址值
扩展底层原理3:字符串拼接的底层原理
- 如果没有变量参与,都是字符串直接相加,编译之后就是拼接之后的结果,会复用串池中的字符串。
- 如果有变量参与,每一行拼接的代码,都会在内存中创建新的字符串,浪费内存。
public class Text{ public static void main(String[] args){ String s ="a"+"b"+"c"; System.out.printIn(s); } } 结果:"abc" | 拼接的时候没有变量,都是 字符串。 触发字符串的优化机制。 在编译的时候就已经时最终 的结果了。 |
public class Text{ public static void main(String[] args){ String s1 ="a"; String s2 = s1+"b"; String s3 = s2+"c"; System.out.printIn(s3); } } | 一个加号,堆内存中俩对象 |
字符串拼接的时候有变量参与:在内存中创建了很多对象,浪费空间,时间也非常慢
结论:如果很多字符串变量拼接,不要直接+。在底层会创建多个对象,浪费时间,浪费性能。
扩展底层原理4:StringBuilder提高效率原理图
- 所有要拼接的内容都会往StringBuilder中放,不会创建很多无用的空间,节约内存。
public class Text{ public static void main(String[] args){ String s1 ="abc";//记录串池的地址值 String s2 = "ab"; String s3 = s2+"c";//新new出来的对象 System.out.printIn(s1==s3);//false } } |
public class Text{ public static void main(String[] args){ String s1 = "abc";//记录串池中的地址值 String s2 ="a"+"b"+"c";//复用串池中的字符串 System.out.printIn(s1==s2);//true } } 在编译时,就会将"a"+"b"+"c"拼接为"abc" |
扩展底层原理5:StringBuilder源码分析
- 默认创建一个长度为16的字节数组
- 添加的内容长度小于16,直接存
- 添加的内容大于16会扩容(原来的容量*2+2)
- 如果扩容之后还不够,以实际长度为准
默认容量:16——最多放多少;长度是实际上已经放了多少。
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
添加a~z:16不够,——扩容:老容量*2+2=34
添加a~z和0~9——扩容:如果超出*2+2的容量则以实际容量为准=36
练习一——转换罗马数字
需求:键盘录入一个字符串,
要求1:长度为小于等于9
要求2:只能是数字。
将内容变成罗马数字,下面是阿拉伯数字跟罗马数字的对比关系:
Ⅰ-1、Ⅱ-2、Ⅲ-3、Ⅳ-4、Ⅴ-5、Ⅵ-6、Ⅶ-7、Ⅷ-8、Ⅸ-9
注意点:罗马数字里面是没有0的,如果键盘录入的数字包含0,可以变成 " "(长度为0的字符串)
练习二——调整字符串
给定两个字符串,A和B。
A的旋转操作是将A最左边的字符移动到最右边。
例如,若A='abcde',在移动一次之后结果是'badea'。
如果在若干次调整之后,A能变成B,那么返回True.
如果不能匹配成功,则返回false
法一
结果:
法二
结果同上