日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java.lang包—StringBuffer类和StringBuilder类

發(fā)布時間:2024/4/15 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java.lang包—StringBuffer类和StringBuilder类 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

一、數(shù)據(jù)結構

二、線程安全性分析

三、源碼

四、適用場景


一、數(shù)據(jù)結構

在?Java?中字符串屬于對象,Java 提供了 String 類來創(chuàng)建和操作字符串。String 類是不可變類,即一旦一個 String 對象被創(chuàng)建以后,包含在這個對象中的字符序列是不可改變的,直至這個對象被銷毀。Java 提供了兩個可變字符串類 StringBuffer 和 StringBuilder,中文翻譯為“字符串緩沖區(qū)”。StringBuilder 類是 JDK 1.5 新增的類,它也代表可變字符串對象。實際上,StringBuilder 和 StringBuffer 功能基本相似,方法也差不多。不同的是,StringBuffer 是線程安全的,而 StringBuilder 則沒有實現(xiàn)線程安全功能,所以性能略高。因此在通常情況下,如果需要創(chuàng)建一個內容可變的字符串對象,則應該優(yōu)先考慮使用 StringBuilder 類。StringBuffer、StringBuilder、String 中都實現(xiàn)了 CharSequence 接口。CharSequence 是一個定義字符串操作的接口,它只包括 length()、charAt(int index)、subSequence(int start, int end) 這幾個 API。StringBuffer、StringBuilder、String 對 CharSequence 接口的實現(xiàn)過程不一樣,如下圖 1 所示:

圖 1??對CharSequence接口的實現(xiàn)

?

二、線程安全性分析

對待線程安全問題,我們可以把一個字符串的改變看成兩部來實現(xiàn),

  • 首先就是字符串的索引位置存放元素 *
  • 然后繼續(xù)增大Size的值。
  • 在單線程的情況下如果size等于0,那么添加一個元素的步驟就是將元素放在位置0,然后size=1,在單線程中這樣做是沒有任何問題的。但是多線程的話,線程a將元素放在位置0,此時的線程B也在搶奪CPU,假設搶奪成功, 那么這個時候a線程的size還沒有運行到增加的那一步 ,同時b線程在位置0又放入一個元素,這就回將a線程放入的元素覆蓋掉, 所以我們來看看實際的情況就是兩個元素都是放在位置0但是實際元素只有一個,size卻等于2,這就造成了線程不安全的問題。

    三、源碼

    1、StringBuffer

    StringBuffer buffer= new StringBuffer(); buffer.append("d");

    進入append

    @Override public synchronized StringBuffer append(String str) {toStringCache = null;super.append(str);return this; }

    函數(shù)被synchronized修飾,說明是有線程安全的

    2、StringBuilder

    StringBuilder builder= new StringBuilder(); builder.append("1"); @Override public StringBuilder append(String str) {super.append(str);return this; }

    沒有synchronized,不是線程安全

    3、擴展因子

    public AbstractStringBuilder append(String str) {if (str == null)return appendNull();int len = str.length();ensureCapacityInternal(count + len);str.getChars(0, len, value, count);count += len;return this; }

    其實如果沒有synchronize的話,在count+=len不安全,所以如果并發(fā)比較大,盡量少用stringBuilder

    四、適用場景

    stringbuffer固然是線程安全的,stringbuffer固然是比stringbuilder更慢,固然,在多線程的情況下,理論上是應該使用線程安全的stringbuffer的。然而,然而,然而,有誰給我一個實際的案例來顯示你需要一個線程安全的string拼接器?對不起,至少在我淺薄的十幾年編程生涯中還沒有遇到過,也許,僅僅是也許,這個地球上的確是存在這樣的編程需求的,然而,它至少跟99.99...99%的程序員是無關的。所以,對于題主的問題,他們的適用場景是什么?最簡單的回答是,StringBuffer基本沒有適用場景,你應該在所有的情況下選擇使用StringBuiler,除非你真的遇到了一個需要線程安全的場景,如果遇到了,請務必在這里留言通知我。然后,補充一點,關于線程安全,即使你真的遇到了這樣的場景,很不幸的是,恐怕你仍然有99.99....99%的情況下沒有必要選擇StringBuffer,因為StringBuffer的線程安全,僅僅是保證jvm不拋出異常順利的往下執(zhí)行而已,它可不保證邏輯正確和調用順序正確大多數(shù)時候,我們需要的不僅僅是線程安全,而是鎖。

    最后,為什么會有stringbuffer的存在,如果真的沒有價值,為什么jdk會提供這個類?答案太簡單了,因為最早是沒有stringbuilder的,sun的人不知處于何種愚蠢的考慮,決定讓stringbuffer是線程安全的,然后大約10年之后,人們終于意識到這是一個多么愚蠢的決定,意識到在這10年之中這個愚蠢的決定為java運行速度慢這樣的流言貢獻了多大的力量,于是,在jdk1.5的時候,終于決定提供一個非線程安全的stringbuffer實現(xiàn),并命名為stringbuilder。順便,javac好像大概也是從這個版本開始,把所有用加號連接的String運算都隱式的改寫成StringBuilder,也就是說,從jdk1.5開始,用加號拼接字符串已經沒有任何性能損失了。

    如諸多評論所指出的,我上面說,"用加號拼接字符串已經沒有任何性能損失了"并不嚴謹,嚴格的說,如果沒有循環(huán)的情況下,單行用加號拼接字符串是沒有性能損失的,java編譯器會隱式的替換成stringbuilder,但在有循環(huán)的情況下,編譯器沒法做到足夠智能的替換,仍然會有不必要的性能損耗,因此,用循環(huán)拼接字符串的時候,還是老老實實的用StringBuilder吧。

    讀后有收獲可以支付寶請作者喝奶茶?

    總結

    以上是生活随笔為你收集整理的java.lang包—StringBuffer类和StringBuilder类的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。