# `StringBuilder`类

> 原文： [https://docs.oracle.com/javase/tutorial/java/data/buffers.html](https://docs.oracle.com/javase/tutorial/java/data/buffers.html)

[`StringBuilder`](https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html) 对象与 [`String`](https://docs.oracle.com/javase/8/docs/api/java/lang/String.html) 对象类似，但可以修改它们。在内部，这些对象被视为包含一系列字符的可变长度数组。在任何时候，可以通过方法调用来改变序列的长度和内容。

除非字符串构建器在更简单的代码（参见本节末尾的示例程序）或更好的性能方面提供优势，否则应始终使用字符串。例如，如果需要连接大量字符串，则附加到`StringBuilder`对象会更有效。

## 长度和容量

与`String`类一样，`StringBuilder`类具有`length()`方法，该方法返回构建器中字符序列的长度。

与字符串不同，每个字符串构建器还具有 _ 容量 _，即已分配的字符空间数。由`capacity()`方法返回的容量始终大于或等于长度（通常大于），并将根据需要自动扩展以适应字符串构建器的添加。

<caption style="font-weight: bold">`StringBuilder` Constructors</caption>
| 构造函数 | 描述 |
| --- | --- |
| `StringBuilder()` | 创建一个容量为 16 的空字符串生成器（16 个空元素）。 |
| `StringBuilder(CharSequence cs)` | 构造一个字符串构建器，其中包含与指定`CharSequence`相同的字符，以及尾随`CharSequence`的额外 16 个空元素。 |
| `StringBuilder(int initCapacity)` | 创建具有指定初始容量的空字符串构建器。 |
| `StringBuilder(String s)` | 创建一个字符串构建器，其值由指定的字符串初始化，另外还有 16 个空字符串尾随该字符串。 |

例如，以下代码

```
// creates empty builder, capacity 16
StringBuilder sb = new StringBuilder();
// adds 9 character string at beginning
sb.append("Greetings");

```

将生成一个长度为 9 且容量为 16 的字符串构建器：

<center>![A string builder's length is the number of characters it contains; a string builder's capacity is the number of character spaces that have been allocated.](img/868b0844016a508d492263f408986654.jpg)</center>

`StringBuilder`类有一些与`String`类没有的长度和容量相关的方法：

<caption style="font-weight: bold">Length and Capacity Methods</caption>
| 方法 | 描述 |
| --- | --- |
| `void setLength(int newLength)` | 设置字符序列的长度。如果`newLength`小于`length()`，则截断字符序列中的最后一个字符。如果`newLength`大于`length()`，则在字符序列的末尾添加空字符。 |
| `void ensureCapacity(int minCapacity)` | 确保容量至少等于指定的最小值。 |

许多操作（例如，`append()`，`insert()`或`setLength()`）可以增加字符串构建器中字符序列的长度，使得结果`length()`将大于当前`capacity()`。发生这种情况时，容量会自动增加。

## StringBuilder 操作

在`String`中不可用的`StringBuilder`上的主要操作是`append()`和`insert()`方法，它们被重载以接受任何类型的数据。每个都将其参数转换为字符串，然后将该字符串的字符追加或插入字符串生成器中的字符序列。 append 方法总是在现有字符序列的末尾添加这些字符，而 insert 方法在指定点添加字符。

以下是`StringBuilder`类的许多方法。

<caption style="font-weight: bold">Various `StringBuilder` Methods</caption>
| 方法 | 描述 |
| --- | --- |
| `StringBuilder append（boolean b）
StringBuilder append（char c）
StringBuilder append（char [] str）
StringBuilder append（char [] str，int offset，int len）
StringBuilder append（double d）
StringBuilder append（float f）
StringBuilder append（int i）
StringBuilder append（long lng）
StringBuilder append（Object obj）
StringBuilder append（String s）` | 将参数追加到此字符串构建器。在附加操作发生之前，数据将转换为字符串。 |
| `StringBuilder delete（int start，int end）
StringBuilder deleteCharAt（int index）` | 第一种方法在`StringBuilder`的 char 序列中删除从开始到结束-1（包括）的子序列。第二种方法删除位于`index`的字符。 |
| `StringBuilder insert（int offset，boolean b）
StringBuilder insert（int offset，char c）
StringBuilder insert（int offset，char [] str）
StringBuilder insert（int index，char [] str，int offset，int len）
StringBuilder insert（int offset，double d）
StringBuilder insert（int offset，float f）
StringBuilder insert（int offset，int i）
StringBuilder insert（ int offset，long lng）
StringBuilder insert（int offset，Object obj）
StringBuilder insert（int offset，String s）` | 将第二个参数插入到字符串构建器中。第一个整数参数表示要在其中插入数据的索引。在插入操作发生之前，数据将转换为字符串。 |
| `StringBuilder 替换（int start，int end，String s）
void setCharAt（int index，char c）` | 替换此字符串生成器中的指定字符。 |
| `StringBuilder reverse()` | 反转此字符串构建器中的字符序列。 |
| `String toString()` | 返回包含构建器中的字符序列的字符串。 |

* * *

**Note:** You can use any `String` method on a `StringBuilder` object by first converting the string builder to a string with the `toString()` method of the `StringBuilder` class. Then convert the string back into a string builder using the `StringBuilder(String str)` constructor.

* * *

## 一个例子

标题为“字符串”一节中列出的`StringDemo`程序是一个程序的示例，如果使用`StringBuilder`而不是`String`，该程序将更有效。

`StringDemo`逆转了回文。在这里，再一次是它的列表：

```
public class StringDemo {
    public static void main(String[] args) {
        String palindrome = "Dot saw I was Tod";
        int len = palindrome.length();
        char[] tempCharArray = new char[len];
        char[] charArray = new char[len];

        // put original string in an 
        // array of chars
        for (int i = 0; i < len; i++) {
            tempCharArray[i] = 
                palindrome.charAt(i);
        } 

        // reverse array of chars
        for (int j = 0; j < len; j++) {
            charArray[j] =
                tempCharArray[len - 1 - j];
        }

        String reversePalindrome =
            new String(charArray);
        System.out.println(reversePalindrome);
    }
}

```

运行该程序会产生以下输出：

```
doT saw I was toD

```

为了完成字符串反转，程序将字符串转换为字符数组（第一个`for`循环），将数组反转为第二个数组（第二个`for`循环），然后转换回字符串。

如果将`palindrome`字符串转换为字符串构建器，则可以使用`StringBuilder`类中的`reverse()`方法。它使代码更简单，更易于阅读：

```
public class StringBuilderDemo {
    public static void main(String[] args) {
        String palindrome = "Dot saw I was Tod";

        StringBuilder sb = new StringBuilder(palindrome);

        sb.reverse();  // reverse it

        System.out.println(sb);
    }
}

```

运行此程序会产生相同的输出：

```
doT saw I was toD

```

请注意，`println()`打印字符串构建器，如下所示：

```
System.out.println(sb);

```

因为`sb.toString()`是隐式调用的，因为它与`println()`调用中的任何其他对象一样。

* * *

**Note:** There is also a `StringBuffer` class that is _exactly_ the same as the `StringBuilder` class, except that it is thread-safe by virtue of having its methods synchronized. Threads will be discussed in the lesson on concurrency.

* * *