最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java源碼深度分析String與StringBuffer及StringBuilder詳解

 更新時(shí)間:2022年05月11日 10:07:15   作者:星辰與晨曦  
當(dāng)對(duì)字符串進(jìn)行修改的時(shí)候,需要使用?StringBuffer?和?StringBuilder類,和String類不同的是,StringBuffer和?StringBuilder類的對(duì)象能夠被多次的修改,并且不產(chǎn)生新的未使用對(duì)象,本篇我們來(lái)分析分析它們的源碼

String的字符串是不可變的,StringBuffer和StringBuilder是可變的

String:是字符常量,適用于少量的字符串操作的情況。

StringBuilder:適用于單線程下在字符緩沖區(qū)進(jìn)行大量操作的情況 。

StringBuffer:適用多線程下在字符緩沖區(qū)進(jìn)行大量操作的情況。

StringBuffer和StringBuild的區(qū)別

StingBuffer是線程安全的,StringBuild是線程不安全的。

然后再往上查看,就會(huì)發(fā)現(xiàn)他兩都是調(diào)用了AbstractStringBuilder類來(lái)實(shí)現(xiàn)的。

我們不是說(shuō)StringBuffer和StringBuilder創(chuàng)建的字符串是可變的。

至于源碼就直接看源碼,就直接在源碼當(dāng)中詳細(xì)的體現(xiàn)出來(lái)了。

在這篇博客我主要說(shuō)一下StringBuffer,因?yàn)镾tingBuild和StringBuffer的方法幾乎一樣,我在這就不做過(guò)多的詳細(xì)贅述了。

創(chuàng)建StringBuffer()

第一種創(chuàng)建方法:

StringBuffer stringBuffer = new StringBuffer();

在使用這個(gè)方法創(chuàng)建的Buffer字符串的時(shí)候,看底層代碼它就調(diào)用了這個(gè)方法:

    public StringBuffer() {
        super(16);
    }

它雖然沒(méi)有給傳入?yún)?shù),它是它默認(rèn)的是一個(gè)數(shù)組長(zhǎng)度為16的字符串。

在往上看這個(gè)向上傳的父類方法就更加簡(jiǎn)單明了:

    AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }

直接創(chuàng)建長(zhǎng)度為16的字符型數(shù)組。

第二種創(chuàng)建方法:

StringBuffer stringBuffer = new StringBuffer(5);

直接給定要?jiǎng)?chuàng)建的字符長(zhǎng)度。

底層源碼:

    public StringBuffer(int capacity) {
        super(capacity);
    }

第三種創(chuàng)建方法:

StringBuffer stringBuffer = new StringBuffer(“Xin”);

在創(chuàng)建的時(shí)候,初始給定初始化的一個(gè)字符串。

那么在這個(gè)時(shí)候就要考慮它的底層保存字符串的數(shù)組要?jiǎng)?chuàng)建幾位呢? 看源碼,源碼會(huì)告訴我們一切的。

    public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
    }

源碼當(dāng)中明確的告訴了我們,在這種情況下創(chuàng)建的字符串,底層數(shù)組長(zhǎng)度是初始字符串的長(zhǎng)度加16.

小小的總結(jié)一下:

在創(chuàng)建StringBuffer或StringBuilder字符串的時(shí)候如果沒(méi)有給長(zhǎng)度,默認(rèn)為16的長(zhǎng)度,給長(zhǎng)度的話,就是給定的長(zhǎng)度,給的是字符串的話,默認(rèn)初始長(zhǎng)度就是字符串的長(zhǎng)度加16

添加功能

public StringBuffer append(String str)

代碼演示一下,這還要一個(gè)點(diǎn)考慮一下:

public class Demo01 {
    public static void main(String[] args) {
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("Xin_");    //stringBuffer.length = 4
        stringBuffer.append("Chen_");   //stringBuffer.length = 9
        stringBuffer.append("Yu_");     //stringBuffer.length = 12
        stringBuffer.append("Chen_");   //stringBuffer.length = 17
        stringBuffer.append("Xi");      //stringBuffer.length = 19
        System.out.println(stringBuffer);
    }
}

在不停的添加下去,當(dāng)數(shù)組的長(zhǎng)度到達(dá)16的時(shí)候,要考慮一下擴(kuò)容的問(wèn)題,如何擴(kuò)容?

老規(guī)矩,看源代碼,一切都在代碼里:

照著這個(gè)步驟一步一步的點(diǎn)進(jìn)去,到達(dá)最后的源代碼:

MAX_ARRAY_SIZE的長(zhǎng)度為:

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

所以最后是 0x7fffffff-8

總的來(lái)說(shuō),每次底層數(shù)組擴(kuò)容為上次的2倍加2的長(zhǎng)度。

刪除功能

第一種刪除字符串中指定位置的字符

