Taste of Google Guava

Not heard about Google Guava yet? Never mind! We’re gonna change that now.

Google Guava is kind of a “Modern Commons” library and imho every Java Developer should use it on a daily basis. It greatly reduces code clutter and improves code quality due to useful utils and functional programming style. Continue reading to taste Guava!

How to get it? You use a dependency management system that understands maven coordinates, right? Here you go:

Got it? Good, let’s get hands on with a couple of simple examples. In (enterprise) applications we do a lot of object conversions i.e. from DTOs to Domain Objects, from Objects to Strings, etc. Lets say we want to convert a list of UserDTO objects to a List of User Domain Objects:

List<span class="sy0"><</span>UserDTO<span class="sy0">></span> userDTOs <span class="sy0">=</span> &hellip;

List converted = ImmutableList.copyOf(
   Iterables.transform( userDTOs, new Function(){
         public User apply( UserDTO input ){
            return new User( input.name, input.id );
         }
}));

This simple example shows the functional-style  programming (at least with the given limited java capacities): A converting function is used to transform the DTOs to Domain Objects and the result is copied to an immutable list.

The cool thing is that the Anonymous Inner Function can be refactored to its own class or an Util class in case it is, or mighty be  reused:

@Test
   public void testFunction(){
         List converted = Lists.newArrayList(
                 Iterables.transform( userDTOs, UserUtils.dtoToUserFunct() ) );
   }

   static class UserUtils{
      public static Function dtoToUserFunct(){
         return new Function(){
            public User apply( UserDTO input ){
               return new User( input.name, input.id );
            }
         };}
   }

 

The com.google.common.collect package contains a lot of highly usable convenience and util classes:

Iterables, Iterators and Collections2. Here’s an example:

Iterables, Iterators and Collections2

Iterables, Iterators and Collections2

Tired of clumsy generic type definition constructs like this?

Map<span class="sy0"><</span>String, <span class="sy0">?</span> <span class="kw1">super</span> Iterable<span class="sy0"><?</span> <span class="kw1">extends</span> UserDTO<span class="sy0">>></span> map <span class="sy0">=</span>
            <span class="kw1">new</span> HashMap<span class="sy0"><</span>String, Iterable<span class="sy0"><?</span> <span class="kw1">extends</span> UserDTO<span class="sy0">>></span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span>

Simply use the Maps util class:

Map<span class="sy0"><</span>String, <span class="sy0">?</span> <span class="kw1">super</span> Iterable<span class="sy0"><?</span> <span class="kw1">extends</span> UserDTO<span class="sy0">>></span> map <span class="sy0">=</span> Maps.<span class="me1">newHashMap</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span>

Readable, isn’t it? There are Util classes for each collection type like Lists, Sets, etc.

Need more sophisticated Maps? This example might not make any sense, but shows the power of Maps created with MapMaker:

Map map = new MapMaker()
      .softKeys()
      .evictionListener( new MapEvictionListener(){
         public void onEviction( Long key, User value ) {
            //DO something
         }} )
      .expireAfterAccess( 1, TimeUnit.HOURS )
      .maximumSize( 100 )
      .makeComputingMap( new Function(){
            public User apply( Long input ) {
               UserDTO user = queryUser( input );
               return Users.dtoToUserFunct().apply( user );
            }
         } );

What about making a comma separated value string out of domain objects?
Let’s take a look on the “old fashioned” imperative style first:

List userList = Arrays.asList( new User( "test1", 1L ),
                                     new User( "test2", 2L ),
                                     new User( "test3", 3L ) );

      StringBuilder result = new StringBuilder();
      Iterator uIt = userList.iterator();
      while( uIt.hasNext() ){
         User u = uIt.next();
         result.append( "'" + u.name + "'" );
         if( uIt.hasNext() ) {
            result.append( ", " );
         }
      }
System.out.println( result.toString() );

And heres the Guava way:

List userList = ...
      String csv = Joiner.on( ", " ).join(
          Collections2.transform( userList,
              new Function(){
                   public String apply( User input ){
                          return "'" + input.name + "'";
                   }
                  } ) );
    System.out.println( csv );

Result is: ‘test1′, ‘test2′, ‘test3′

Matching chars?

public void charMatcher(){
      String s = CharMatcher.is( 'b' ).or( CharMatcher.DIGIT )
                 .retainFrom( "bla foo 1234 foobar" );
      System.out.println( s );
   }

Result is ‘b1234b’. More readable compared to regex, isn’t it?

Please note that CharMatcher is Beta API! Thx to Patrick for the hint:

“Anyway (more importantly and more on topic) when talking about Guava you should not neglect to mention @Beta APIs (you are even using some (CharMatcher) in your examples without explaining their potentially dangerous behavior) basically it is never save to use @Beta APIs in any library project without repackaging the classes.”

Read the “important warnings” on the Guava Homepage before using Beta APIs!

One of the Hightlights, at least for me, are Multimaps. A Multimap allows to map multiple values to one key out of the box:

   public void testMultiMap()
   {
      Multimap usersByForename = LinkedListMultimap.create();
      usersByForename.put( "Robert", new User( "Robert Klaus", 1L ) );
      usersByForename.put( "Robert", new User( "Robert Wilhelm", 2L ) );
      usersByForename.put( "Klaus", new User( "Klaus Adenauer", 2L ) );
      System.out.println( usersByForename.get( "Robert" ) );
   }

Enough candy for now. Go and taste it yourself!

Also look at the libraries source code to learn modern and good-practice coding techniques in Java.

 

Links:
http://code.google.com/p/guava-libraries/ (Guava Homepage)
Guava Package Overview (worth to have a look at!)
http://www.discursive.com/book/322 (Brief examples for individual Guava components)
http://blog.solidcraft.eu/2010/10/googole-guava-v07-examples.html (Further examples)
Or just use Google Search

 

About the author

Arthur Hupka

Arthur Hupka

I have graduated in Computer Science and I am working for Bosch Software Innovations since 2009 as a Java Developer and Technical Consultant with expertise in web applications and batch processing. The past two years I have been involved in several credit risk rating projects and spent months at different customer sites. Recently, I have joined the product development team. I’m interested in all aspects of software development like (component based) software design, architecture, code quality, tests, scrum, etc. In my spare time I’m also experimenting with my own project based on Apache Wicket, Brix CMS, and Google Guice. I enjoy doing sports like bike cycling, beach volleyball and snowboarding. Lake Constance is a great area for doing that btw! I also like reading and visiting festivals during summer. Sometimes I enjoy cooking but I hate housekeeping.