`
linpyi
  • 浏览: 63067 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

String和StringBuffer的比较

阅读更多

今天本来看着原型模式的,不知怎么搞的就到了String和StringBuffer了

 

网上找了一些资料

 

String 对象是非可变对象

 

StringBuffer 对象则是可变对象。

 

非可变对象一旦创建之后就不能再被改变,可变对象则可以在创建之后被改变。

 

为了性能你可以选择不同的对象,效果差别很大

 

底下贴一段测试代码

 

package com.lpy.thread;

public class StringAndStringBuffer {

	public static void main(String[] args) {
		Long statDate = System.currentTimeMillis();
		for (int i = 0; i < 100000; i++) {
			String str = "this is hello.";
		}
		Long endDate = System.currentTimeMillis();
		System.out.println("直接用string='' 使用时间 : "
				+ (endDate - statDate) + " milli seconds");

		
		Long statDate1 = System.currentTimeMillis();
		for (int i = 0; i < 100000; i++) {
			String str = new String("this is hello.");
		}
		
		Long endDate1 = System.currentTimeMillis();
		System.out.println("用String str = new String('')使用时间 : "
				+ (endDate1 - statDate1) + " milli seconds");

		
		
		Long statDate2 = System.currentTimeMillis();
		for (int i = 0; i < 100000; i++) {
			StringBuffer str = new StringBuffer();
			str.append("this is hello.");
		}
		
		Long endDate2 = System.currentTimeMillis();
		System.out.println("用StringBuffer append('')使用时间 : "
				+ (endDate2 - statDate2) + " milli seconds");
		
		//**************测试连接速度*****************
		System.out.println("\r\n**************String和StringBuffer测试连接速度*****************\r\n\n");
		
		Long statDate3 = System.currentTimeMillis();
		String str="";
		for (int i = 0; i < 10000; i++) {//这里缩短了循环次数,100000太慢了
			str+="this is hello.";
		}
		
		Long endDate3 = System.currentTimeMillis();
		System.out.println("使用str连续自加使用时间 : "
				+ (endDate3 - statDate3) + " milli seconds");
		
		
		Long statDate4 = System.currentTimeMillis();
		StringBuffer strBf=new StringBuffer();
		for (int i = 0; i < 10000; i++) {//这里缩短了循环次数,100000太慢了
			strBf.append("this is hello.");
		}
		
		Long endDate4 = System.currentTimeMillis();
		System.out.println("使用StringBuffer连续自加使用时间 : "
				+ (endDate4 - statDate4) + " milli seconds");
		
		
		Long statDate5 = System.currentTimeMillis();
		StringBuffer strBf1=new StringBuffer(150000);
		for (int i = 0; i < 10000; i++) {//这里缩短了循环次数,100000太慢了
			strBf1.append("this is hello.");
		}
		
		Long endDate5 = System.currentTimeMillis();
		System.out.println("使用StringBuffer初始化容量值连续自加使用时间: "
				+ (endDate5 - statDate5) + " milli seconds");
	}
}

 

测试结果

 

直接用string='' 使用时间 : 0 milli seconds
用String str = new String('')使用时间 : 16 milli seconds
用StringBuffer append('')使用时间 : 47 milli seconds

**************String和StringBuffer测试连接速度*****************


使用str连续自加使用时间 : 25859 milli seconds
使用StringBuffer连续自加使用时间 : 16 milli seconds
使用StringBuffer初始化容量值连续自加使用时间: 0 milli seconds

 

可以很清楚的看到效果差距

 

1首先是String str=""和String str = new String()的比较

 

以下引用

 

java虚拟机会维护一个内部的滞留字符串对象的列表(唯一字符串的池)来避免在堆内存中产生重复的String对象。当

JVM从class文件里加载字符串字面量并执行的时候,它会先检查一下当前的字符串是否已经存在于滞留字符串列表,如果

已经存在,那就不会再创建一个新的String对象而是将引用指向已经存在的String对象,JVM会在内部为字符串字面量作这

种检查,但并不会为通过new关键字创建的String对象作这种检查。当然你可以明确地使用String.intern()方法强制JVM

为通过 new关键字创建的String对象作这样的检查。这样可以强制JVM检查内部列表而使用已有的String对象。

  所以结论是,JVM会内在地为字符串字面量维护一些唯一的String对象,程序员不需要为字符串字面量而发愁,但是可

能会被一些通过 new关键字创建的String对象而困扰,不过他们可以使用intern()方法来避免在堆内存上创建重复的

String对象来改善Java的运行性能。

 2,对比了String和StringBuffer.append("")速度上的区别,差别也很大,有人认为append会比String快,其实不一定

 

直接用string='' 使用时间 : 0 milli seconds
用StringBuffer append('')使用时间 : 47 milli seconds

 

也可以明显的看出来,那string什么时候比StringBuffer快了

 

这里编译器的优化起了关键作用,一个是在编译期决定,一个是在运行期决定,2者开销不一样.

 

这里String对象在编译期就决定了而StringBuffer对象是在运行期决定的。运行期决定需要额外的开销当字符串的值无法

 

预先知道的时候,编译期决定作用于字符串的值可以预先知道的时候

 

3.对比str+=""与StringBuffer.append的速度

 

  两者的速度可以说完全不是一个档次的,差距太多了

 

  使用str连续自加使用时间 : 25859 milli seconds
  使用StringBuffer连续自加使用时间 : 16 milli seconds

 

 差别很大,这和上面的对比是不是又有冲突了

 

  以下引用

 

   原因是两者都是在运行期决定字符串对象,但是+操作符使用不同于StringBuffer.append()的规则通过String和

 

StringBuffer来完成字符串连接操作。
 
借助StringBuffer的初始化过程的优化技巧


  你可以通过StringBuffer的构造函数来设定它的初始化容量,这样可以明显地提升性能。这里提到的构造函数是

 

StringBuffer(int length),length参数表示当前的StringBuffer能保持的字符数量。你也可以使用ensureCapacity

 

(int minimumcapacity)方法在StringBuffer对象创建之后设置它的容量。首先我们看看StringBuffer的缺省行为,然后

 

再找出一条更好的提升性能的途径。
 
StringBuffer的缺省行为:


  StringBuffer在内部维护一个字符数组,当你使用缺省的构造函数来创建StringBuffer对象的时候,因为没有设置初

 

始化字符长度,StringBuffer的容量被初始化为16个字符,也就是说缺省容量就是16个字符。当StringBuffer达到最大容

 

量的时候,它会将自身容量增加到当前的2倍再加2,也就是(2*旧值+2)。


  如果你使用缺省值,初始化之后接着往里面追加字符,在你追加到第16个字符的时候它会将容量增加到34

 

(2*16+2),当追加到34个字符的时候就会将容量增加到70(2*34+2)。无论何事只要StringBuffer到达它的最大容

 

量它就不得不创建一个新的字符数组然后重新将旧字符和新字符都拷贝一遍——这也太昂贵了点。所以总是给StringBuffer

 

设置一个合理的初始化容量值是错不了的,这样会带来立竿见影的性能增益。

 

     至于设置初始值,上面我们做了第4个测试,我在StringBuffer strBf1=new StringBuffer(150000);

 

   速度也有差距,当然你不能设置过大,过大会影响效果

 

测试就到这,如何使用大家心理有术,实际情况实际解决,

分享到:
评论

相关推荐

    String StringBuffer和StringBuilder区别之源码解析

    String、StringBuffer和StringBuilder的比较 通过上面的分析,我们可以看到,String类的字符串是不可变的,而StringBuffer和StringBuilder类的字符串可以被修改。StringBuffer类是线程安全的,而StringBuilder类...

    javaString 和StringBuffer的区别

    JAVA平台提供了两个类:String和StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据.这个String类提供了数值不可改变的字符串.而这个StringBuffer类提供的字符串进行修改.当你知道字符数据要改变的时候...

    String ,StringBuffer与StringBuilder

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

    String 和StringBuffer的区别

    从非常细致的角度分析了String和Stringbuffer的主要区别

    String和StringBuffer的区别

    在上述代码示例中,我们比较了使用`String`和`StringBuffer`进行5000次字符串拼接操作的时间消耗。当使用`String`时,每次循环都会生成新的`String`对象,导致总时间达到46687毫秒。而使用`StringBuffer`,由于其...

    String及StringBuffer和StringBuilder的区别

    String、StringBuffer 和 StringBuilder 是 Java 语言中三种不同类型的字符串处理方式,它们之间存在着明显的性能和线程安全性差异。 String String 类型是不可变的对象,每次对 String 对象进行改变时都会生成一...

    String、StringBuffer、StringBuilder的使用方法

    在Java编程语言中,`String`、`StringBuffer`和`StringBuilder`是处理字符串的三个重要类,它们各自有特定的使用场景和优缺点。理解它们的差异对于编写高效的代码至关重要。 **String类** `String`是不可变的类,...

    String、StringBuilder和StringBuffer的区别

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

    string和StringBuffer的区别

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

    源码string和stringbuffer

    针对String的详细介绍针对String的详细介绍针对String的详细介绍针对String的详细介绍针对String的详细介绍针对String的详细介绍针对String的详细介绍针对String的详细介绍针对String的详细介绍针对String的详细介绍...

    java面试笔试题String 和StringBuffer的区别

    在Java编程语言中,`String`与`StringBuffer`是两个重要的字符串处理类,它们各自具有独特的特性和用途,尤其在面试或笔试中常被提及作为考察应聘者对Java基础知识掌握程度的重要知识点。 ### `String`类:不可变性...

    String、StringBuffer与StringBuilder之间区别

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

    String-StringBuffer-StringBuilder

    在Java编程语言中,`String`、`StringBuffer`和`StringBuilder`都是用来处理字符串的类,但它们之间存在显著的差异,主要体现在性能、线程安全性和使用场景上。 首先,`String`是最基本的字符串类,它代表的是不可...

    JAVA中String与StringBuffer的区别 自己的学习笔记总结

    在这个示例中,我们比较了使用 `String` 和 `StringBuffer` 进行 5000 次字符串拼接的执行时间。根据实际运行结果,我们可以发现 `StringBuffer` 的执行时间明显短于 `String`,尤其是在大量字符串拼接的情况下。 #...

    StringBuffer和String_区别

    1. **单线程环境**:在这种情况下,推荐使用 **StringBuilder**,因为它不提供线程安全机制,所以在性能上优于 StringBuffer 和 String。 2. **多线程环境**: - 如果需要修改字符串内容,则应选择 **...

    String和StringBuffer详细用法总结

    ### `String` 和 `StringBuffer` 的基本概念 #### `String` 在Java中,`String` 类表示不可变的字符序列,也就是说一旦创建了一个字符串对象后,其内容就不能被更改。这使得`String`对象非常适合于处理固定不变的...

    String与StringBuffer区别详解

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

    string与stringbuffer的区别

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

Global site tag (gtag.js) - Google Analytics