Concatenating Strings In Java – 在Java中串联字符串

最后修改: 2018年 12月 29日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.绪论

Java provides a substantial number of methods and classes dedicated to concatenating Strings.

Java提供了大量的方法和类,专门用于连接字符串。

In this tutorial, we’ll dive into several of them as well as outline some common pitfalls and bad practices.

在本教程中,我们将深入探讨其中的几个问题,以及概述一些常见的陷阱和不良做法。

2. StringBuilder

2.字符串Builder

First up is the humble StringBuilder. This class provides an array of String-building utilities that makes easy work of String manipulation.

首先是简陋的StringBuilder。提供了一个String-building utilities数组,使String操作变得简单。

Let’s build a quick example of String concatenation using the StringBuilder class:

让我们使用StringBuilder 类建立一个快速的String concatenation的例子。

StringBuilder stringBuilder = new StringBuilder(100);

stringBuilder.append("Baeldung");
stringBuilder.append(" is");
stringBuilder.append(" awesome");

assertEquals("Baeldung is awesome", stringBuilder.toString());

Internally, StringBuilder maintains a mutable array of characters. In our code sample, we’ve declared this to have an initial size of 100 through the StringBuilder constructor. Because of this size declaration, the StringBuilder can be a very efficient way to concatenate Strings.

在内部,StringBuilder维护着一个可变的字符数组。在我们的代码示例中,我们通过StringBuilder构造器将其声明为初始大小为100由于这个大小声明,StringBuilder可以成为一个非常有效的连接字符串的方式。

It’s also worth noting that the StringBuffer class is the synchronized version of StringBuilder

同样值得注意的是,StringBuffer类是StringBuilder的同步版本。

Although synchronization is often synonymous with thread safety, it’s not recommended for use in multithreaded applications due to StringBuffer’s builder pattern. While individual calls to a synchronized method are thread safe, multiple calls are not.

尽管同步通常是线程安全的同义词,但由于StringBuffer的builder模式,不建议在多线程应用程序中使用。虽然对同步方法的单个调用是线程安全的,但多个调用则不是

3. Addition Operator

3.加法运算符

Next up is the addition operator (+). This is the same operator that results in the addition of numbers and is overloaded to concatenate when applied to Strings.

接下来是加法运算符(+)。这也是导致数字相加的运算符,当应用于字符串时,重载连接。

Let’s take a quick look at how this works:

让我们快速看一下这是如何工作的。

String myString = "The " + "quick " + "brown " + "fox...";

assertEquals("The quick brown fox...", myString);

At first glance, this may seem much more concise than the StringBuilder option. However, when the source code compiles, the + symbol translates to chains of StringBuilder.append() calls. Due to this, mixing the StringBuilder and + method of concatenation is considered bad practice.

乍一看,这似乎比StringBuilder选项要简洁得多。然而,当源代码编译时,+符号转化为StringBuilder.append()调用链。由于这个原因,混合StringBuilder和+方法的连接是被认为是不好的做法

Additionally, String concatenation using the + operator within a loop should be avoided. Since the String object is immutable, each call for concatenation will result in a new String object being created.

此外,应避免在循环中使用+运算符进行String 连接。因为String 对象是不可改变的,每次调用连接将导致一个新的String 对象被创建。

4. String Methods

4.字符串方法

The String class itself provides a whole host of methods for concatenating Strings.

字符串类本身提供了一大堆串联字符串的方法。

4.1. String.concat

4.1.String.concat

Unsurprisingly, the String.concat method is our first port of call when attempting to concatenate String objects. This method returns a String object, so chaining together the method is a useful feature.

不出所料,String.concat方法是我们在尝试连接String对象时的第一个调用端口。该方法返回一个String对象,因此将该方法串联起来是一个有用的功能。

String myString = "Both".concat(" fickle")
  .concat(" dwarves")
  .concat(" jinx")
  .concat(" my")
  .concat(" pig")
  .concat(" quiz");

assertEquals("Both fickle dwarves jinx my pig quiz", myString);

In this example, our chain is started with a String literal, the concat method then allows us to chain the calls to append further Strings.

在这个例子中,我们的链是由一个String字头开始的,concat方法然后允许我们以链式调用来追加更多的Strings

4.2. String.format

4.2.String.format

Next up is the String.format method, which allows us to inject a variety of Java Objects into a String template.

接下来是String.format方法,它允许我们将各种JavaObjects注入Stringtemplate中。

The String.format method signature takes a single String denoting our template. This template contains ‘%’ characters to represent where the various Objects should be placed within it.

