String、StringBuilder、StringBuffer
2016-02-22 18:00
453 查看
先进行一段测试代码:
输出结果:
类的定义:
1.
2.
3.
附:
2.上面列举出了各个类中所有的成员属性,从上面可以看出这些类其实是通过char数组来保存字符串的。
String、StringBuffer、StringBuilder的关系
从类的定义中可以看出StringBuffer与StringBuilder都继承了同一个父类,两个类中的方法大部分是相同的,String在处理字符串频繁拼接的时候效率慢,有StringBuffer类进行解决了,为什么还需要StringBuilder?
在文档注释中有这样的三句话:
String:@since JDK1.0
StringBuffer:@since JDK1.0
StringBuilder:@since 1.5
大致可以看出,StringBuilder出现的比较晚,目的是对StringBuffer进行简易替换以进一步提高效率,在提高效率的同时必然有部分功能是要舍弃的。
①StringBuilder是一个可变的字符序列。此类提供一个与
API,但不保证同步。该类被设计用作
②StringBuffer是线程安全的可变字符序列。可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。
在使用StringBuffer或是StringBuilder时用到的最多的方法是append和insert,执行效率也就体现在这两个方法上,两个类中方法的对比:
java.lang.StringBuffer#publicsynchronized
StringBuffer append……
java.lang.StringBuilder#public
StringBuilder append……
可以发现在StringBuffer的方法声明中多了synchronized修饰,也就是该方法是线程安全的,且在StringBuffer中多数方法是线程安全的,但是在StringBuilder中没有对线程进行考虑,也就是StringBuilder更快的原因所在。
而String慢又慢在什么地方呢?
都知道String是一个常量,存储在内存中一个叫字符串缓冲池的区域中,一经生成,不可改变。看下面的一段代码:
能够看出:String在进行字符串拼接的时候原对象并没有改变,而是生成一个全新的对象并将引用赋值给变量,而StringBuffer和StringBuilder是在原对象上进行的操作。这也就解释了为什么String进行字符串频繁拼接效率低的原因。
但是StringBuilder就一定是最快的吗?
执行上面三局代码的时候,效率显然是第一句快一些。对于少量的字符串直接相加,效率很高,因为在编译时便确定了它的值,是个常量。但是对于使用变量进行的字符串+操作,效率就不如StringBuffer和StringBuilder了。
总结:
1.String适用于少量字符串直接相加操作;
2.StringBuilder适用于不考虑线程的情况下的多字符串拼接操作,也是优先考虑的;
3.StringBuffer只有在考虑现车甘泉的情况下才使用;
4.执行大量字符串拼接操作时速度:String<StringBuffer<StringBuilder;
5.StringBuilder比StringBuffer快的原因是忽略了对线程安全的考虑,是StringBuffer的简易替换。
附录:StringBuffer与StringBuilder方法整理
1.构造方法,经常使用的是构造一个其中不带字符的对象,其初始容量都为 16 个字符。以及传入String字符串构造一个对象。
2.append(),拼接字符串;
3.insert(),插入字符串;
4.detelte(),删除字符串;
以及一些类似于String类的方法、获取容量、反转操作等方法。
<span style="font-size:14px;"> long startStr = System.currentTimeMillis(); String str = ""; for(int i = 0 ; i<100000 ; i++){ str += i; } long endStr = System.currentTimeMillis(); System.out.println("String循环用时:" + String.valueOf(endStr-startStr)); long startSbf = System.currentTimeMillis(); StringBuffer sbf = new StringBuffer(); for(int i = 0 ; i<100000 ; i++){ sbf.append(i); } long endSbf = System.currentTimeMillis(); System.out.println("StringBuffer循环用时:" + String.valueOf(endSbf-startSbf)); long startSbi = System.currentTimeMillis(); StringBuilder sbi = new StringBuilder(); for(int i = 0 ; i<100000 ; i++){ sbi.append(i); } long endSbi = System.currentTimeMillis(); System.out.println("StringBuilder循环用时:" + String.valueOf(endSbi-startSbi));</span>
输出结果:
<span style="font-size:14px;">String循环用时:28509 StringBuffer循环用时:21 StringBuilder循环用时:14</span>对比一下发现在进行字符串多次拼接时String花费的时间远远大于StringBuffer和StringBuilder,StringBuilder花费时间最少。
类的定义:
1.
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { /** The value is used for character storage. */ private final char value[]; /** Cache the hash code for the string */ private int hash; // Default to 0 /** use serialVersionUID from JDK 1.0.2 for interoperability */ private static final long serialVersionUID = -6849794470754667710L; …… }
2.
public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence { /** use serialVersionUID from JDK 1.0.2 for interoperability */ static final long serialVersionUID = 3388685877147921107L; /** * Constructs a string buffer with no characters in it and an * initial capacity of 16 characters. */ public StringBuffer() { super(16); } …… }
3.
<pre class="java" name="code">public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence { /** use serialVersionUID for interoperability */ static final long serialVersionUID = 4383685877147921099L; /** * Constructs a string builder with no characters in it and an * initial capacity of 16 characters. */ public StringBuilder() { super(16); } …… }
附:
abstract class AbstractStringBuilder implements Appendable, CharSequence { /** * The value is used for character storage. */ char[] value; /** * The count is the number of characters used. */ int count; /** * This no-arg constructor is necessary for serialization of subclasses. */ AbstractStringBuilder() { } /** * Creates an AbstractStringBuilder of the specified capacity. */ AbstractStringBuilder(int capacity) { value = new char[capacity]; } …… }1.三个类都被声明为了final,意味着三个类都不能被继承,并且它们的成员方法都默认为final方法,final意味着不能够修改,也就是说这些方法不能够被覆写。
2.上面列举出了各个类中所有的成员属性,从上面可以看出这些类其实是通过char数组来保存字符串的。
String、StringBuffer、StringBuilder的关系
从类的定义中可以看出StringBuffer与StringBuilder都继承了同一个父类,两个类中的方法大部分是相同的,String在处理字符串频繁拼接的时候效率慢,有StringBuffer类进行解决了,为什么还需要StringBuilder?
在文档注释中有这样的三句话:
String:@since JDK1.0
StringBuffer:@since JDK1.0
StringBuilder:@since 1.5
大致可以看出,StringBuilder出现的比较晚,目的是对StringBuffer进行简易替换以进一步提高效率,在提高效率的同时必然有部分功能是要舍弃的。
①StringBuilder是一个可变的字符序列。此类提供一个与
StringBuffer兼容的
API,但不保证同步。该类被设计用作
StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比
StringBuffer要快。
②StringBuffer是线程安全的可变字符序列。可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。
在使用StringBuffer或是StringBuilder时用到的最多的方法是append和insert,执行效率也就体现在这两个方法上,两个类中方法的对比:
java.lang.StringBuffer#publicsynchronized
StringBuffer append……
java.lang.StringBuilder#public
StringBuilder append……
可以发现在StringBuffer的方法声明中多了synchronized修饰,也就是该方法是线程安全的,且在StringBuffer中多数方法是线程安全的,但是在StringBuilder中没有对线程进行考虑,也就是StringBuilder更快的原因所在。
而String慢又慢在什么地方呢?
都知道String是一个常量,存储在内存中一个叫字符串缓冲池的区域中,一经生成,不可改变。看下面的一段代码:
<span style="font-size:14px;">String str1 = "abc"; String str2 = str1; str1 +="d"; System.out.println(str1);//abcd System.out.println(str1==str2);//false System.out.println(str2);//abc StringBuffer sbf1 = new StringBuffer("abc"); StringBuffer sbf2 = sbf1; sbf1.append("d"); System.out.println(sbf1==sbf2);//true System.out.println(sbf2);//abcd StringBuilder sbi1 = new StringBuilder("abc"); StringBuilder sbi2 = sbi1; sbi1.append("d"); System.out.println(sbi1==sbi2);//true System.out.println(sbi2);//abcd</span>
能够看出:String在进行字符串拼接的时候原对象并没有改变,而是生成一个全新的对象并将引用赋值给变量,而StringBuffer和StringBuilder是在原对象上进行的操作。这也就解释了为什么String进行字符串频繁拼接效率低的原因。
但是StringBuilder就一定是最快的吗?
String str = "hel" + "lo" + "wor" + "ld" + "。"; StringBuffer sbf = new StringBuffer().append("hel").append("lo").append("wor").append("ld").append("。"); StringBuilder sbi = new StringBuilder().append("hel").append("lo").append("wor").append("ld").append("。");
执行上面三局代码的时候,效率显然是第一句快一些。对于少量的字符串直接相加,效率很高,因为在编译时便确定了它的值,是个常量。但是对于使用变量进行的字符串+操作,效率就不如StringBuffer和StringBuilder了。
总结:
1.String适用于少量字符串直接相加操作;
2.StringBuilder适用于不考虑线程的情况下的多字符串拼接操作,也是优先考虑的;
3.StringBuffer只有在考虑现车甘泉的情况下才使用;
4.执行大量字符串拼接操作时速度:String<StringBuffer<StringBuilder;
5.StringBuilder比StringBuffer快的原因是忽略了对线程安全的考虑,是StringBuffer的简易替换。
附录:StringBuffer与StringBuilder方法整理
1.构造方法,经常使用的是构造一个其中不带字符的对象,其初始容量都为 16 个字符。以及传入String字符串构造一个对象。
2.append(),拼接字符串;
3.insert(),插入字符串;
4.detelte(),删除字符串;
以及一些类似于String类的方法、获取容量、反转操作等方法。
相关文章推荐
- UIVisualEffectView(自定义模糊视图)
- SSH+Easyui之combotree ,TreeGrid 树形展现数据
- SourceTree——MAC OSX下的Git GUI客户端
- UINavigationController + UIScrollView组合,视图尺寸的设置探秘(三)
- UINavigationController + UIScrollView组合,视图尺寸的设置探秘(二)
- UINavigationController + UIScrollView组合,视图尺寸的设置探秘(一)
- easyUI 布局
- AFNetworking 遇到错误 Code=-1016 "Request failed: unacceptable content-type: text/plain"
- 【Deep Learning】genCNN: A Convolutional Architecture for Word Sequence Prediction
- 「UI 测试自动化selenium」汇总
- 有备无患 打造UEFI应急启动盘
- leetcode笔记:Increasing Triplet Subsequence
- iOS UIButton的基本使用
- LeetCode_OJ【63】Unique Paths II
- iOS AVQueuePlayer 详解
- Google推出iOS功能性UI测试框架EarlGrey
- mongo VUE的使用(增删改查)
- 从UIL源码学习到新内容
- runOnUiThread使用实例
- iOS关于CAShapeLayer与UIBezierPath的知识内容