Java基础学习笔记(七)—— java中的字符串池与可变字符串

Java基础学习笔记(七)—— java中的可变字符串与字符串池

Life was like a box of chocolates, you never know what you’re gonna get.

| @Author:TTODS


Java中的字符串池(String Pool)

我们在获得字符串对象的时候,有两种方法:
①、使用字符串常量赋值的方法
②、创建对象的通用方法,即new一个对象

String str = "Hello, World!"; //方法①
String str1 = new String("Hello, World!"); //方法②

那么这两种方法创建的字符串有区别吗?且看下一段代码

String s7 = new String("Hello");
String s8 = new String("Hello");
String s9 = "Hello";
String s10 ="Hello";

System.out.println("s7==s8:"+(s7==s8));
System.out.println("s9==s10:"+(s9==s10));
System.out.println("s7==s9:"+(s7==s9));
System.out.println("s7==s10:"+(s7==s10));
s7==s8:false
s9==s10:true
s7==s9:false
s7==s10:false

通过上例可以看出在使用==对上面四个字符串对象进行比较时,只有s9与s10比较时,结果时true,其他比较结果都是false,前面已经说过了在使用==对引用数据类型 进行比较时,实际比较的是其在内存中的首地址,即判断比较的两个数据是否为同一对象,也就是说上面的s9与s10其实是一个对象。
这是为什么?Java中的不可变字符串String常量,采用字符串池(String Pool)管理技术,字符串池是一种字符串驻留技术。采用字符串常量赋值时(方法①),会在字符串池中查找"Hello"字符串常量,如果已经存在把引用赋值给s9,否则创建"Hello"字符串对象,并放到池中。根据此原理,可以推定s10与s9是相同的引用,指向同一个对象。但此原理并不适用于new所创建的字符串对象,在使用new创建字符串对象时,会创建"Hello"字符串对象,而它并没有放到字符串池中。也就是说上例中的s7和s8是两个不同的引用,指向不同的对象。
在这里插入图片描述

上例与本图来自源于《java从小白到大牛》

java中的可变字符串 StringBuffer与StringBuilder

StringBuffer和StringBuilder都是java中的可变字符串,中文翻译为"字符缓冲区",它们完全相同的API,唯一的区别就是StringBuffer是线程安全的,StringBuilder不是线程安全的,但它的执行效率很高。

构造方法
StringBuilder()

构造一个没有字符的字符串构建器,初始容量为16个字符。

StringBuilder sbuilder = new StringBuilder();
System.out.println(sbuilder.capacity());//输出16
StringBuilder(CharSequence seq)
StringBuilder sbuilder = new StringBuilder("Hello, World!");
System.out.println(sbuilder);//输出Hello, World
StringBuilder(int capacity)
StringBuilder sbuilder = new StringBuilder(32);
System.out.println(sbuilder.capacity());//输出32
StringBuilder(String str)
String str = "Hello, World!";
StringBuilder sbuilder = new StringBuilder(str);
System.out.println(sbuilder);//输出Hello, World
常用方法(一些与String相同的方法参考上篇笔记 )

关于下面的方法的更多重构方法请参考官方文档

append

将一个字符串(也可将其他类型转化成字符串类型)拼接到此字符串的尾部

StringBuilder sbuilder  = new StringBuilder("Hello, World!");
sbuilder.append(" Hello, TTODS.");
System.out.println(sbuilder);//输出Hello, World! Hello, TTODS.
capacity

返回当前容量。 容量是新插入字符可用的存储量,超过此值将进行分配。

delete(int start, int end)

删除指定索引区间[start,end)的字符,如果start为负数或者start大于end,会报错StringIndexOutOfBoundsException

StringBuilder sbuilder  = new StringBuilder("0123456789");
sbuilder.delete(0,4);
System.out.println(sbuilder);//输出456789
deleteCharAt

删除指定索引处的字符

StringBuilder sbuilder  = new StringBuilder("0123456789");
sbuilder.deleteCharAt(4);
System.out.println(sbuilder);//012356789
replace(int start,int end,String str)

用字符串str替换原字符串中指定的内容

StringBuilder sbuilder  = new StringBuilder("0123456789");
String str ="-----";
sbuilder.replace(1, 3, str);
System.out.println(sbuilder); // 输出 0-----3456789
insert(int index,char[] str,int offset,int len)

在指定位置插入字符数组中指定的内容

StringBuilder sbuilder  = new StringBuilder("0123456789");
char[] chs = {'1','2','3','4','5','6'};
sbuilder.insert(10,chs,0,6);
System.out.println(sbuilder);//输出 0123456789123456
reverse

反转字符串

StringBuilder sbuilder  = new StringBuilder("0123456789");
System.out.println(sbuilder);// 输出 0123456789
sbuilder.reverse();
System.out.println(sbuilder);// 输出 9876543210
setCharAt
StringBuilder sbuilder  = new StringBuilder("0123456789");
sbuilder.setCharAt(4, '6');
System.out.println(sbuilder);//输出 0123656789
setLength

设置字符串的长度,参数为设定的新长度,当新长度为负数时,会报错IndexOutOfBoundsException

StringBuilder sbuilder  = new StringBuilder("0123456789");
StringBuilder sbuilder1  = new StringBuilder("0123456789");
sbuilder.setLength(5);
System.out.println(sbuilder);
System.out.println(sbuilder.length());
sbuilder1.setLength(15); //当新长度大于原长度时,将用字符'\u0000'填充
System.out.println(sbuilder1);
System.out.println(sbuilder1.length());

输出

01234
5
0123456789
再谈String、StringBuilder和StringBuffer

之前已经讲过了String是final类,String对象一旦创建内容是不能修改的,即所有修改内容的方法,都是在「暗地里」创建了新的对象,这样就会产生许多的数据垃圾.所以我们如果需要频繁修改字符串的值,应使用StringBuilder类和StringBuffer类.在考虑线程安全时推荐StringBuffer类,在不 考虑线程安全时,推荐使用StringBuilder类.
运行速度比较:StringBuilder>StringBuffer>String
StringBuilder不是线程安全的,但运行速度最快,StringBuffer是可以修改的,且线程安全,运行速度较快,String不可以修改,在对象的回收与创建时会耗费时间,速度最慢.

- THE END -
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章