Having fun with Guava’s String Helpers

Having fun with Guava’s String Helpers

During my life so far with Java I found myself often using separated Strings, such as a comma separated String. The reason is simple. Separated Strings are useful in many situations, like persistence prototyping, where you don’t want to add a full blown persistence solution but a small, lightweight file based store to save some values. Or, when you transmit data over the wire and don’t want to use a formal protocol but send just a comma separated String of values. I bet you’ve found yourself implementing a List<String> to comma separated String method at least once ;).

Whenever I used separated Strings, two things bugged me. The first is what I call the “Special Element Handling”. When transforming a collection into a separated String you always have to handle one item uniquely, for example, removing the comma from the last element. The second annoying thing is the formatting. With this I mean the special handling for whitespace or null elements in the collection.

The problem here is that the code that will be created to cover the two issues is everything but clean. Let’s take a look at a simple List to Comma Separated String method.

public static String toCommaSeparatedString( List strings ) {
  String result = "";
  if( strings != null && !strings.isEmpty() ) {
    StringBuilder stringBuilder = new StringBuilder();
    for( int i = 0; i < strings.size(); i++ ) {
      String string = strings.get( i );
      if( string != null ) {
        stringBuilder.append( string );
        stringBuilder.append( "," );
      }
    }
    stringBuilder.deleteCharAt( stringBuilder.length() - 1 );
    result = stringBuilder.toString();
  }
  return result;
}

As you can see, we handled the last element by removing the comma from the StringBuilder after the loop. We skipped null elements to avoid NPEs and mal-formatting. We also added a special flow when the collection is null or empty. Ugly, right? When converting a comma separated string back to a List we also have to handle whitespaces like those in this method:

public static List fromCommaSeparatedString( String string ) {
  List strings = new ArrayList();
  String[] splitted = string.split( "," );
  for( int i = 0; i < splitted.length; i++ ) {
    String element = splitted[ i ].trim();
    strings.add( element );
  }
  return strings;
}

As I said in the beginning, everything but clean! The methods are too long and they do too many things. Also it’s not clear why we removed the last comma from the StringBuilder without understanding that we added a comma in every iteration within the loop. The good news is that Google Guava provides String Helpers. I converted the two snippets above using Guava’s Splitter and Joiner.

public static String toCommaSeparatedString( List strings ) {
  Joiner joiner = Joiner.on( "," ).skipNulls();
  return joiner.join( strings );
}

public static List fromCommaSeparatedString( String string ) {
  Iterable split = Splitter.on( "," ).omitEmptyStrings().trimResults().split( string );
  return Lists.newArrayList( split );
}

With this solution we can shrink the lines of code from 22 to 9 while improving readability. The formatting problem I mentioned is also covered by methods like trimResults or skipNulls. In a nutshell, it’s a much cleaner solution compared to the first two methods ;). I have to mention that this post only covers Splitter and Joiner but there is more useful stuff related to strings in Guava. As always, feel free to disagree in a comment ;).