Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Pink & Squishy: Fun with Guava #1

Pink & Squishy: Fun with Guava #1

An ongoing series of presentations I made to show my workmates the wonders of Guava in a JRuby environment.

Chris Jester-Young

December 31, 2010
Tweet

More Decks by Chris Jester-Young

Other Decks in Programming

Transcript

  1. 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)
  2. 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!
  3. 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}
  4. 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
  5. 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)
  6. 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)
  7. 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]}
  8. 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}
  9. 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]
  10. 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<K, Collection<V>> 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<T, AtomicInteger>