一、String存在的问题
Java开辟了两类存储区域,分别是栈和堆:
存储区域 | 存储内容 | 优点 | 缺点 | 回收 |
---|---|---|---|---|
栈 | 基本类型的变量和对象的引用变量 | 存取速度比堆要快,仅次于寄存器,栈数据可以共享 | 存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量 | 当超过变量的作用域后,Java会自动释放掉该变量,内存空间可以立即被另作他用 |
堆 | 由new等指令创建的对象和数组 | 可以动态地分配内存大小,生存期也不必事先告诉编译器 | 由于要在运行时动态分配内存,存取速度较慢 | 由Java虚拟机的自动垃圾回收器来回收不再使用的数据 |
我们在学习前需要先了解Java对象和引用变量,这更有利于之后理解String中存在的问题
请记住,String类是不可改变的,一旦创建String对象,那它的值就无法改变了
此处我们创建两个变量str1和str2,
将其相加后,并非更改了原本引用变量str1指向的堆中String对象内容,
而是重新开辟了一块新空间,用来存放相加后的“HelloWorld”内容,
并将原本指向“Hello”空间的引用变量str1(指针)指向了“HelloWorld”这块空间。 此时原本str1指向的那块空间“Hello”并没有被销毁,
而是在一段时间后由垃圾回收机制自动进行处理,
如果我们需要对很多字符串进行频繁操作的时候,
这种模式下在单位时间内显然是十分耗费内存空间
二、StringBuilder以及链式调用
为解决上面提出的问题,可以使用StringBuffer 和 StringBuilder 类。
和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
StringBuilder 的方法不是线程安全的(不能同步访问),
但StringBuilder 相较于 StringBuffer 有速度优势,
所以多数情况下建议使用 StringBuilder 类。
尝试使用StringBuilder: (引用菜鸟教程中例子,其实质是操作一个线性表)
public class RunoobTest{
public static void main(String args[]){
StringBuilder sb = new StringBuilder(10);
sb.append("Runoob..");
System.out.println(sb);
sb.append("!");
System.out.println(sb);
sb.insert(8, "Java");
System.out.println(sb);
sb.delete(5,8);
System.out.println(sb);
}
}
自己写一个例子:
package com.google.study.string;
import org.junit.Test;
public class StringBuilderTest {
@Test
public void demo(){
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Hello");
stringBuilder.append(" world");
System.out.println(stringBuilder);
}
}