Photo by Kier in Sight Archives on Unsplash

How to Concatenate Strings In Java?

Amr Saeed

--

In Java, there are different strategies to concatenate strings together. In this article, we will explain those strategies and how they work.

String Concatenation Operator

The string concatenation operator (+) is the most common way to concatenate strings:

String message = "He" + "ll" + "o!";

The way string concatenation operation works internally highly depends on the Java compiler and the Java version you’re using. For instance, before Java 9, the previous expression might be directly optimized by the compiler to something like this:

String message = new StringBuilder("He").append("ll").append("o!").toString();

The reason is that, unlike String, the StringBuilder is mutable. Hence, it’s more efficient in terms of performance and memory.

After Java 9, the optimization is not that straightforward. Instead, the Java compiler uses different strategies on runtime to highly optimize this operation. For more details, you can check this question (How is String concatenation implemented in Java 9?) on StackOverflow.

String concat() Method

The concat() method appends a string to the end of another and returns the result:

String firstName = "Amr";
String secondName = "Saeed";

String fullName = firstName.concat(" ").concat(secondName);

Unlike the string concatenation operator, which is dynamic and highly dependent on the compiler and Java version, the concat() method falls under the String class and has a fixed implementation.

One interesting difference between the concat() method and string concatenation operator is the way they handle null values. If in the previous code the secondName was null, the concat() method would raise NullPointerException. But for the string concatenation operator, the fullName would hold Amr null due to converting the null value into a string.

StringBuilder Class

The StringBuilder class is a class that implements the CharSequence interface in Java. It is the same interface the String class implements.

StringBuilder class implements Serializable, Comparable, and CharSequence.

As mentioned earlier, the StringBuilder is the mutable version of the string, which means that it allows modifying the content without creating new objects. That’s why the StringBuilder is more efficient when it comes to string operations.

String message = new StringBuilder("He").append("ll").append("o!").toString();

One thing you need to be aware of is that StringBuilder methods are not synchronized, hence, not thread-safe. This means that it’s not safe for multiple threads to manipulate it simultaneously.

Regarding null handling, if a variable with null values is passed to the StringBuilder constructor, it will throw a NullPointerException. If it’s passed to the append() method, it will append the null value as a string.

StringBuffer Class

Like the StringBuilder class, the StringBuffer implements the CharSequence interface in Java and behaves the same way.

StringBuffer class implements Serializable, Comparable, and CharSequence.

The only difference between the StringBuilder and StringBuffer is that the StringBuffer methods are synchronized, hence, thread-safe. This means that it is suitable for multi-threaded environments and guarantees data integrity.

String message = new StringBuffer("He").append("ll").append("o!").toString();

The general rule of thumb is to use the StringBuilder as it is more efficient than the StringBuffer because of the synchronization overhead. So, unless you need the thread-safety feature of the StringBuffer, just use the StringBuilder.

String format() Method

The format() method is a static method under the String class. It’s commonly used when you want to inject arguments in a sentence based on their types without splitting it in the code to achieve readability. It’s similar to the printf method in C/C++ if you’re familiar with.

String firstName = "Amr";
String lastName = "Saeed";

String message = String.format("My name is %s %s.", firstName, lastName);

If the string to be formatted holds a null value, the format method will raise a NullPointerException. If one of the arguments to be injected is null, the method will treat the null value as a string and inject it normally into the sentence.

One interesting feature of the format() method is that it accepts an optional Locale parameter. This parameter helps applying some rules to the formatted string based on the region.

double number = 25.32;
String message = "Number is %.2f";

String usFormatted = String.format(Locale.US, message, number);
String germanyFormatted = String.format(Locale.GERMANY, message, number);

The usFormatted variable holds the value Number is 25.32 while the germanyFormatted variable holds the value Number is 25,32.

StringJoiner Class

The StringJoiner class has been introduced in Java 8. It’s very useful in scenarios where you want to join a number of strings with a delimiter and optionally a prefix and suffix.

StringJoiner stringJoiner = new StringJoiner(",", "[", "]");

String numbers = stringJoiner.add("One").add("Two").add("Three").toString();

The numbers variable holds the value [One,Two,Three].

If one of the values to be joined is null, the null will be joined as a string.

String join() Method

The join static method of the String class was also introduced in Java 8, it works as a shortcut to join a number of strings with a delimiter. It takes the delimiter and the strings to be joined as parameters.

String numbers = String.join(",", "One", "Two", "Three");

The numbers variable holds the value One,Two,Three.

If one of the values to be joined is null, the null will be joined as a string.

Collectors joining() Method

Probably you heard about streams in Java 8. The joining() static method of the Collectors class in the streams package can be used also to join elements of an array with a delimiter and optionally a prefix and suffix.

List<String> numberList = Arrays.asList("One", "Two", "Three");

String numbers = numberList.stream().collect(Collectors.joining(",", "[", "]"));

The numbers variable holds the value [One,Two,Three].

Like the rest of the join strategies, if the list contains a null value, it will be joined as a string.

--

--

Amr Saeed

A software engineer with 5+ years working in back-end, front-end, and DevOps. Love building cool stuff that scales and making life easier for fellow developers.