public StringBuffer deleteCharAt(int index)

這個(gè)指定刪除字符串當(dāng)中明確的第幾個(gè)索引。只刪除一個(gè)元素

注意這里是索引的位置,不是第幾個(gè)元素。

public class Demo01 {
    public static void main(String[] args) {
        StringBuffer stringBuffer = new StringBuffer("Xin_Chen_Yu_Chen_Xi");
        System.out.println(stringBuffer);
        stringBuffer.deleteCharAt(4);
        System.out.println(stringBuffer);
    }
}

源碼其實(shí)也不難,就不重視的看了,在這主要看一經(jīng)過(guò)刪除操作,它的字符串長(zhǎng)度是如何減少的。

刪除字符串當(dāng)中指定區(qū)間的字符串

public StringBuffer delete(int start,int end)

牢記在Java當(dāng)中大多情況下,數(shù)組下標(biāo)索引都是左閉右開(kāi)的。

在下面的代碼當(dāng)中,我刪除的就是"Chen_"這5個(gè)字符

public class Demo01 {
    public static void main(String[] args) {
        StringBuffer stringBuffer = new StringBuffer("Xin_Chen_Yu_Chen_Xi");
        System.out.println(stringBuffer);
        stringBuffer.delete(4,9);
        System.out.println(stringBuffer);
    }
}

和上面一樣??匆谎墼创a,如何處理刪除后的字符串的長(zhǎng)度:

它兩的底層都調(diào)用的是native本地反方,交由計(jì)算機(jī)系統(tǒng)完成。

替換功能

就是將字符串中其中某一段的字符串替換為其他的字符串。

public StringBuffer replace(int start,int end,String str)

public class Demo01 {
    public static void main(String[] args) {
        StringBuffer stringBuffer = new StringBuffer("Xin_Chen_Yu_Chen_Xi");
        System.out.println(stringBuffer);
        stringBuffer.replace(4,8,"Gu_Chen");
        System.out.println(stringBuffer);
    }
}

這里也都是數(shù)組的下標(biāo)索引,所以就是從0開(kāi)始計(jì)數(shù)的。

替換這也同上面的一樣,也需要考慮一下底層字符串的長(zhǎng)度問(wèn)題,先看源碼:

反轉(zhuǎn)功能

這個(gè)功能就是將原字符串玩去哪反轉(zhuǎn)過(guò)來(lái),倒序保存起來(lái)。

public class Demo01 {
    public static void main(String[] args) {
        StringBuffer stringBuffer = new StringBuffer("Xin_Chen_Yu_Chen_Xi");
        System.out.println(stringBuffer);
        stringBuffer.reverse();
        System.out.println(stringBuffer);
    }
}

也來(lái)看一下它的源代碼

最后總結(jié)一下

  • String的字符串是不可變的,StringBuffer和StringBuilder是可變的
  • String:是字符常量,適用于少量的字符串操作的情況。
  • StringBuilder:線程不安全的,適用于單線程下在字符緩沖區(qū)進(jìn)行大量操作的情況 。
  • StringBuffer:線程不安全的,適用多線程下在字符緩沖區(qū)進(jìn)行大量操作的情況。

在這幾條總計(jì)出來(lái)的說(shuō)法當(dāng)中,在這再詳細(xì)說(shuō)明一下為什么StringBuffer和StringBuilder是可變的。

在文章上面,我展示了許多的源碼,仔細(xì)觀察一下,Buffer和Builder修飾的方法,它最后返回的都是this,返回了,自己,就是無(wú)論什么操作,它最終都返回的是自己。

但是有些小伙伴還是有個(gè)疑問(wèn),當(dāng)它底層擴(kuò)容超過(guò)它的最大值的時(shí)候,它的數(shù)組不就要換了嗎?

這點(diǎn)確實(shí)是對(duì)的,但是在這我們要理清一個(gè)概念,StringBuffer引用的是底層數(shù)組名字的地址,而數(shù)組在需要換一個(gè)更大的時(shí)候,這個(gè)時(shí)候是數(shù)組的引用變化了,就是指向數(shù)組的地址變了,但是指向StringBuffer的地址是不變的。

我下來(lái)使用一個(gè)debug動(dòng)圖來(lái)展示一下,相信能更好的理解一下。

主要看控制臺(tái)里的StringBuffer和value的值。我們發(fā)現(xiàn)StringBuffer值地址自始至終都沒(méi)有改變,而value的值在到達(dá)16的時(shí)候,需要擴(kuò)容的時(shí)候,就變了。這正印證了我上面所說(shuō)的。

本篇博客也就到此為止了,感謝你的閱讀。如果要是還是想不清楚,特別是最后的總結(jié)部分,歡迎在評(píng)論區(qū)討論,我看到話,會(huì)第一時(shí)間共同討論,解決問(wèn)題。

