# Java `StringBuilder`

原文：http://zetcode.com/java/stringbuilder/

Java `StringBuilder`教程显示了如何在 Java 中使用`StringBuilder`。 Java `String`对象是不可变的。 只能创建原始字符串的修饰副本。 当我们需要就地修改字符串时，可以使用`StringBuilder`。

## `StringBuilder`

`StringBuilder`是可变的字符序列。 当我们想就地修改 Java 字符串时，使用`StringBuilder`。 `StringBuffer`是类似于`StringBuilder`的线程安全等效项。

`StringBuilder`具有允许修改字符串的方法，例如`append()`，`insert()`或`replace()`。

## Java `StringBuilder`构造器

`StringBuilder`具有四个构造器：

| 构造器 | 描述 |
| --- | --- |
| `StringBuilder()` | 创建一个初始容量为 16 个字符的空字符串构建器 |
| `StringBuilder(CharSequence seq)` | 从`CharSequence`创建一个字符串生成器 |
| `StringBuilder(int capcity)` | 用指定的首字母创建一个空的字符串生成器 |
| `StringBuilder(String str)` | 从指定的字符串创建字符串生成器 |

## Java `StringBuilder`是可变的

Java `String`是不可变的，而`StringBuilder`是可变的。

`MutableImmutableEx.java`

```java
package com.zetcode;

public class MutableImmutableEx {

    public static void main(String[] args) {

        var word = "rock";
        var word2 = word.replace('r', 'd');

        System.out.println(word2);

        var builder = new StringBuilder("rock");
        builder.replace(0, 1, "d");

        System.out.println(builder);
    }
}

```

该示例演示了`String`和`StringBuilder`之间的主要区别。

```java
var word2 = word.replace('r', 'd');

```

Java `String`具有`replace()`方法，但它不会修改原始字符串。 而是创建修改后的副本。

```java
var builder = new StringBuilder("rock");
builder.replace(0, 1, "d");

```

另一方面，`StringBuilder`替换字符串。

```java
dock
dock

```

这是输出。

## Java `StringBuilder`附加方法

`StringBuilder`包含几个重载`append()`方法，它们在字符串的末尾添加一个值。

`StringBuilderEx.java`

```java
package com.zetcode;

import java.util.stream.LongStream;

public class StringBuilderAppendEx {

    private final static long MAX_VAL = 500;

    public static void main(String[] args) {

        var builder = new StringBuilder();

        var sum = LongStream.rangeClosed(0, MAX_VAL).sum();

        LongStream.rangeClosed(1, MAX_VAL).forEach(e -> {

            builder.append(e);

            if (e % 10 == 0) {
                builder.append("\n");
            }

            if (e < MAX_VAL) {
                builder.append(" + ");
            } else {
                builder.append(" = ");
            }
        });

        builder.append(sum);

        System.out.println(builder);
    }
}

```

该示例从数百个小字符串中构建一个大字符串。 字符串的格式如下：`1 + 2 + 3 + ... + MAX_VAL = SUM`。

```java
var builder = new StringBuilder();

```

空的`StringBuilder`被创建。

```java
LongStream.rangeClosed(1, MAX_VAL).forEach(e -> {

```

将创建一个值范围`1..MAX_VAL`。 我们使用`forEach()`方法迭代这些值。

```java
builder.append(e);

```

我们使用`append()`方法将当前值附加到字符串生成器。

```java
if (e % 10 == 0) {
    builder.append("\n");
}

```

为了使输出适合屏幕，我们在每十个值之后添加一个换行符。

```java
if (e < MAX_VAL) {
    builder.append(" + ");
} else {
    builder.append(" = ");
}

```

在这些值之间，我们添加``+``或`"="`字符。

```java
builder.append(sum);

```

在字符串的末尾，我们添加值的总和。

```java
System.out.println(builder);

```

最后，字符串被打印到控制台。

## `StringBuilder`插入方法

`insert()`方法用于将字符串插入构建器的指定位置。

`StringBuilderInsertEx.java`

```java
package com.zetcode;

public class StringBuilderInsertEx {

    public static void main(String[] args) {

        var sentence = "There is a red fox in the forest.";
        var builder = new StringBuilder(sentence);

        builder.insert(19, "and a wolf ");

        System.out.println(builder);
    }
}

```

该示例使用`insert()`方法将字符串插入句子中。

```java
There is a red fox and a wolf in the forest.

```

我们创建了这句话。

## 获取子字符串的索引

`indexOf()`方法返回第一次出现的子字符串，而`lastIndexOf()`方法返回最后出现的子字符串。

`StringBuilderIndexesEx.java`

