zoukankan      html  css  js  c++  java
  • StringBuffer和StringBuilder区别?

    1. String是不可变类,改变String变量中的值,相当于开辟了新的空间存放新的string变量

    2. StringBuffer 可变的类,可以通过append方法改变变量的值,且StringBuffer是线程安全的,它的很多方法都是同步方法,支持并发操作,适用于多线程    

    3. StringBuilder 可变的类,但是线程不安全的,用于单线程中性能高于StringBuffer

    4. HashTable 线程安全的,HashMap线程不安全的

    为什么StringBuffer是同步的?

    因为很多方法都是synchronized 。。。

      1 /*
      2  * @(#)StringBuffer.java    1.101 05/11/17
      3  *
      4  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
      5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
      6  */
      7 
      8 package java.lang;
      9 
     10 
     11 /**
     12  * A thread-safe, mutable sequence of characters. 
     13  * A string buffer is like a {@link String}, but can be modified. At any 
     14  * point in time it contains some particular sequence of characters, but 
     15  * the length and content of the sequence can be changed through certain 
     16  * method calls.
     17  * <p>
     18  * String buffers are safe for use by multiple threads. The methods 
     19  * are synchronized where necessary so that all the operations on any 
     20  * particular instance behave as if they occur in some serial order 
     21  * that is consistent with the order of the method calls made by each of 
     22  * the individual threads involved.
     23  * <p>
     24  * The principal operations on a <code>StringBuffer</code> are the 
     25  * <code>append</code> and <code>insert</code> methods, which are 
     26  * overloaded so as to accept data of any type. Each effectively 
     27  * converts a given datum to a string and then appends or inserts the 
     28  * characters of that string to the string buffer. The 
     29  * <code>append</code> method always adds these characters at the end 
     30  * of the buffer; the <code>insert</code> method adds the characters at 
     31  * a specified point. 
     32  * <p>
     33  * For example, if <code>z</code> refers to a string buffer object 
     34  * whose current contents are "<code>start</code>", then 
     35  * the method call <code>z.append("le")</code> would cause the string 
     36  * buffer to contain "<code>startle</code>", whereas 
     37  * <code>z.insert(4, "le")</code> would alter the string buffer to 
     38  * contain "<code>starlet</code>". 
     39  * <p>
     40  * In general, if sb refers to an instance of a <code>StringBuffer</code>, 
     41  * then <code>sb.append(x)</code> has the same effect as 
     42  * <code>sb.insert(sb.length(), x)</code>.
     43  * <p>
     44  * Whenever an operation occurs involving a source sequence (such as
     45  * appending or inserting from a source sequence) this class synchronizes
     46  * only on the string buffer performing the operation, not on the source.
     47  * <p>
     48  * Every string buffer has a capacity. As long as the length of the 
     49  * character sequence contained in the string buffer does not exceed 
     50  * the capacity, it is not necessary to allocate a new internal 
     51  * buffer array. If the internal buffer overflows, it is 
     52  * automatically made larger. 
     53  *
     54  * As of  release JDK 5, this class has been supplemented with an equivalent 
     55  * class designed for use by a single thread, {@link StringBuilder}.  The 
     56  * <tt>StringBuilder</tt> class should generally be used in preference to 
     57  * this one, as it supports all of the same operations but it is faster, as 
     58  * it performs no synchronization.
     59  *
     60  * @author    Arthur van Hoff
     61  * @version     1.101, 11/17/05
     62  * @see     java.lang.StringBuilder
     63  * @see     java.lang.String
     64  * @since   JDK1.0
     65  */
     66  public final class StringBuffer
     67     extends AbstractStringBuilder
     68     implements java.io.Serializable, CharSequence
     69 {
     70 
     71     /** use serialVersionUID from JDK 1.0.2 for interoperability */
     72     static final long serialVersionUID = 3388685877147921107L;
     73 
     74     /**
     75      * Constructs a string buffer with no characters in it and an 
     76      * initial capacity of 16 characters. 
     77      */
     78     public StringBuffer() {
     79     super(16);
     80     }
     81 
     82     /**
     83      * Constructs a string buffer with no characters in it and 
     84      * the specified initial capacity. 
     85      *
     86      * @param      capacity  the initial capacity.
     87      * @exception  NegativeArraySizeException  if the <code>capacity</code>
     88      *               argument is less than <code>0</code>.
     89      */
     90     public StringBuffer(int capacity) {
     91     super(capacity);
     92     }
     93 
     94     /**
     95      * Constructs a string buffer initialized to the contents of the 
     96      * specified string. The initial capacity of the string buffer is 
     97      * <code>16</code> plus the length of the string argument.
     98      *
     99      * @param   str   the initial contents of the buffer.
    100      * @exception NullPointerException if <code>str</code> is <code>null</code>
    101      */
    102     public StringBuffer(String str) {
    103     super(str.length() + 16);
    104     append(str);
    105     }
    106 
    107     /**
    108      * Constructs a string buffer that contains the same characters
    109      * as the specified <code>CharSequence</code>. The initial capacity of
    110      * the string buffer is <code>16</code> plus the length of the
    111      * <code>CharSequence</code> argument.
    112      * <p>
    113      * If the length of the specified <code>CharSequence</code> is
    114      * less than or equal to zero, then an empty buffer of capacity
    115      * <code>16</code> is returned.
    116      *
    117      * @param      seq   the sequence to copy.
    118      * @exception NullPointerException if <code>seq</code> is <code>null</code>
    119      * @since 1.5
    120      */
    121     public StringBuffer(CharSequence seq) {
    122         this(seq.length() + 16);
    123         append(seq);
    124     }
    125 
    126     public synchronized int length() {
    127     return count;
    128     }
    129 
    130     public synchronized int capacity() {
    131     return value.length;
    132     }
    133 
    134 
    135     ...

    既然StringBuffer是线程同步的,那么代价就是损失性能,摘自一个测试http://blog.sina.com.cn/s/blog_5749ead90100b7lq.html

    public class TestBufferAndBuilder {
     public static void main(String[] args) {
    
      String randoms[] = { String.valueOf(Math.random()), String.valueOf(Math.random()), String.valueOf(Math.random()), String.valueOf(Math.random()),
        String.valueOf(Math.random()), String.valueOf(Math.random()), String.valueOf(Math.random()), String.valueOf(Math.random()), String.valueOf(Math.random()),
        String.valueOf(Math.random()) };
    
      System.gc();
      long d = System.currentTimeMillis();
      for (int i = 0; i < 1000000; i++) {
       StringBuffer buffer = new StringBuffer();
       buffer.append(randoms[0]).append(randoms[1]).append(randoms[2]).append(randoms[3]).append(randoms[4]).append(randoms[5]).append(randoms[6]).append(randoms[7]).append(
         randoms[8]).append(randoms[9]);
      }
      System.err.println(System.currentTimeMillis() - d);
      System.gc();
    
      d = System.currentTimeMillis();
      for (int i = 0; i < 1000000; i++) {
       StringBuilder builder = new StringBuilder();
       builder.append(randoms[0]).append(randoms[1]).append(randoms[2]).append(randoms[3]).append(randoms[4]).append(randoms[5]).append(randoms[6]).append(randoms[7]).append(
         randoms[8]).append(randoms[9]);
      }
      System.err.println(System.currentTimeMillis() - d);
    
      System.gc();
      d = System.currentTimeMillis();
      for (int i = 0; i < 1000000; i++) {
       StringBuffer buffer = new StringBuffer(200);
       buffer.append(randoms[0]).append(randoms[1]).append(randoms[2]).append(randoms[3]).append(randoms[4]).append(randoms[5]).append(randoms[6]).append(randoms[7]).append(
         randoms[8]).append(randoms[9]);
      }
      System.err.println(System.currentTimeMillis() - d);
      System.gc();
    
      d = System.currentTimeMillis();
      for (int i = 0; i < 1000000; i++) {
       StringBuilder builder = new StringBuilder(200);
       builder.append(randoms[0]).append(randoms[1]).append(randoms[2]).append(randoms[3]).append(randoms[4]).append(randoms[5]).append(randoms[6]).append(randoms[7]).append(
         randoms[8]).append(randoms[9]);
      }
      System.err.println(System.currentTimeMillis() - d);
    
     }
    }

    输出结果:

        3188
        3657
        1672
        1859

    结果如上,基本上要慢10-20%

  • 相关阅读:
    浏览器开发者工具----F12 功能介绍
    python 爬虫之beautifulsoup(bs4)使用 --待完善
    python 爬虫之beautifulsoup(bs4)环境准备
    python dic字典使用
    python list的使用
    python 实现进制转换(二进制转十进制)
    字符串str的使用方法
    python 第一课 helloworld
    python 学习地址
    React中setState 什么时候是同步的,什么时候是异步的?
  • 原文地址:https://www.cnblogs.com/atom-wangzh/p/8718058.html
Copyright © 2011-2022 走看看