這也是我重讀javase基礎(chǔ)的一個(gè)系列,比起當(dāng)時(shí)初學(xué)的時(shí)候,現(xiàn)在看問(wèn)題多了個(gè)高度,理解什么也相對(duì)輕松一點(diǎn)全面一些。學(xué)習(xí)起來(lái)更加偏向閱讀源碼來(lái)看,所以多為大家分享看源碼。

到此這篇關(guān)于Java源碼深度分析String與StringBuffer及StringBuilder詳解的文章就介紹到這了,更多相關(guān)Java String源碼分析內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java Swing JProgressBar進(jìn)度條的實(shí)現(xiàn)示例

    Java Swing JProgressBar進(jìn)度條的實(shí)現(xiàn)示例

    這篇文章主要介紹了Java Swing JProgressBar進(jìn)度條的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • IDEA導(dǎo)入eclipse項(xiàng)目并且部署到tomcat的步驟詳解

    IDEA導(dǎo)入eclipse項(xiàng)目并且部署到tomcat的步驟詳解

    這篇文章主要給大家介紹了關(guān)于IDEA導(dǎo)入eclipse項(xiàng)目并且部署到tomcat的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • 解析Java的Jackson庫(kù)中Streaming API的使用

    解析Java的Jackson庫(kù)中Streaming API的使用

    這篇文章主要介紹了解析Java的Jackson庫(kù)中Streaming API的使用,Jackson被用于Java對(duì)象和JSON的互相轉(zhuǎn)換,需要的朋友可以參考下
    2016-01-01
  • 關(guān)于Java下奇怪的Base64詳解

    關(guān)于Java下奇怪的Base64詳解

    這篇文章主要給大家介紹了關(guān)于Java下奇怪的Base64的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • java配置數(shù)據(jù)庫(kù)連接池的方法步驟

    java配置數(shù)據(jù)庫(kù)連接池的方法步驟

    java配置數(shù)據(jù)庫(kù)連接池的方法步驟,需要的朋友可以參考一下
    2013-05-05
  • mybatis整合springboot報(bào)BindingException:Invalid?bound?statement?(not?found)異常解決

    mybatis整合springboot報(bào)BindingException:Invalid?bound?stateme

    這篇文章主要給大家介紹了關(guān)于mybatis整合springboot報(bào)BindingException:Invalid?bound?statement?(not?found)異常的解決辦法,這個(gè)錯(cuò)誤通常是由于Mapper文件中的statement?id與Java代碼中的方法名不一致導(dǎo)致的,需要的朋友可以參考下
    2024-01-01
  • gateway和jwt網(wǎng)關(guān)認(rèn)證實(shí)現(xiàn)過(guò)程解析

    gateway和jwt網(wǎng)關(guān)認(rèn)證實(shí)現(xiàn)過(guò)程解析

    這篇文章主要介紹了gateway和jwt網(wǎng)關(guān)認(rèn)證實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Classloader隔離技術(shù)在業(yè)務(wù)監(jiān)控中的應(yīng)用詳解

    Classloader隔離技術(shù)在業(yè)務(wù)監(jiān)控中的應(yīng)用詳解

    這篇文章主要為大家介紹了Classloader隔離技術(shù)在業(yè)務(wù)監(jiān)控中的應(yīng)用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Java遞歸尋路實(shí)現(xiàn),你真的理解了嗎

    Java遞歸尋路實(shí)現(xiàn),你真的理解了嗎

    遞歸就是一個(gè)過(guò)程或函數(shù)在其定義或說(shuō)明中有直接或間接調(diào)用自身的一種方法,它通常把一個(gè)大型復(fù)雜的問(wèn)題層層轉(zhuǎn)化為一個(gè)與原問(wèn)題相似的規(guī)模較小的問(wèn)題來(lái)求解,需要的朋友可以參考下
    2021-08-08
  • java并發(fā)編程包JUC線程同步CyclicBarrier語(yǔ)法示例

    java并發(fā)編程包JUC線程同步CyclicBarrier語(yǔ)法示例

    這篇文章主要為大家介紹了java并發(fā)編程工具包JUC線程同步CyclicBarrier語(yǔ)法使用示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-03-03

最新評(píng)論

海兴县| 鲁甸县| 团风县| 景德镇市| 屏东市| 浮梁县| 武穴市| 东源县| 德格县| 晴隆县| 馆陶县| 敖汉旗| 巨鹿县| 天津市| 淮北市| 姜堰市| 建昌县| 银川市| 沁水县| 喀喇| 闽侯县| 黄山市| 佛坪县| 边坝县| 巴中市| 亳州市| 大宁县| 大渡口区| 雷波县| 藁城市| 汶上县| 五河县| 南开区| 东平县| 鹿泉市| 阿巴嘎旗| 曲沃县| 涡阳县| 垫江县| 阜平县| 济源市|