```java
package com.zetcode;

public class StringBuilderIndexesEx {

    public static void main(String[] args) {

        var builder = new StringBuilder();

        builder.append("There is a wolf in the forest. ");
        builder.append("The wolf appeared very old. ");
        builder.append("I never saw a wild wolf in my life.");

        var term = "wolf";

        int firstIdx = builder.indexOf(term);
        int firstIdx2 = builder.indexOf(term, 15);

        System.out.format("First occurrence of %s %d%n", term, firstIdx);
        System.out.format("First occurrence of %s %d%n", term, firstIdx2);

        int lastIdx = builder.lastIndexOf(term);
        int lastIdx2 = builder.lastIndexOf(term, 15);

        System.out.format("Last occurrence of %s %d%n", term, lastIdx);
        System.out.format("Last occurrence of %s %d%n", term, lastIdx2);

        System.out.println(builder);
    }
}

```

该示例使用`indexOf()`和`lastIndexOf()`方法来获取`"wolf"`子字符串的索引。

```java
var builder = new StringBuilder(); 

builder.append("There is a wolf in the forest. ");
builder.append("The wolf appeared very old. ");
builder.append("I never saw a wild wolf in my life.");

```

我们使用`append()`方法创建一个字符串生成器。

```java
int firstIdx = builder.indexOf(term);

```

我们从生成器中首次获得`"wolf"`一词。

```java
int firstIdx2 = builder.indexOf(term, 15);

```

从索引 15 开始，我们从构建器中首次获得`"wolf"`术语。

```java
int lastIdx = builder.lastIndexOf(term);
int lastIdx2 = builder.lastIndexOf(term, 15);

```

同样，我们获得`"wolf"`子字符串的最后一次出现。

```java
First occurrence of wolf 11
First occurrence of wolf 35
Last occurrence of wolf 78
Last occurrence of wolf 11
There is a wolf in the forest. The wolf appeared very old. I never saw 
a wild wolf in my life.

```

这是输出。

## `StringBuilder`替换方法

`replace()`方法用指定的新字符串替换字符串生成器中的子字符串。

`StringBuilderReplaceEx.java`

```java
package com.zetcode;

public class StringBuilderReplaceEx {

    public static void main(String[] args) {

        var sentence = "I saw a red fox running into the forest.";
        var builder = new StringBuilder(sentence);

        var term = "fox";
        var newterm = "dog";

        int idx = builder.indexOf(term);
        int len = term.length();

        builder.replace(idx, idx + len, newterm);

        System.out.println(builder);
    }
}

```

该示例将`"fox"`子字符串替换为`"dog"`字符串。

```java
int idx = builder.indexOf(term);

```

我们找到要替换的子字符串的开始索引。

```java
int len = term.length();

```

在我们的操作中，我们需要知道子字符串的长度。

```java
builder.replace(idx, idx + len, newterm);

```

我们称为`replace()`方法。 第一个参数是要删除的子字符串的开始索引，第二个参数是要删除的子字符串的结束索引。 第三个参数是新字符串。

## `StringBuilder`删除字符

在字符串构建器中，有两种删除字符的方法。

`StringBuilderRemoveEx.java`

```java
package com.zetcode;

public class StringBuilderRemoveEx {

    public static void main(String[] args) {

        var sentence = "There is a red fox in the forest.";
        var builder = new StringBuilder(sentence);

        builder.delete(11, 14);
        System.out.println(builder);

        builder.deleteCharAt(11);
        System.out.println(builder);
    }
}

```

该示例从字符串中删除一些字符。

```java
builder.delete(11, 14);

```

使用`delete()`方法，我们删除了由索引指定的子字符串。

```java
builder.deleteCharAt(11);

```

使用`delete()`方法，我们删除一个字符； 在我们的情况下，它是多余的空格字符。

```java
There is a  fox in the forest.
There is a fox in the forest.

```

这是输出。

## `StringBuilder`子字符串

使用`substring()`方法可以从字符串返回子字符串。

`StringBuilderSubstringsEx.java`

```java
package com.zetcode;

public class StringBuilderSubstringsEx {

    public static void main(String[] args) {

        var sentence = "There is a red fox in the forest.";
        var builder = new StringBuilder(sentence);

        var word = builder.substring(15, 18);
        System.out.println(word);

        var sbstr = builder.substring(15);
        System.out.println(sbstr);
    }
}

```

在示例中，我们检索了两个子字符串。

```java
var word = builder.substring(15, 18);

```

该行检索起始索引为 15 且终止索引为 18 的子字符串。

```java
var sbstr = builder.substring(15);

```

在这里，我们检索从索引 15 到句子结尾的子字符串。

```java
fox
fox in the forest.

```

这是输出。

在本教程中，我们使用了 Java `StringBuilder`。 您可能也对相关教程感兴趣： [Java 教程](/lang/java/)， [Java 拆分字符串教程](/java/splitstring)， [Java 中的`HashMap`迭代](/java/hashmapiterate/)， [Java `ArrayList`教程](/articles/javaarraylist/) ， [Java `HashSet`教程](/java/hashset)， [Java `NumberFormat`教程](/java/numberformat/)， [Java8 `forEach`教程](/articles/java8foreach/)，[读取 Java 文本文件](/articles/javareadtext/)和[用 Java 读取和编写 ICO 图像](/articles/javaico/)。