Java 可变字符串StringBuilder&StringBuffer 区别联系 构造器 方法

可变字符串StringBuilder&StringBuffer

  • 字符串的分类:

    • 不可变字符串:String。在地址不变的情况下,字符串不可改变
    • 可变字符串:StringBuilder,StringBuffer。地址不变的情况下,想把“ab”变成“abcd”是可能的,直接追加即可sb.append("cd")
  • 区别与联系

  • String类是不可变类,即一旦一个String对象被创建后,包含在这个对象中的字符序列是不可改变的,直至这个对象销毁。
  • StringBuffer类则代表一个字符序列可变的字符串,可通过append、insert、reverse、setChartAt、setLength等方法改变其内容。一旦生成了最终的字符串,调用toString方法将其转变为String
    • StringBuffer:JDK1.0开始 效率低 线程安全
  • StringBuilder类在JDK1.5新增,与StringBuffer相似,构造方法和方法基本相同。区别在于StringBuffer是线程安全的,而StringBuilder是线程不安全的,所以性能略高。通常情况下,创建一个内容可变的字符串,应该优先考虑使用StringBuilder。将 StringBuilder 的实例用于多个线程是不安全的。如果需要这样的同步,则建议使用 StringBuffer。
    • StringBuilder:JDK1.5开始 效率高 线程不安全
  • StringBuffer的主要StringBufferappendinsert方法,它们被重载以便接受任何类型的数据。 每个都有效地将给定的数据转换为字符串,然后将该字符串的字符附加或插入到字符串缓冲区。 append方法总是在缓冲区的末尾添加这些字符; insert方法将insert添加到指定点。

  • StringBuilder&StringBuffer底层:非常重要的两个属性:

    /**该值用于字符存储
     * The value is used for character storage.
     */
    char[] value;
    /**计数是使用的字符数
     * The count is the number of characters used.
     */
    int count;
    
  • 每个字符串生成器都有一定的容量。只要字符串生成器所包含的字符序列的长度没有超出此容量,就无需分配新的内部缓冲区。如果内部缓冲区溢出,则此容量自动增大。 字符数组扩容,自动扩容时长度翻倍后加2。new = old * 2 + 2,相关源码如下:

    class AbstractStringBuilder
        
    private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0) {
            value = Arrays.copyOf(value,
                    newCapacity(minimumCapacity));
        }
    }
    
    private int newCapacity(int minCapacity) {
            // overflow-conscious code 左移一位相当于乘2
            int newCapacity = (value.length << 1) + 2;
            if (newCapacity - minCapacity < 0) {
                newCapacity = minCapacity;
            }
            return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
                ? hugeCapacity(minCapacity)
                : newCapacity;
    }
    

构造器

StringBuilder/StringBuffer的构造器完全相同

构造方法摘要
StringBuilder()构造一个其中不带字符的字符串生成器,初始容量为 16 个字符。
StringBuilder(CharSequence seq)构造一个字符串生成器,包含与指定的 CharSequence 相同的字符。
StringBuilder(int capacity)构造一个其中不带字符的字符串生成器,初始容量由 capacity参数指定。
StringBuilder(String str)构造一个字符串生成器,并初始化为指定的字符串内容。

方法

StringBuilder&StringBuffer方法基本一致,StringBuffer中个别方法使用了synchronized修饰

Modifier and TypeMethodDescription
StringBufferappendCodePoint(int codePoint)codePoint参数的字符串表示法附加到此序列。
intcapacity()返回当前容量。
charcharAt(int index)返回此序列中指定索引index处的 char 值。
intcodePointAt(int index)返回指定索引处的字符(Unicode代码点)。
intcodePointBefore(int index)返回指定索引之前的字符(Unicode代码点)。
intcodePointCount(int beginIndex, int endIndex)返回此序列指定文本范围内的Unicode代码点数。
StringBufferdelete(int start, int end)删除此序列的子字符串中的字符。
StringBufferdeleteCharAt(int index)删除 char在这个序列中的指定位置。
voidensureCapacity(int minimumCapacity)确保容量至少等于规定的最小值。
intindexOf(String str)返回指定子字符串第一次出现的字符串内的索引。不存在返回-1。
intindexOf(String str, int fromIndex)返回指定子串的第一次出现的字符串中的索引,从指定的索引开始。不存在返回-1。
intlastIndexOf(String str)返回指定子字符串最右边出现的字符串内的索引。不存在返回-1。
intlastIndexOf(String str, int fromIndex)返回指定子字符串最后一次出现的字符串中的索引。不存在返回-1。
intlength()返回长度(字符数)。
intoffsetByCodePoints(int index, int codePointOffset)返回此序列中与 indexcodePointOffset代码点偏移的索引。
StringBufferreplace(int start, int end, String str)用指定的String中的字符替换此序列的子字符串中的 String
StringBufferreverse()导致该字符序列被序列的相反代替。
voidsetCharAt(int index, char ch)指定索引处的字符设置为 ch
voidsetLength(int newLength)设置字符序列的长度。
CharSequencesubSequence(int start, int end)返回一个新的字符序列,该序列是该序列的子序列。
Stringsubstring(int start)返回一个新的 String ,其中包含此字符序列中当前包含的字符的子序列。
Stringsubstring(int start, int end)返回一个新的 String ,其中包含此序列中当前包含的字符的子序列。
StringtoString()返回表示此顺序中的数据的字符串。
voidtrimToSize()尝试减少用于字符序列的存储。
  • void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)

