Diving into the Google Guava library (part 2)

</p>
<div xmlns:cc="http://creativecommons.org/ns#" about="http://www.flickr.com/photos/pinksherbet/345653550/"><a rel="cc:attributionURL" href=In part one of this blog series I gave an introduction to the excellent Google Collections and Guava libraries and briefly explained how you as a Java developer can benefit from using Guava with Collections to reduce the amount of boilerplate code in your projects. In this blog post we will dive deeper into the more advanced features that Guava offers to you as a Java developer!

We will take a deeper dive into Guava and look at the really neat CharMatcher class, the Joiner and Splitter classes and what else Guava brings us when it comes to working with primitives.

The Guava CharMatcher
The CharMatcher class in Guava is a quite neat addition to your Java toolbox! Some people call it “StringUtils on steroids”:p
Out of the box you have access to some predefined constant matchers like CharMatcher.WHITESPACE, CharMatcher.JAVA_DIGIT or CharMatcher.ASCII, and in addition you have some neat factory methods like CharMatcher.is(‘aaa’), CharMatcher.isNot(‘bbb’), CharMatcher.oneOf(‘abcd’).negate() and even more complex things like:

CharMatcher.inRange('a', 'z').or(inRange('A', 'Z'));

You can also subclass it and implement the matches(char c) method. You can even create one from one of your Google Collection Predicates (that we will cover next time)!

So, if you want to get all the digits from a piece of text, all you need to do is:

String string = CharMatcher.DIGIT.retainFrom("some text 89983 and more");

You want to go the other way around and remove all digits from a string, simply do the following:

String string = CharMatcher.DIGIT.removeFrom("some text 89983 and more");

For matching purposes you have several methods like:
matchesAllOf(CharSequence)
matchesAnyOf(CharSequence)
matchesNoneOf(CharSequence)

You also have indexIn, lastIndexIn and countIn methods in addition to several methods for trimming, replacing and collapsing.
Check out the Java doc for more info!

Joiner and Splitter
The Joiner class is currently part of Collections and the Splitter class is found in Guava (but will ultimately join hands in Guava, once Collections get it’s 1.0 release).
With the Joiner class, we can do stuff like this:

 String[] subdirs = { "usr", "local", "lib" };
 String directory = Joiner.on("/").join(subdirs);

or this:

 int[] numbers = { 1, 2, 3, 4, 5 };
 String numbersAsString = Joiner.on(";").join(Ints.asList(numbers));

Thanks to Guava we can also join directly on primitives, which is quite handy:

 String numbersAsStringDirectly = Ints.join(";", numbers);

For Strings we can obviously split directly, but the behavior is somewhat strange, and the Splitter class is more robust and gives us more options. Also, String split always returns and array as where the Splitter class returns us an Iterable.

Iterable split = Splitter.on(",").split(numbsAsString);

With the String split you can simply do:

String[] splitRegular = testString.split(",");

But try doing that with a String like this one:

String testString = "foo , what,,,more,";

Output would be:
‘foo ‘
‘ what’


‘more’
And that might be fine, but the Splitter class let’s us gain more control over the desired output of the splitting:

Iterable<String> split = Splitter.on(",").omitEmptyStrings().trimResults().split(testString);

Giving us the output ‘foo’,'what’,'more’

Both the Joiner and Splitter classes are configurable and you can even use the Joiner on maps!

Working with primitives cont’d
In part one of this blog series I briefly mentioned working with primitives and that Guava offers things like Ints.compare(a, b) and Ints.toArray(list).

Let me just introduce you to a couple of more handy things that Guava offers when it comes to working with primitives.

Let’s say we have an array of ints, and we want to know if that array contains a specific int. The old way of doing that would look something like this:

 int[] array = { 1, 2, 3, 4, 5 };
 int a = 4;
 boolean hasA = false;
 for (int i : array) {
 if (i == a) {
 hasA = true;
 }
 }

With Guava, we can do this:

boolean contains = Ints.contains(array, a);

And again, we can do this with all the other primitives as well! We can even do things like this directly in our array:

 int indexOf = Ints.indexOf(array, a);
 int max = Ints.max(array);
 int min = Ints.min(array);
 int[] concat = Ints.concat(array, array2);

In the next post in this series we will take a look at the more advanced features of the Google Collections library such as Functions, Filtering and Ordering! Stay tuned, and please share your comments with us!

About Aleksander Stensby

Aleksander is a lead software developer and co-owner of Integrasco A/S where he has been working since 2004. He has broad experience with Java development and technologies such as Lucene Search, Solr, Hibernate, Mysql, Spring and Hibernate Shards, with keen interests in search, machine learning, pattern recognition and scalability. Aleksander have a MSc from the University of Agder in Norway and Carleton University in Ottawa, Canada. His Master's thesis was awarded University Senate Medal for best Master thesis in 2008. Aleksander enjoy working with challenging tasks and solving AI related problems. In addition to his work at Integrasco, Aleksander also give public talks related to search, scalability and machine learning.