天天看點

#深度解析StringBuffer

基本介紹

StringBuffer代表可變的字元序列,可對字元串内容進行增删,很多方法與String相同,但是StringBuffer是可變長度的

StringBuffer是一個容器

StringBuffer類圖如下

從類圖中可以看出

StringBuffer的直接父類 是 AbstractStringBuilder

StringBuffer 實作了 Serializable, 即 StringBuffer 的對象可以串行化

在父類中 AbstractStringBuilder 有屬性 char[] value,不是 final

該 value 數組存放 字元串内容,存放在堆中

StringBuffer 是一個 final 類,不能被繼承

因為 StringBuffer 字元内容是存在 char[] value, 是以在變化(增加/删除) 時,不用每次都更換位址(即不是每次建立新對象), 是以效率高于 String

String 和 StringBuffer 互相轉換

首先看一下StringBuffer的構造器

package com.wxit.stringbuffer;

/**
 * @Author wj
 * StringBuffer學習,構造器的使用
 **/
public class StringBuffer01 {
    public static void main(String[] args) {
        //建立一個大小為16的char[],用于存放字元内容
        StringBuffer stringBuffer01 = new StringBuffer();
        
        //2.通過構造器指定char[]的大小
        StringBuffer stringBuffer02 = new StringBuffer(100);

        //通過給一個String 建立 StringBuffer,char[] 大小就是str.length + 16
        StringBuffer stringBuffer03 = new StringBuffer("hello");
    }
}
           

以上三個構造器對應的源碼如下圖

代碼示例如下

package com.wxit.stringbuffer;

/**
 * @Author wj
 * String與StringBuffer互相轉化
 **/
public class StringAndStringBuffer {
    public static void main(String[] args) {

        //String --> StringBuffer
        String str = "hello world";
        //方式一 使用構造器
        StringBuffer stringBuffer = new StringBuffer(str);
        System.out.println(stringBuffer);

        StringBuffer stringBuffer1 = new StringBuffer();
        StringBuffer append = stringBuffer1.append(str);
        System.out.println(append);

        //StringBuffer -->  String
        StringBuffer stringBuffer2 = new StringBuffer("即使再小的帆也能遠航");
        //方式一 : StringBuffer提供的toString方法
        String s = stringBuffer2.toString();
        System.out.println(s);

        //方式二:使用構造器
        String s1 = new String(stringBuffer2);
        System.out.println(s1);
    }
}
           

StringBuffer方法

從類圖中可以看出StringBuffer中有衆多方法

以上隻是部分方法,還不包括父類的方法

下面列舉常用的方法

常用方法

代碼示例

package com.wxit.stringbuffer;

/**
 * @Author wj
 * StringBufferMethod常用方法
 **/
public class StringBufferMethod {
    public static void main(String[] args) {
        StringBuffer buffer = new StringBuffer("你好");
        //增加
        buffer.append(",");
        buffer.append("吳傑");
        buffer.append("李婷").append("佳偉").append("子龍").append("子雲").append("還有合一小家");
        System.out.println(buffer);

        //删
        System.out.println(buffer.delete(5,7));

        //改
        System.out.println(buffer.replace(4,6,"小昊"));

        //查找指定的子串在字元串第一次出現的索引,如果找不到傳回-1
        System.out.println(buffer.indexOf("子雲"));

        //插入  在索引為 0 的位置插入 "hello",原來索引為 9 的内容自動後移
        System.out.println(buffer.insert(0,"hello"));
    }
}
           

運作效果

StringBuffer練習

以下代碼輸出什麼?為什麼?

代碼如下

package com.wxit.interview;

/**
 * @Author wj
 **/
public class Demo08 {
    public static void main(String[] args) {
        String str = null;
        StringBuffer sb = new StringBuffer();
        sb.append(str);
        System.out.println(sb.length());//4
    }
}
           

解析如下

首先 String str = null; 是成立的

然後進入到StringBuffer的源碼中,檢視append()方法,源碼如下

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

從源碼中看出StringBuffer中的append方法有調用了父類的append方法,是以,追進父類AbstractStringBuilder檢視父類的append方法,源碼如下

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;
    }           

又str為空,是以又調用了appendNull()方法,追進appendNull()方法,代碼如下

private AbstractStringBuilder appendNull() {
        int c = count;
        ensureCapacityInternal(c + 4);
        final char[] value = this.value;
        value[c++] = 'n';
        value[c++] = 'u';
        value[c++] = 'l';
        value[c++] = 'l';
        count = c;
        return this;
    }           

由此可以看出把空對象轉化為字元數組'null'

故最後輸出的結果應該為4

練習二

package com.wxit.test;

import javax.swing.plaf.synth.SynthOptionPaneUI;
import java.util.Scanner;

/**
 * @Author wj
 * 練習
 * 需求:輸入價格,要求,價格的小數點前面每三位就用一個逗号隔開
 **/
public class StringBufferDemo01 {
    public static void main(String[] args) {
        /*
        思路分析
        1.定義一個Scanner 對象,接收使用者的價格(String)
        2.希望使用到StringBuffer中的insert方法,需要将String 轉換成StringBuffer
        3.然後使用相關的方法進行字元串的處理
         */

        Scanner scanner = new Scanner(System.in);
        System.out.println("請輸入價格");
        String price = scanner.next();
        System.out.println("輸入的價格為:" + price);
        StringBuffer sb = new StringBuffer(price); //123456.789
        //先完成一個最簡單的實作
//        System.out.println(sb.lastIndexOf("."));
        System.out.println(sb.insert(sb.lastIndexOf(".") - 3,","));
        //有上面可得出規律為,先找到小數點的索引位置,然後向該索引的前三個位置插入一個逗号,是以要做一個循環
        for (int i = sb.lastIndexOf(".") - 3;i > 0; i -= 3){
            sb.insert(i,",");
        }
        System.out.println(sb);
    }
}
           

繼續閱讀