String类和StringBuffer类的比较

我们先看一下下面的代码

String str=“abc”;

int i=3;

float f=4.5f;

char ch='a';

boolean b=true;

System.out.println(str + i + f + ch + b);// abc34.5fatrue

在java中我们可以将String类的对象和任意数据进行"+"操做。因为针对String的“+”和“+=”,是Java中唯一被重载的操作符;在Java中,不允许程序员重载操作符。这一点和C++是不同的。在java中String对象是一常量对象,在它们被创建之后不能被改变,因为它们是不可以改变的,所以是可以被共享的。下面用一个程序我们解释一下:

public class StringTest
{
public static void main(String[] args)
{
String str1 = new String("abc");
String str2 = new String("abc");
String str3 = "bcd";
String str4 = "bcd";
if(str1 == str2)
{
System.out.println("str1==str2");
}
else {
System.out.println("str1!=str2");
}
if(str3 == str4)
{
System.out.println("str3==str4");
}
else
{
System.out.println("str3!=str4");
}
str1 = "bcd";
System.out.println("after str1 = \"bcd\"");
if(str1 == str3)
{
System.out.println("str1==str3");
}
else {
System.out.println("str1!=str3");
}
}
}//str1!=str2
str3==str4
after str1 = "bcd"
str1==str3

看到这个结果可能有人会很纳闷,结果怎么是这样的。下面我们来分析一下,首先对于str1!=str2和str3==str4,在我原来的文章里已经解释了(详细请登录http://blog.csdn.net/mengxiangyue)。现在我们解释一下后面的str1==str3。首先我们应该记住在java中String类的对象是可以共享的。在我执行完str1=“bcd”后,java并没有再开辟空间创建一个bcd对象,而是去查找在内存中是否有一个“bcd“的对象,如果有就直接将bcd的地址赋值给str1,所以最后输出的是str1==str3。但是这样也有一个问题,由于在java中的String类的对象是不可以改变的,这就让我们想到假如我们执行str1=”aaa“,那是怎么执行的呢?在java中对于这种赋值是采用在内存中重新开辟空间,再创建一个"aaa"的对象,并将此对象的内存地址赋给str1。这样就完成了str1的赋值,但是这样也就产生了一个问题,原来的"bcd"就没有用了,但是也不能被销毁,只能等到java虚拟机感到内存不够的时候,把它当成垃圾回收。但是这样必定会影响到java程序执行的效率。我们想能不能在不产生垃圾的情况下,对str1重新赋值呢?在java中有一个类——StringBuffer就给我解决了这个问题。下面看一下java帮助文档对于StringBuffer的描述:

public final class StringBuffer

extends Object

implements Serializable, CharSequence

 
  

线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。

可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。

StringBuffer 上的主要操作是 appendinsert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而insert 方法则在指定的点添加字符。

例如,如果 z 引用一个当前内容为 "start" 的字符串缓冲区对象,则此方法调用 z.append("le") 会使字符串缓冲区包含 "startle",而z.insert(4, "le") 将更改字符串缓冲区,使之包含 "starlet"。

通常,如果 sb 引用 StringBuilder 的一个实例,则 sb.append(x) sb.insert(sb.length(),x) 具有相同的效果。

当发生与源序列有关的操作(如源序列中的追加或插入操作)时,该类只在执行此操作的字符串缓冲区上而不是在源上实现同步。

每个字符串缓冲区都有一定的容量。只要字符串缓冲区所包含的字符序列的长度没有超出此容量,就无需分配新的内部缓冲区数组。如果内部缓冲区溢出,则此容量自动增大。从 JDK 5 开始,为该类补充了一个单个线程使用的等价类,即StringBuilder。与该类相比,通常应该优先使用 StringBuilder 类,因为它支持所有相同的操作,但由于它不执行同步,所以速度更快。

可能看了这个大家就很明白了,但是还有一些东西要注意,StringBuffer类中不能使用"+"+=",因为在java中只有String类重载了"+"+="。我们可以利用好StringBuffer类提供的方法append(追加)、insert(插入)、delete(删除)等方法替代String类。

这只是自己的一点见解,希望能对你有帮助。

你可能感兴趣的:(String类和StringBuffer类的比较)