String类
String是个不可变长度的字符串
String类没有提供可以用来修改字符串的方法,所以在Java文档中,String类对象称为不可变字符串,如同3永远是3一样,字符串‘Hello’永远包含H、e、l、l、o代码单元序列,而不能修改其中任何一个字符。可以修改字符串变量,让他引用另外一个字符串变量,就如同可以将存放的3字符串变量改成4一样。
不可变字符串的优点:编译器让字符串共享,具体的工作方式:可以想象成将各种字符串存放在一个公共的常量池中,字符串指向常量池中的相应位置,如果复制一个字符串变量,原始字符串与复制的字符串共享相同的变量。共享带来的高效率远远胜过于提取、拼接字符串所带来的的低效率。
String str = "hello"; str = str + " world";
如果将greeting赋予另外一个值,这样做是正确的,不会产生内存泄漏的情况。因为:原始字符串内存放在堆中,Java会自动的进行垃圾回收,如果一块内存不在使用了,系统最终会将其回收。我们来看一下这张对String操作时内存变化的图:
尽管字符串放在堆中,jvm自动回收,但这样不仅效率低下,而且大量浪费有限的内存空间。初始String值为“hello”,然后在这个字符串后面加上新的字符串“world”,这个过程是需要重新在栈堆内存中开辟内存空间的,最终得到了“hello world”字符串也相应的需要开辟内存空间,这样短短的两个字符串,却需要开辟三次内存空间,不得不说这是对内存空间的极大浪费。
如果这样的操作放在循环内,会极大的影响程序的性能。
为了应对经常性的字符串相关的操作,引入了两个新的类——StringBuffer类和StringBuild类来对此种变化字符串进行处理。
查看程序会发现:很少需要修改字符串,而是往往需要对字符串进行比较(有一种例外的情况,将来自于文件或键盘的单个字符或较短的字符串汇集成字符串。为此Java提供了独立的类。------Java核心技术)
String Buffer
StringBuffer类也可以存放字符串,和String类不同的是,StringBuffer字符串代表的是可变的字符序列,可以对字符串对象内容进行修改,并且不产生未使用的对象。
public class Foo { public static void main(String[] args) { StringBuffer a = new StringBuffer("A"); StringBuffer b = new StringBuffer("B"); operate(a, b); System.out.println(a + "," + b); } static void operate(StringBuffer x, StringBuffer y) { x.append(y); y = x; } }
运行结果:
StringBuilder
有时候需要由较短字符串构建字符串,例如,按键或来自文件中的单词。采用字符串连接的方式到达此目的效率比较低。每次连接字符串,都会构建一个新的String对象,既耗时,又浪费空间。使用StringBuilder类可以避免这个问题发生。
如果需要许多小字段的字符串构建一个字符串,那么应该按照下列步骤进行。首先构建一个空的字符串构建器:
StringBuilder sb=new StringBuilder();
当每次添加一部分内容时,就调用append方法:
sb.append(ch); sb,append(str);
在需要构建字符串时就调用toString方法,将可以得到一个String对象,其中包含了构建器中的字符序列。
String completedString=sb.toString();
在JDK5.0中引入StringBuilder类。这个类前身是StringBuffer,其效率稍微有些低,但允许采用多线程的方式执行添加或者删除的字符的操作。如果所有的字符串在一个单线程中编辑(通常都是这样),则应该用StringBuilder代替他。这两个类的API都是一样的。
下面的API注释包含了StringBuilder类的重要方法:
SringBuilder();//构造一个空洞字符串构建器 int length();//返回构建器或者缓冲器中的代码单元数量 StringBuilder append(String str);//追加一个字符串并返回this StringBuilder append(char c);//追加一个代码单元并返回this StringBuilder appendCodePoint(int cp);//追加一个代码点,并将其转换为一个或两个代码单元并返回this。 void setCharAt(int i,char c);//将第i个代码单元设置为c StringBuilder insert(int offset,String str);//在offset位置插入一个代码单元并返回this。 Stringbuilder delete(int startIndex,int endIndex);//删除偏移量从startIndex到endIndex-1的代码单元并返回this String toString();//返回一个与构建器或缓冲器内容相同的字符串
总结
1、String是变长度的字符串,而StringBuffer和StringBuilder是可变长度的字符串;
2、在对String类进行操作的时候(例如增加字符),实际上是在内存中产生了一个新的String对象; 而StringBuffer和StringBuilder是给原对象增加字符,不是新创建一个对象;
3、Stringbuffer是线程安全的,效率低---->适用于多线程操作字符串缓冲区下操作大量数据
Stringbuilder是非线程安全的----->适用于单线程操作字符串缓冲区下操作大量数据