Dustin's Pages

Monday, February 23, 2015

Joining Strings in JDK 8

JDK 8 introduced language features such as lambda expressions, streams, and even the new Date/Time API that will change the way we write Java applications. However, there are also several new APIs and features that might be less "game changing," but still bring greater convenience and expressiveness to the Java programming language. In this post, I look at one of these smaller features and examine the ability to easily concatenate multiple Strings in JDK 8.

Using the two static String.join methods is an easy way to combine strings, but the StringJoiner class introduced with JDK 8 provides even more power and flexibility. The next code listing demonstrates instantiating a StringJoiner and passing it a specified delimiter (decimal point), prefix (opening parenthesis), and suffix (closing parenthesis).

The StringJoiner is an especially attractive approach in the scenario where one is adding delimiting characters to a String being built up as part of some type of iteration with a StringBuilder. In such cases, it was often necessary to remove an extra character added to the end of that builder with the last iteration. StringJoiner is "smart enough" to only add the delimiters between strings being concatenated and not after the final one. The successive calls to add(CharSequence) methods look very similar to the StringBuilder/StringBuffer APIs.

The final JDK 8-introduced approach for joining Strings that I will cover in this post is use of stream-powered collections with a joiningcollector (reduction operation). This is demonstrated in the next code listing and its output is the same as the String.join approach used to print a MAC address via the String.join that accepted an Iterable as its second argument.

If a developer wants the ability to provide a prefix and suffix to the joined string without having to make successive calls to add methods required to join Strings with StringJoiner, the Collectors.joining(CharSequence, CharSequence, CharSequence) method is a perfect fit. The next code example shows the IP address example from above used to demonstrate StringJoiner, but this time implemented with a collection, stream, and joining collector. The output is the same as the previous example without the need to specify add(CharSequence) for each String to be joined.