Splitting and joining strings with Guava

Joining strings from a collection or splitting strings in several elements can be quite difficult in Java. The JDK only offers a split method expecting a regular expression and returning an array. But this quite powerful approach is not easy to use, usage of regular expressions can be expensive and needs deeper knowledge of the regular expression patterns. And there is no support for joining elements of collections in the JDK yet. It looks like an implementation is coming in JDK 8. Have a look at this (German) blog post.

But if you are interested in an easy but also powerful approach at the moment, Guava is your man. It offers a fluent API for joining and splitting strings. The class Joiner provides two overloaded static factory methods on() for creating a new Joiner object providing a delimiter as character or string. There are several overloaded join() methods accepting Iterator, Iterable, Arrays or variable object arguments. Joiner can also deal with null values skipping them or provide an alternative value.

assertEquals("1, 2, 3", Joiner.on(", ").join(Arrays.asList(1, 2, 3)));
assertEquals("1, 2, 3", Joiner.on(", ").skipNulls().join(Arrays.asList(1, null, 2, null, 3)));
assertEquals("1, null, 2, null, 3", Joiner.on(", ").useForNull("null").join(Arrays.asList(1, null, 2, null, 3)));

Splitter works similarly but the other way around. The static factory methods provide different delimiter types ranging from characters, strings, CharMatcher, regular expression patterns to fixed lengths. The result is an Iterable which can be directly used in a foreach loop or can be converted to any type of collection. The result string may be trimmed (trimResults()) and empty strings can be ignored (omitEmptyStrings()).

assertEquals(Lists.newArrayList("1", "2", "3"), Lists.newArrayList(Splitter.on(',').split("1,2,3")));
assertEquals(Lists.newArrayList("1", "2", "3"), Lists.newArrayList(Splitter.on(',').trimResults().split("1, 2, 3")));
assertEquals(Lists.newArrayList("1", "2", "3"), Lists.newArrayList(Splitter.on(',').trimResults().omitEmptyStrings().split("1,, , 2, 3")));
assertEquals(Lists.newArrayList("a", "b", "c"), Lists.newArrayList(Splitter.onPattern("\W").split("a,b,c")));
assertEquals(Lists.newArrayList("a", "b", "c"), Lists.newArrayList(Splitter.on(Pattern.compile("\W")).split("a,b,c")));
assertEquals(Lists.newArrayList("abc", "def", "geh", "i"), Lists.newArrayList(Splitter.fixedLength(3).split("abcdefgehi")));

Splitter can also produce maps by separating the splitted parts in key value pairs.

Map map = Splitter.on(',').withKeyValueSeparator(":").split("a:1,b:2,c:3");
assertTrue(map.containsKey("a"));
assertTrue(map.containsValue("2"));
assertEquals("3", map.get("c"));

Splitter and Joiner instances are always immutable. So they are threadsafe and can be used as static final constants.

Short URL for this post: https://wp.me/p4nxik-Yo
This entry was posted in Java and Quality, Java Basics and tagged , , . Bookmark the permalink.

Leave a Reply