StringBuffer如何在不创建两个对象的情况下实现追加功能?

jav*_*Man 22 java string stringbuilder

这是一个面试问题.我被要求实现StringBuffer追加功能.我在采访后看到了代码.但我无法理解如何通过创建单个对象来完成操作.

我在想这个.

String s = "orange";
s.append("apple");
Run Code Online (Sandbox Code Playgroud)

这里创建了两个对象.

StringBuilder s = new StringBuilder("Orange");
s.append("apple");
Run Code Online (Sandbox Code Playgroud)

现在这里只创建了一个对象.

Java如何进行此操作?

sti*_*vlo 49

首先,您的问题存在问题:

String s = "orange";
s.append("apple");
Run Code Online (Sandbox Code Playgroud)

这里创建了两个对象

正确,在StringBuffer/StringBuilder中创建了两个对象,字符串"orange"和字符串"apple",如果我们不溢出缓冲区,则不会创建对象.所以这些代码行创建2或3个对象.

StringBuilder s = new StringBuilder("Orange");
s.append("apple");
Run Code Online (Sandbox Code Playgroud)

现在这里只创建了一个对象

我不知道你从哪里得到它,在这里你创建一个StringBuilder对象,一个"橙色"字符串,一个"apple"字符串,总共3个对象,如果我们溢出StringBuilder缓冲区则为4.(我将数组创建视为对象创建).


我读了你的问题,StringBuilder如何在不创建新对象的情况下执行追加(当缓冲区没有溢出时)?

你应该看一下StringBuilder,因为它是非线程安全的实现.代码很有趣,易于阅读.我添加了内联评论.

作为内部结构,有一个char数组,而不是String.它最初构建为长度为16,并且每次超过容量时都会增加.如果要追加的字符串适合char数组,则无需创建新对象.

StringBuilder扩展AbstractStringBuilder,您将在其中找到以下代码:

/**
 * The value is used for character storage.
 */
char value[];
Run Code Online (Sandbox Code Playgroud)

由于并非所有数组都将在给定时间使用,因此另一个重要变量是长度:

/**  
 * The count is the number of characters used.
 */
int count;
Run Code Online (Sandbox Code Playgroud)

附加有很多重载,但最有趣的是以下内容:

public AbstractStringBuilder append(String str) {
    if (str == null) str = "null"; //will literally append "null" in case of null
    int len = str.length(); //get the string length
    if (len == 0) return this; //if it's zero, I'm done
    int newCount = count + len; //tentative new length
    if (newCount > value.length) //would the new length fit?
        expandCapacity(newCount); //oops, no, resize my array
    str.getChars(0, len, value, count); //now it will fit, copy the chars 
    count = newCount; //update the count
    return this; //return a reference to myself to allow chaining
}
Run Code Online (Sandbox Code Playgroud)

String.getChars(INT srcBegin处,INT srcEnd,炭[] DST,INT dstBegin)从该字符串到目标字符阵列复制字符.

所以,append方法非常简单,唯一可以发现的魔法是expandCapacity,这里是:

void expandCapacity(int minimumCapacity) {
    //get the current length add one and double it
    int newCapacity = (value.length + 1) * 2; 
    if (newCapacity < 0) { //if we had an integer overflow
        newCapacity = Integer.MAX_VALUE; //just use the max positive integer
    } else if (minimumCapacity > newCapacity) { //is it enough?
        //if doubling wasn't enough, use the actual length computed
        newCapacity = minimumCapacity;
    }
    //copy the old value in the new array
    value = Arrays.copyOf(value, newCapacity); 
}
Run Code Online (Sandbox Code Playgroud)

Arrays.copyOf(char [] original,int newLength)复制指定的数组,截断或填充空字符(如有必要),使副本具有指定的长度.

在我们的例子中,填充,因为我们正在扩大长度.

  • 你能解释一下为什么在expandCapacity中,第一个value.length增加1,然后乘以2?是否需要增加1来考虑空字符 (3认同)

Lor*_*ias 9

是你的朋友,卢克!

这是AbstractStringBuilder的源代码