字符从该序列复制到目标字符数组dst 。 要复制的第一个字符是索引srcBegin ; 要复制的最后一个字符在索引srcEnd-1 。 要复制的srcEnd-srcBegin总数为srcEnd-srcBegin 。 字符被复制到的子阵列dst开始于索引dstBegin且结束于 dstbegin + (srcEnd-srcBegin) - 1

srcBegin - 以此偏移开始复制;srcEnd - 在此偏移处停止复制;dst - 将数据复制到的数组;dstBegin - 偏移到 dst 。

append

  • StringBuffer append(类型 变量)

(类型 变量)9种组合:(doubled) (floatf) (inti) (longlng) (Stringstr) (StringBuffersb) (boolean b) (char c) (char[] str)

作用:将参数的字符串表示附加到此序列

(StringBuffersb)中,如果 sb 为 null,则向该序列中添加 4 个 “null” 字符。

  • StringBuffer append(char[] str, int offset, int len)

char数组参数的子阵列的字符串表示附加到此序列。从索引offset开始的char数组str按顺序附加到该序列的内容。 此序列的长度由的值增加len 。

str - 要附加的字符,offset -要追加的第一个字符的索引,len - 要追加的 char的数量。

  • StringBuffer append(CharSequence s[, int start, int end])

单参时,追加指定的CharSequence到这个序列,

如果snull ,则附加四个字符"null"

将指定的 CharSequence 的子序列附加到此序列。参数 s 的字符从索引 start 开始,按顺序附加到此序列的内容,直到(独占)索引end。 这个序列的长度增加了 end - start 的值。

令 n 为执行 append 方法之前的此字符序列的长度。 如果 k 小于 n,则该字符序列中索引 k 处的字符等于该序列中索引 k 处的字符; 否则,它等于参数 s 中索引 k+start-n 处的字符。

s - 要追加的顺序;start - 要追加的子序列的起始索引;end - 要附加的子序列的结束索引。

insert

  • StringBuffer insert(int Offset, 类型 变量)

(类型 变量)9种组合:(doubled) (floatf) (inti) (longlng) (Stringstr) (StringBuffersb) (boolean b) (char c) (char[] str)

作用:在此序列中插入参数的字符串表示形式。 参数的字符在offset的位置插入到该序列的内容中。 该序列的长度增加参数的长度。

offset参数必须大于或等于0 ,小于或等于此序列的length 。 0 <= offset <= sb.length()

(StringBuffersb)中,如果 sb 为 null,则向该序列中添加 4 个 “null” 字符。

  • StringBuffer insert(int index, char[] str, int offset, int len) 在此序列中插入 str数组参数的子阵列的字符串表示形式。

在此序列中插入str数组参数的子阵列的字符串表示形式。 子阵列开始在指定的offset和延伸len char秒。 子阵列的字符在index的位置被插入到该序列中。 该序列的长度增加len char s。

index - 插入子阵列的位置;str - A char数组; offset - 要插入的子阵列中的第一个 char的索引; len - 要插入的子阵列中的 char的数量。

  • StringBuffer insert(int dstOffset, CharSequence s[, int start, int end])

将指定 CharSequence 的子序列插入到此序列中。

如果s是null ,那么四个字符"null"被插入到该序列中。

startend 指定的参数 s 的子序列按顺序插入到指定目标偏移处的此序列中,向上移动最初位于该位置上方的任何字符。 这个序列的长度随着end - start而增加。

该序列中索引k处的字符等于:

如果k小于dstOffset ,为此序列中索引 k 处的字符
如果k大于或等于dstOffset但小于dstOffset+end-start ,为参数 s 中索引 k+start-dstOffset 处的字符
如果k大于或等于dstOffset+end-start ,为此序列中索引 k-(end-start) 处的字符

dstOffset参数必须大于或等于0 ,小于或等于此序列的length 。

dstOffset - 此序列中的偏移量;s - 要插入的序列;start - 要插入的子序列的起始索引;end - 要插入的子序列的结束索引。

实例

public class Test {
    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer("YuZhen Feng");
        //增
        sb.append("nb");
        System.out.println(sb); //YuZhen Fengnb

        //删
        sb.delete(2, 6);//删除位置在[2,6)上的字符
        System.out.println(sb); //Yu Fengnb
        sb.deleteCharAt(1);//删除位置在1上的字符
        System.out.println(sb); //Y Fengnb

        //改-->插入
        sb = new StringBuffer("YuZhen Feng");
        sb.insert(6, "NBPro");//在索引为6的位置上插入NBPro
        System.out.println(sb); //YuZhenNBPro Feng

        //改-->替换
        sb = new StringBuffer("YuZhen Feng");
        sb.replace(0, 6, "NBProPlusMax Xs");//将索引[0,6)位置上字符换为NBMax
        System.out.println(sb); //NBProPlusMax Xs Feng
        sb.setCharAt(6, '!');//将索引6处替换为 !
        System.out.println(sb); //NBProP!usMax Xs Feng

        //查
        sb = new StringBuffer("YuZhen Feng");
        for (int i = 0; i < sb.length(); i++) {
            System.out.print(sb.charAt(i) + "\t"); //遍历字符串
        } //Y  u  Z  h  e  n     F  e  n  g  
        System.out.println();

        //截取
        String str = sb.substring(2, 6);//创建截取字符串索引得到的[2,6)的副本
        System.out.println(str); //Zhen
        System.out.println(sb); //YuZhen Feng
    }
}
posted @ 2021-08-11 00:42  SKPrimin  阅读(34)  评论(0编辑  收藏  举报