String.format 方法的签名需要一个单个String 表示我们的模板。这个模板包含’%’字符,代表各种Objects应该放在哪里

Once our template is declared, it then takes a varargs Object array which is injected into the template.

一旦我们的模板被声明,它就会接受一个varargs Object array,它被注入到模板中

Let’s see how this works with a quick example:

让我们通过一个快速的例子来看看这是如何工作的。

String myString = String.format("%s %s %.2f %s %s, %s...", "I",
  "ate",
  2.5056302,
  "blueberry",
  "pies",
  "oops");

assertEquals("I ate 2.51 blueberry pies, oops...", myString);

As we can see above, the method has injected our Strings into the correct format.

正如我们在上面看到的,该方法已经将我们的字符串注入到正确的格式中。

4.3. String.join (Java 8+)

4.3.String.join (Java 8以上)

If our application is running on Java 8 or above, we can take advantage of the String.join method. With this, we can join an array of Strings with a common delimiter, ensuring no spaces are missed.

如果我们的应用程序运行在Java 8 或以上,我们可以利用String.join方法。通过这个方法,我们可以用一个共同的分隔符连接一个字符串数组,确保不遗漏任何空格。

String[] strings = {"I'm", "running", "out", "of", "pangrams!"};

String myString = String.join(" ", strings);

assertEquals("I'm running out of pangrams!", myString);

A huge advantage of this method is not having to worry about the delimiter between our strings.

这种方法的一个巨大优势是不必担心我们的字符串之间的分隔符。

5. StringJoiner (Java 8+)

5.StringJoiner(Java 8以上)

StringJoiner abstracts all of the String.join functionality into a simple to use class. The constructor takes a delimiter, with an optional prefix and suffix. We can append Strings using the well-named add method.

StringJoiner将所有的String.join功能抽象成一个简单易用的类。构造器需要一个分隔符,以及一个可选的前缀和后缀。我们可以使用名字很好的add方法来追加字符串

StringJoiner fruitJoiner = new StringJoiner(", ");

fruitJoiner.add("Apples");
fruitJoiner.add("Oranges");
fruitJoiner.add("Bananas");

assertEquals("Apples, Oranges, Bananas", fruitJoiner.toString());

By using this class, instead of the String.join method, we can append Strings as the program runs; There’s no need to create the array first!

通过使用这个类,代替String.join方法,我们可以在程序运行时追加字符串;不需要先创建数组!

Head over to our article on StringJoiner for more information and examples.

前往我们的关于StringJoiner的文章,了解更多信息和实例。

6. Arrays.toString

6.Arrays.toString

On the topic of arrays, the Array class also contains a handy toString method which nicely formats an array of objects. The Arrays.toString method also calls the toString method of any enclosed object – so we need to ensure we have one defined.

关于数组的话题,Array class也包含一个方便的toString 方法,可以很好地格式化对象的数组。 Arrays.toString 方法也调用任何封闭对象的toString 方法 – 所以我们需要确保我们有一个定义。

String[] myFavouriteLanguages = {"Java", "JavaScript", "Python"};

String toString = Arrays.toString(myFavouriteLanguages);

assertEquals("[Java, JavaScript, Python]", toString);

Unfortunately, the Arrays.toString method is not customizable and only outputs a String encased in square brackets.

不幸的是,Arrays.toString方法是不可定制的,并且只能输出一个用方括号括起来的String

7. Collectors.joining (Java 8+)

7.Collectors.join(Java 8以上)

Finally, let’s take a look at the Collectors.joining method which allows us to funnel the output of a Stream into a single String.

最后,让我们看看Collectors.join方法,它允许我们将Stream的输出输送到一个String.

List<String> awesomeAnimals = Arrays.asList("Shark", "Panda", "Armadillo");

String animalString = awesomeAnimals.stream().collect(Collectors.joining(", "));

assertEquals("Shark, Panda, Armadillo", animalString);

Using streams unlocks all of the functionality associated with the Java 8 Stream API, such as filtering, mapping, iterating and more.

使用流可以解锁与Java 8 Stream API相关的所有功能,例如过滤、映射、迭代等。

8. Wrap Up

8 总结

In this article, we’ve taken a deep dive into the multitude of classes and methods used to concatenate Strings in the Java language.

在这篇文章中,我们对Java语言中用于连接字符串的众多类和方法进行了深入的研究。

As always, the source code is available over on GitHub.

像往常一样,源代码可在GitHub上获得