Concatenating Strings In Java

1. Introduction

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

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

2. StringBuilder

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

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

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.

It’s also worth noting that the StringBuffer class is the synchronized version of 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.

3. Addition Operator

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.

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.

4. String Methods

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

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 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.

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.

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

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

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+)

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.

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+)

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 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!

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

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.

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.

7. Collectors.joining (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.

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.

8. Wrap Up

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

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

Related posts:

Java Program to Implement Bellman-Ford Algorithm
Quick Guide on Loading Initial Data with Spring Boot
Spring – Injecting Collections
OAuth2.0 and Dynamic Client Registration
Spring JDBC
Validate email address exists or not by Java Code
Spring 5 and Servlet 4 – The PushBuilder
Java Program to Describe the Representation of Graph using Adjacency Matrix
Java Program to Find Median of Elements where Elements are Stored in 2 Different Arrays
Spring Boot - Enabling HTTPS
Comparing Arrays in Java
Java Program to Implement SimpeBindings API
Java Program to Implement Hash Tables with Linear Probing
Notify User of Login From New Device or Location
Hướng dẫn Java Design Pattern – MVC
Java Program to Implement LinkedHashSet API
Java Program to Generate All Subsets of a Given Set in the Lexico Graphic Order
Java Program to Implement Merge Sort on n Numbers Without tail-recursion
Java Program to Implement Weight Balanced Tree
Batch Processing with Spring Cloud Data Flow
Java Program to Perform Searching Based on Locality of Reference
Java Program to Implement Merge Sort Algorithm on Linked List
Mix plain text and HTML content in a mail
Guide to the Synchronized Keyword in Java
Từ khóa this và super trong Java
Custom Exception trong Java
Jackson Ignore Properties on Marshalling
Java Program to Check whether Directed Graph is Connected using DFS
Java Program to Represent Graph Using Adjacency List
Java Program to Check Whether a Directed Graph Contains a Eulerian Cycle
Tiêu chuẩn coding trong Java (Coding Standards)
Spring Boot Tutorial – Bootstrap a Simple Application