什么是 StringBuilder 以及何时使用它

一个 StringBuilder 表示一系列字符,它不像普通的字符串,是可变的。通常需要修改我们已经创建的字符串,但标准字符串对象不可变。这意味着每次修改字符串时,都需要创建,复制并重新分配新的字符串对象。

string myString = "Apples";
mystring += " are my favorite fruit";

在上面的例子中,myString 最初只有 Apples 的值。但是,当我们连接我最喜欢的水果时,字符串类在内部需要做的是:

  • 创建一个新的字符数组,等于 myString 的长度和我们要追加的新字符串。
  • myString 的所有字符复制到新数组的开头,并将新字符串复制到数组的末尾。
  • 在内存中创建一个新的字符串对象,并将其重新分配给 myString

对于单个串联,这是相对微不足道的。但是,如果需要在循环中执行许多追加操作呢?

String myString = "";
for (int i = 0; i < 10000; i++)
    myString += " "; // puts 10,000 spaces into our string

由于反复复制和创建对象,这将显着降低程序的性能。我们可以通过使用 StringBuilder 来避免这种情况。

StringBuilder myStringBuilder = new StringBuilder();    
for (int i = 0; i < 10000; i++)
    myStringBuilder.Append(' ');

现在,当运行相同的循环时,程序执行时间的性能和速度将明显快于使用普通字符串。为了使 StringBuilder 恢复正常的字符串,我们可以简单地调用 StringBuilderToString() 方法。

但是,这并不是 StringBuilder 唯一的优化。为了进一步优化功能,我们可以利用其他有助于提高性能的属性。

StringBuilder sb = new StringBuilder(10000); // initializes the capacity to 10000

如果我们事先知道 StringBuilder 需要多长时间,我们可以提前指定它的大小,这将阻止它需要调整它内部的字符数组的大小。

sb.Append('k', 2000);

虽然使用 StringBuilder 进行追加比字符串快得多,但如果你只需要多次添加单个字符,它可以运行得更快。

完成构建字符串后,可以使用 StringBuilder 上的 ToString() 方法将其转换为基本的 string。这通常是必要的,因为 StringBuilder 类不继承 string

例如,以下是如何使用 StringBuilder 创建 string

string RepeatCharacterTimes(char character, int times)
{
    StringBuilder builder = new StringBuilder("");
    for (int counter = 0; counter < times; counter++)
    {
        //Append one instance of the character to the StringBuilder.
        builder.Append(character);
    }
    //Convert the result to string and return it.
    return builder.ToString();
}

总之,当需要对性能进行多次修改时,应使用 StringBuilder 代替字符串。