Slide 1

Slide 1 text

Pink & Squishy: Fun with Guava #1 Chris K. Jester-Young December 2010

Slide 2

Slide 2 text

What is Guava? • Open-source library from Google • Extends Java in many useful ways • Widely used (e.g., IDEA 10 comes bundled with it) • Builds on ideas from Java Collections Framework o Designed with input from Josh Bloch (JCF creator) • Very clean interface (for a Java API, anyway)

Slide 3

Slide 3 text

The Pink & Squishy series • Why Pink & Squishy? That's what guavas are! • Each session, I'll cover three or so Guava-related topics o At least, until I run out of stuff I want to talk about • Where feasible, code examples will use JRuby o Why JRuby? It's our main language at On-Site.com o Some topics, especially generics-related, will use Java • On occasion I'll put in refreshers for related topics o Let me know if I need to expand more!

Slide 4

Slide 4 text

Java Collections refresher Java Collections has three major collection interfaces: • List: items in insertion order ArrayList.new [-3, 1, 4, 1, 5, 9] # [-3, 1, 4, 1, 5, 9] • Set: unique items in no particular order HashSet.new [-3, 1, 4, 1, 5, 9] # [1, -3, 4, 5, 9] o SortedSet: unique items with given ordering TreeSet.new [-3, 1, 4, 1, 5, 9] # [-3, 1, 4, 5, 9] • Map: unique keys (in no particular order) with values HashMap.new 'foo'=>0, 'bar'=>1, 'baz'=>2 # {baz=2, foo=0, bar=1} o SortedMap: unique keys (with ordering) with values TreeMap.new 'foo'=>0, 'bar'=>1, 'baz'=>2 # {bar=1, baz=2, foo=0}

Slide 5

Slide 5 text

BiMap: two-way (bijective) mapping • A BiMap maps unique keys to unique values, and vice versa bimap = HashBiMap.create 'C++'=>'Bjarne', 'Perl'=>'Larry', 'Python'=>'Guido', 'Ruby'=>'Matz' bimap # {Ruby=Matz, Python=Guido, Perl=Larry, C++=Bjarne} bimap.inverse # {Guido=Python, Matz=Ruby, Bjarne=C++, Larry=Perl} • Allows fast and easy inverse lookups bimap['Perl'] # Larry bimap.inverse['Matz'] # Ruby

Slide 6

Slide 6 text

BiMap: two-way (bijective) mapping • Values must be unique bimap['Perl 6'] = 'Larry' # IllegalArgumentException bimap.force_put 'Perl 6', 'Larry' bimap['Perl 6'] # Larry bimap['Perl'] # nil (unset by force_put)

Slide 7

Slide 7 text

Multimap: many-to-many mapping • Multimap maps non-unique keys to non-unique values • Or, put another way, it maps keys to any number of values multimap = HashMultimap.create multimap.put 'C', 'Brian' multimap.put 'C', 'Dennis' multimap.put 'AWK', 'Alfred' multimap.put 'AWK', 'Brian' multimap.put 'AWK', 'Peter' multimap # {C=[Brian, Dennis], AWK=[Alfred, Brian, Peter]} multimap.get 'C' # [Brian, Dennis] multimap.get 'AWK' # [Alfred, Brian, Peter] multimap.get 'Perl' # [] (not nil)

Slide 8

Slide 8 text

Inverting Multimaps • There is no BiMultimap, but they're still easy to invert inverted = Multimaps.invert_from multimap, HashMultimap.create inverted # {Alfred=[AWK], Brian=[C, AWK], Dennis=[C], Peter=[AWK]} • You can also easily invert from a normal Map… map = {'Java'=>'James', 'Groovy'=>'James', 'Scala'=>'Martin', 'Clojure'=>'Rich'} multimap = Multimaps.for_map map inverted = Multimaps.invert_from multimap, HashMultimap.create inverted # {Martin=[Scala], James=[Groovy, Java], Rich=[Clojure]}

Slide 9

Slide 9 text

Inverting Multimaps • …or from a Multimap to a normal Map, for that matter map = Maps.transform_values multimap.as_map, &Iterables.method(:get_only_element) map # {Clojure=Rich, Scala=Martin, Groovy=James, Java=James}

Slide 10

Slide 10 text

Multiset: sets with occurrence counter • Multiset holds unique items with corresponding counters multiset = HashMultiset.create multiset << 'foo' << 'bar' << 'baz' << 'foo' # [baz, foo x 2, bar] multiset.remove 'foo' # [baz, foo, bar] multiset.add 'foo', 2 # [baz, foo x 3, bar] multiset.remove 'foo', 3 # [baz, bar] multiset.count 'foo' # 0 multiset.count 'bar' # 1 multiset.set_count 'foo', 42 # [baz, foo x 42, bar] multiset.set_count 'bar', 10 # [baz, foo x 42, bar x 10]

Slide 11

Slide 11 text

Recap • BiMap o Provides both forward and inverse mapping  Both maps implement Map, hence the capital M o Normally implemented as two maps, updated together • Multimap o Provides many-to-many mapping  Does not implement Map, hence the lower-case m o Normally implemented as Map> o Clean API: no need to check for prior key presence • Multiset o Provides a set that keeps items' occurrence counts  Does not implement Set, hence the lower-case s o Normally implemented as Map