`
阳光星心
  • 浏览: 75944 次
  • 性别: Icon_minigender_2
  • 来自: 广州
社区版块
存档分类
最新评论

String && StringBuffer的区别

阅读更多

String && StringBuffer的区别:
非可变对象一旦创建之后就不能再被改变,可变对象则可以在创建之后被改变。String对象是非可变对象;StringBuffer对象则是可变对象。为获得更佳的性能需要根据实际情况小心谨慎地选择到底使用这两者中的某一个。
String类用来表示那些创建后就不会再改变的字符串,它是不可变的(immutable);
StringBuffer类用来表示内容可变的字符串;
例:
1.String对象:
String str = "Hello";
str += "World";
//     JVM会创建一个临时的StringBuffer类对象,并调用其append()方法完成字符串的拼接,这是因为 String类是不可变的,拼接操作不得不使用StringBuffer类(并且--JVM会将"Hello"和"World"创建为两个新的 String对象)。之后,再将这个临时StringBuffer对象转型为一个String,代价不菲!可见,在这一个简单的一次拼接过程中,我们让程 序创建了四个对象:两个待拼接的String,一个临时StringBuffer,和最后将StringBuffer转型成为 的String--它不是最初的str,而是最初的str的引用指向了新生成的String对象"HelloWorld"。
2.StringBuffer对象:
StringBuffer strBuf = new StringBuffer("Hello");
strBuf.append("World");
//     程序将只产生两个对象:最初的strBuf :"Hello"和拼接时的String("World"),不再需要创建临时的StringBuffer类对象而后还得将其转换回String对象。节省额外的系统开销。

如何选择是使用String还是StringBuffer:
取决于两种情况,第一种情况是需要连接的字符串是在编译期决定的还是在运行期决定的,第二种情况是你使用的是StringBuffer还是String。
1) 第一种情况:编译期决定相对于运行期决定;如:
String str = "This " + "is " + "a " + "Java " + "program";
StringBuffer strBuf = new StringBuffer();
strBuf.append("This ");
strBuf.append("is ");
strBuf.append("a ");
strBuf.append("Java ");
strBuf.append("program");

此时,+操作符比StringBuffer.append()方法要快,WHY?这里编译器的优化起了关键作用,编译器简单地在编译期连接多个字符串。 它使用编译期决定取代运行期决定,在你使用new关键字来创建String对象的时候也是如此。这里str对象在编译期就决定了而 StringBuffer对象是在运行期决定的。运行期决定需要额外的开销当字符串的值无法预先知道的时候,编译期决定作糜谧址 闹悼梢栽は戎 赖氖?候,也就是说String str = "This " + "is " + "a " + "Java " + "program";这段代码在编译时,编译器会对程序作出优化,String str被优化成“This is a Java program”;而StringBuffer strBuf只会在运行时才处理。所以效率是不一样的。(注意,这里的String str = "This " + "is " + "a " + "Java " + "program";与 String str = "Hello";
str += "World";是不一样的);
2) 第二种情况:使用StringBuffer取代String
String str = "Hello";
for(int i = 0; i < 40000; i++) {
     str += "World";
}

StringBuffer strBuf = new StringBuffer("Hello");
for(int i = 0; i < 40000; i++) {
      strBuf.append("World");
}
此时,StringBuffer.append()方法要比+操作符快得多,WHY?原因是两者都是在运行期决定字符串对 象,但是+操作符使用不同于StringBuffer.append()的规则;它是通过String和StringBuffer来完成字符串的连接操作 的。

另外,在使用StringBuffer时,可以通过StringBuffer的构造函数来设定它的初始化容量,这样可以明显地提升性能。这里提到的构造函 数是StringBuffer(int length),length参数表示当前的StringBuffer能保持的字符数量。如:
(1) StringBuffer strBuf = new StringBuffer();
             for(int i = 0; i < 40000; i++) {
                  strBuf.append("Hello");
             }
(2)
StringBuffer strBuf = new StringBuffer(100000);
             for(int i = 0; i < 40000; i++) {
                  strBuf.append("Hello");
             }
此时,(2) 的效率好于 (1),因为StringBuffer内部实现是char数组,当使用缺省的构造函数来创建StringBuffer对象的时候,因为没有设置初始化字符 长度,StringBuffer的容量被初始化为16个字符,也就是说缺省容量就是16个字符。当StringBuffer达到最大容量的时候,它会将自 身容量增加到当前的2倍再加2,也就是(2*旧值+2)。 如果使用缺省值,初始化之后接着往里面追加字符,在追加到第16个字符的时候它会将容量增加到 34(2*16+2),当追加到34个字符的时候就会将容量增加到70(2*34+2)。无论何事只要StringBuffer到达它的最大容量它就不得 不创建一个新的字符数组然后重新将旧字符和新字符都拷贝一遍。所以总是给StringBuffer设置一个合理的初始化容量值是错不了的,这样会带来立竿 见影的性能增益。(2)避免了复制数组的开销。

创建String对象:
String str = "Hello";
//  
JVM先根据内容"Hello"查找对象,如果没找到,则在heap(堆栈)* 上创建新对象,并将其赋予str,否则使用已经存在的对象。
String str = new String("Hello");
//   
据内不管heap上有没有"Hello"这个对象,JVM都会在heap上创建一个新String对象;此时heap上可能会出现内容相同,地址不同的String对象。
推荐使用String str = "Hello";这种方法创建String类型的对象,这样会使heap中只存在唯一的一个存放"Hello"对象的内存地址;实际上我们不需要多个独立的"Hello"对象,因为要运行它们的话浪费时间+浪费内存。我们也不必因使用new String("Hello"); 创 建了多个”Hello”对象而发愁,可以使用intern()方法来避免在堆内存上创建重复的String对象来改善Java的运行性能。String intern()方法检查字符串对象的存在性,如果需要的字符串已经存在,那么它将会引用指向已经存在的字符串对象而不是重新创建一个。这和使用 String str = "Hello";这种方法创建对象就作用上来说是一致的。使用intern():
String str = new String("Hello");
str = str.intern();

String对象的比较:
"=="            //比较地址;
"equals"     //比较内容;
String str1 = "a";
String str2 = "a";
String str3 = new String("a");
str1 == str2        //    true
str1 == str3        //    false
str1.equals(str2);       //   true
str1.equals(str3);       //   true

但是StringBuffer类并没有实现Objcet类的Equals方法,所以不能用这个方法来比较两个StringBuffer类的字符串是否相等:
StringBuffer strBuf1 = new StringBuffer(“a”);
StringBuffer strBuf2 = new StringBuffer(“a”);
     System.out.println(
strBuf1 .equals( strBuf2 ));
程序输出:false

* 这里想对“heap(堆栈) ”做一下更正:应该是heap(堆),而非堆栈。
“堆”是一种通用的内存池,用于存放所有的Java对象。当使用“new”实例化一个对象时,编译器会自动在堆里进行存储分配。
C++在堆栈中创建对象,Java对象引用存储在堆栈中;而Java对象并不存储于其中。
堆栈:堆栈指针向下移动,分配新内存,向上移动,释放内存;创建程序时编译器必须知道存储在堆栈中所有数据的确切大小和生命周期,因为要通过代码实现来控 制上下移动堆栈指针,这一约束限制了程序的灵活性。而如果是在堆上创建对象,编译器不需要知道从堆里分配多少存储区域,也不必知道存储的数据在堆里存活多 长时间。因此,在堆里分配存储有很大的灵活性。

分享到:
评论

相关推荐

    String & StringBuffer全面总结

    String & StringBuffer全面总结,希望能使初学者彻底掌握String&StringBuffer。

    String、StringBuilder和StringBuffer的区别

    在Java编程语言中,String、StringBuilder和StringBuffer都是用来处理字符串的类,它们之间存在一些重要的区别,主要涉及到性能和线程安全性。 首先,`String`类代表的是字符串常量,一旦创建,其内容就不能改变。...

    Java-String&StringBuilder&StringBuffer的区别与分析

    Java中的String、StringBuilder和StringBuffer类都是用于处理字符串的,但在不同的场景下,它们各有优缺点。本篇文章将深入分析这三个类的区别。 首先,我们来看它们的值可变性。String类是不可变的,这意味着一旦...

    String&StringBuffer&StringBuilder三者之间的区别-经典解析.doc

    在Java编程语言中,String、StringBuffer和StringBuilder都是用来处理字符串的重要类,它们各自有特定的使用场景和特性。理解这三个类的区别对于任何Java开发者,无论是初学者还是经验丰富的程序员,都是非常重要的...

    String&Stringbuffer

    #### 二、String与StringBuffer的区别 1. **可变性**:`String`对象是不可变的,而`StringBuffer`对象是可变的。 2. **性能**:对于频繁修改的字符串,使用`StringBuffer`会比不断创建新`String`对象更加高效。 3. ...

    String StringBuffer和StringBuilder区别之源码解析

    "String StringBuffer和StringBuilder区别之源码解析" 在Java中,字符串是我们经常使用的数据类型,而String、StringBuffer和StringBuilder是Java中三种常用的字符串类。在这篇文章中,我们将从源码角度对String、...

    String、StringBuffer、StringBuilder的使用方法

    在Java编程语言中,`String`、`...理解`String`、`StringBuffer`和`StringBuilder`的区别和使用场合,可以帮助开发者写出更高效、更安全的代码。在实际开发中,应根据项目需求和环境选择合适的字符串处理类。

    String、StringBuilder、StringBuffer 用法比较

    stringbuilder用法 String、StringBuilder、StringBuffer 用法比较String、StringBuilder、StringBuffer 用法比较String、StringBuilder、StringBuffer 用法比较String、StringBuilder、StringBuffer 用法比较String...

    String、StringBuffer与StringBuilder之间区别

     StringBuffer:字符创变量  StringBuilder:字符创变量  从上面的名字可以看到,String是“字符创常量”,也就是不可改变的对象。对于这句话的理解你可能会产生这样一个疑问 ,比如这段代码:

    String、StringBuilder、StringBuffer的区别

    String、StringBuilder、StringBuffer的区别 在 Java 中,String、StringBuilder 和 StringBuffer 三者都是字符串处理类,但是它们之间存在着本质的区别。本文将从执行速度、线程安全性、字符串处理方式等方面对这...

    String和StringBuffer的区别

    在Java编程语言中,`String`和`StringBuffer`都是用来表示和操作字符串的重要类,但它们在性能和使用场景上有显著的区别。 首先,`String`类是不可变的,这意味着一旦创建了一个`String`对象,它的内容就不能改变。...

    Java 中String StringBuilder 与 StringBuffer详解及用法实例

    在Java编程语言中,String、StringBuilder和StringBuffer都是用来处理字符串的重要类,它们各有特点,适用于不同的场景。这里我们将深入探讨这三个类的区别、特性和使用策略。 首先,String类是不可变的,这意味着...

    string与stringbuffer的区别

    字符串在Java中的表现形式主要有两种:`String`和`StringBuffer`(或者`StringBuilder`)。它们之间的主要区别在于可变性、性能和使用场景。 1. **不可变性**: `String`类是不可变的,这意味着一旦创建了一个`...

    String与StringBuffer区别详解

    在Java编程语言中,`String`和`StringBuffer`(在Java 5之后被`StringBuilder`取代,但在多线程环境中仍然使用`StringBuffer`)是处理文本字符串的两个核心类,它们各自有着不同的特性和用途。理解它们的区别对于...

    string和StringBuffer的区别

    在Java编程语言中,`String`和`StringBuffer`都是用来表示和操作字符串的重要类,但它们在使用场景和性能上有显著的区别。了解这些差异对于编写高效、优化的代码至关重要。 首先,`String`类是不可变的。这意味着...

    StringBuffer和String_区别

    ### StringBuffer与String的区别详解 #### 一、概念与特性 **String** 是 Java 中一个不可变的类,代表了字符序列。一旦一个 String 对象被创建后,其内容就不能被改变。这使得 String 类非常适合用来表示常量或者...

    String、StringBuilder以及StringBuffer的区别

    String、StringBuilder以及StringBuffer的区别

    String及StringBuffer和StringBuilder的区别

    但是,在某些特别情况下,String 对象的字符串拼接其实是被 JVM 解释成了 StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢。 线程安全性 StringBuffer 是线程安全的,而 ...

    String ,StringBuffer与StringBuilder

    String, StringBuffer 与 StringBuilder 的区别 在 Java 中,String, StringBuffer 和 StringBuilder 三个类都是用于字符操作的,但它们之间有着很大的区别。 首先,String 是不可变类,意味着一旦创建了 String ...

Global site tag (gtag.js) - Google Analytics