This document provides an introduction and overview of the Google Guava libraries. It describes what Guava is, why developers would use it, how it compares to Apache Commons libraries, its design principles and release cycles. It provides descriptions of some key Guava packages and classes for common Java utilities, including Preconditions, Optional, Objects, Strings, Charsets, CaseFormat, CharMatcher, Joiner and Splitter. The document aims to explain the purpose and usage of important Guava functionality.
4. What’s Guava?
• Open source version of Google's core Java libraries
• […] Carefully designed, tested, optimized and used in
production at Google
• These utilities relate to: collections, concurrency, primitives,
reflection, comparison, I/O, hashing, networking, strings,
math, in-memory caching, in-memory publish/subscribe...
and various basic data types.
• The “JDK-plus”! (JDK 6+)
• Apache License 2.0
https://code.google.com/p/guava-libraries/wiki/PhilosophyExplained
5. Why Guava?
• Guava’s goal is for developer to write less code.
• And for the code you do write to be simpler,
cleaner, and more readable.
• Battle tested in production at Google
– Staggering numbers of unit tests: 286,000 as of July
2012 (generated)
• Under active development and has a strong,
vocal, and involved user base
https://code.google.com/p/guava-libraries/wiki/PhilosophyExplained
6. Guava vs. Apache Commons
• Guava is more “mordern”
– Guava greatly benefits from the Java 5 features: generics, varargs, enums, and
autoboxing
• Guava is very well designed / documented
– factory methods (such as ImmutableList.copyOf())
– builder pattern (ImmutableList.builder(), Joiner, CharMatcher, Splitter ...)
– immutability (immutable collections, CharMatcher, Joiner, Splitter,...)
– implementation hiding (Predicates.xXx, ...)
– favoring composition over inheritance(the ForwardXXX collections)
– null-checks
– enum-singleton pattern
– serialization proxies
– well thought-out naming conventions
• Guava is consistent
• Guava is in active development
tinyurl.com/guava-vs-apache
7. Guava Design Principles
• There should always be some use case for which the API is clearly
the best solution possible.
• The semantics of methods and classes should be obvious and
intuitive from their signatures, as opposed to "smart."
• Encourage good code habits in Guava users, and exemplify good
code habits ourselves in Guava source.
• Don't try to address every use case individually
• Emphasize maintainability, and leave room for future refactorings.
8. Guava Release
• Every 3 months, with significant
new functionality and fixes.
• Posted 14.0 last month. (in maven
central: com.google.guava:guava:14.0)
• Guava's classes and methods are
a mixture of API-frozen and
non-API-frozen (marked with
@Beta).
• So all releases are either major
or patch releases; never minor.
https://code.google.com/p/guava-libraries/wiki/ReleaseHistory
11. Preconditions (1/3)
• Useful for validation
• Recommended to be used as static imports
Each method has three variants:
• No extra arguments
• An extra object. Exception is obj.toString()
• An extra String & Objects. String.format like
but only allows %s (GWT compat)
12. Preconditions (2/3) - Examples
import static com.google.common.base.Preconditions.*;
// Before
public Period(Date start, Date end) {
if (null == start || null == end) {
throw new NullPointerException(“Dates cannot be null”);
}
if (start.after(end)) {
throw new IllegalArgumentException(“Start cannot be after end”);
}
this.start = start;
this.end = end;
}
// After
public Period (Date start, Date end) {
this.start = checkNotNull(start, “Start cannot be null”);
this.end = checkNotNull(start, “End cannot be null”);
checkArguments(start.after(end), “Start cannot be after end”);
}
http://www.slideshare.net/alexkorotkikh/google-guava-12991826
13. Preconditions (3/3)
• checkArgument(boolean)
– Throws IllegalArgumentException if false
– Used to validate method arguments
• checkNotNull(T)
– Throws NullPointerException if null
– Returns the value. Can be used inline
• checkState(boolean)
– Throws IllegalStateException if false
– Used to check object state
• checkElementIndex(index,size)
– Throws IndexOutOfBoundsException
– Interval [0, size) (exclusive)
• checkPositionIndex(index,size)
– Throws IndexOutOfBoundsException
– Interval [0, size] (inclusive)
14. Optional<T>
An immutable wrapper that is either present(contains a non-null
reference ) or absent(contains nothing) but it never "contains null“.
Optional
Similar to Scala’s Option type
Absent Present
Possible uses:
• return type (vs. null): "a T that must be present“ vs. "a T that might be
absent"
• distinguish between
– "unknown" (for example, not present in a map)
– "known to have no value" (present in the map, with value Optional.absent())
• wrap nullable references for storage in a collection that does not support
null
See the documentation on com.google.common.base.Optional.
http://www.slideshare.net/savu.andrei/guava-overview-part-1-bucharest-jug-1
15. Optional<T>
• Creating an Optional<T>
• Optional.of(notNull);
• Optional.absent();
• Optional.fromNullable(maybeNull);
• Unwrapping an Optional<T>
• mediaType.charset().get(); // throws IllegalStateException if absent
• mediaType.charset().or(Charsets.UTF_8);
• mediaType.charset().or(costlySupplier);
• mediaType.charset().orNull();
• Other Useful methods
mediaType.charset().asSet(); // 0 or 1
mediaType.charset().transform(stringFunc);
16. Objects
Useful methods provided by Objects
• Objects.firstNonNull(a, b): return the first non-null object or throw NPE
• Objects.equal(a, b): determines whether two possibly-null objects are
equal
• Objects.hashCode(objects...): generates a hash code for multiple values
• Objects.toStringHelper(): Makes implementing Object.toString() cleaner
The Objects class in JDK 7 or higher provides the equivalent Objects.equals
and Objects.hash(Object...) methods.
See the documentation on com.google.common.base.Objects and Guava's
utilities for implementing common object methods, explained
18. Strings
Charsets
There are six standard charsets guaranteed to be implemented in
every JVM.
But still there's lots of code like:
try {
bytes = string.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new AssertionError(e); // how can this possibly happen?
}
Do this instead:
bytes = string.getBytes(Charsets.UTF_8);
See the documentation on com.google.common.base.Charsets.
http://www.slideshare.net/tomaszdziurko/google-guava-almost-everything-you-need-to-know
19. Strings
CaseFormat
A handy little class for converting between ASCII case conventions
Supported formats include:
• LOWER_CAMEL: lowerCamel
• LOWER_HYPHEN: lower-hyphen
• LOWER_UNDERSCORE: lower_underscore
• UPPER_CAMEL: UpperCamel
• UPPER_UNDERSCORE: UPPER_UNDERSCORE
CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, "CONSTANT_NAME"));
// -> "constantName"
See the documentation on com.google.common.base.CaseFormat.
20. Strings
CharMatcher
• What's a matching character?
– WHITESPACE, ASCII, ANY (many pre-defined sets)
– .is('x'), .isNot('_'), .oneOf("aeiou"), .inRange('a', 'z')
– Or subclass CharMatcher, implement matches(char)
• What to do with those matching characters?
– matchesAllOf, matchesAnyOf, matchesNoneOf
– indexIn, lastIndexIn, countIn
– removeFrom, retainFrom
– trimFrom, trimLeadingFrom, trimTrailingFrom
– collapseFrom, trimAndCollapseFrom, replaceFrom
• Example (scrub a user ID):
CharMatcher.DIGIT.or(CharMatcher.is('-')).retainFrom(userInput);
21. Strings
CharMatcher
• Scrubbing a user ID from user input:
private static final CharMatcher ID_MATCHER = CharMatcher.DIGIT.or(CharMatcher.is('-'));
// ...
ID_MATCHER.retainFrom("54-74-90not_a_digit-2014");
// -> "54-74-90-2014"
• Replace all digits with asterisks:
CharMatcher.JAVA_DIGIT.replaceFrom("54-74-90not_a_digit-2014", "*");
// -> "**-**-**not_a_digit-****"
See the documentation on com.google.common.base.CharMatcher.
22. Strings
CharMatcher - Predefined
CharMatcher.JAVA_ISO_CONTROL.removeFrom(string);
// remove control characters
CharMatcher.DIGIT.retainFrom(string);
// keep only the digits
CharMatcher.ASCII.retainFrom(string);
// keep only ASCII (code is less than 128) characters
CharMatcher.JAVA_DIGIT.replaceFrom(string, "*");
// star out all digits
CharMatcher.JAVA_DIGIT.or(CharMatcher.JAVA_LOWER_CASE).retainFrom
(string);
// keep only digits or lowercase
23. Strings
CharMatcher – Factory methods
CharMatcher.anyOf("2468").replaceFrom("123456789", "*")
//star out all even numbers. Output - 1*3*5*7*9
CharMatcher.noneOf("2468").replaceFrom("123456789", "*")
// star out all non-even numbers. Output - *2*4*6*8*
CharMatcher.inRange('a', 'z').or(inRange('A', 'Z'))
CharMatcher.is('x‘)
// matches only the character ‘x’
CharMatcher.isNot('_')
// matches any character except the ‘_’.
24. Strings
Joiner
Joiner concatenates strings using a delimiter
• throws a NPE on null objects, unless:
– .skipNulls()
– .useForNull(String)
private static final Joiner JOINER = Joiner.on(", ").skipNulls();
JOINER.join(null, "Kurt", "Kevin", null, "Chris");
// -> "Kurt, Kevin, Chris"
• also handle maps
static final MapJoiner MAP_JOINER = Joiner.on("; ")
.useForNull("NODATA")
.withKeyValueSeparator(":");
// Map { "foo": "bar", "quux": null } -> "foo: bar; quux: NODATA"
See the documentation on com.google.common.base.Joiner and
Guava's string utilities, explained.
25. Strings
String Splitting quiz
• Question: What does this return?
" foo, ,bar, quux,".split(",");
• Answer:
① [" foo", " ", "bar", " quux"]
② ["foo", "bar", "quux"]
③ ["foo", "", "bar", "quux"]
④ [" foo", " ", "bar", " quux", ""]
• We probably want ["foo", "bar", "quux"]. How do we
get it?
Splitter.on(',')
.trimResults()
.omitEmptyStrings()
.split(" foo, ,bar, quux,");
// -> ["foo", "bar", "quux"]
26. Strings
Splitter
Splitter divides strings into substrings with a delimiter
• A better, more intuitive String.split()
– doesn't silently discard trailing separators
– handles empty pieces predictably
• By default, assumes nothing about whitespace
– .trimResults()
– .omitEmptyStrings()
private static final Splitter SPLITTER = Splitter.on(',').trimResults();
SPLITTER.split("Kurt, Kevin, Chris");
// yields: ["Kurt", "Kevin", "Chris"]
See the documentation on com.google.common.base.Splitter and
Guava's string utilities, explained.
27. StopWatch
Prefer Stopwatch over System.nanoTime()
(and definitely over currentTimeMillis()!)
exposes relative timings, not absolute time
alternate time sources can be substituted using
Ticker (read() returns nanoseconds)
toString() gives human readable format
Stopwatch stopwatch = new Stopwatch().start();
stopwatch.start();
doSomeOtherOperation();
long nanos = stopwatch.elapsedTime(TimeUnit.NANOSECONDS);
See the documentation on com.google.common.base.Stopwatch.
29. Throwables(2/3) - Propagation
“Guava provides several utilities to simplify propagating exceptions”
• propagate(Throwable)
Propagates the throwable as-is if it is a RuntimeException or an Error, or wraps it
in a RuntimeException and throws it otherwise.
• propagateIfInstanceOf(Throwable,Class<X extends Exception>)
Propagates the throwable as-is, if and only if it is an instance of X
• propagateIfPossible(Throwable)
Throws throwable as-is only if it is a RuntimeException or an Error.
• propagateIfPossible(Throwable, Class<X extends Throwable>)
Throws throwable as-is only if it is a RuntimeException or an Error, or an X.
30. Throwables(3/3) – Casual Chain
“Guava makes it somewhat simpler to study the causal
chain of an exception, providing three useful methods
whose signatures are self-explanatory”
• getRootCause(Throwable)
• getCausalChain(Throwable)
• getStackTraceAsString(Throwable)
31. Functional Programming
Function
Function<F, T>
• one way transformation of F into T
• T apply(F input)
• most common use: transforming collections (view)
See the documentation on com.google.common.base.Function and
Functional idioms in Guava, explained.
The com.google.common.base.Functions class provides common
functions and related utilites.
http://www.slideshare.net/tomaszdziurko/google-guava-almost-everything-you-need-to-know
33. Functional Programming
Predicate
Predicate<F>
• determines true or false for a given F
• boolean apply(F input)
• most common use: filtering collections (view)
See the documentation on com.google.common.base.Predicate and
Functional idioms in Guava, explained.
The com.google.common.base.Predicates class provides common
predicates and related utilites.
http://www.slideshare.net/tomaszdziurko/google-guava-almost-everything-you-need-to-know
34. Functional Programming
Predicates
There are considerably more construction and
manipulation methods available in Predicates
• instanceOf(Class)
• assignableFrom(Class)
• contains(Pattern)
• in(Collection)
• isNull()
• alwaysFalse()
• alwaysTrue()
• equalTo(Object)
• compose(Predicate, Function)
• and(Predicate…)
• or(Predicate…)
• not(Predicate…)
35. Functional Programming
Functional Examples
Predicate activeClients = new Predicate() {
public boolean apply(Client client) {
return client.activeInLastMonth();
}
};
// Returns an immutable list of the names of
// the first 10 active clients in the database.
FluentIterable.from(database.getClientList())
.filter(activeClients) // Predicate
.transform(Functions.toStringFunction()) // Function
.limit(10) .toImmutableList();
36. Utility Classes
Other useful classes in com.google.common.base are:
• Ascii: Static methods and constants pertaining to ASCII characters
• Strings: nullToEmpty, isNullOrEmpty, common{Prefix, Suffix}
• Enums: getIfPresent, valueOfFunction
• Throwables: getStackTraceAsString, getCausalChain, propagateIfIns
tanceOf
• Suppliers: memoizeWithExpiration, ofInstance
• Equivalence: A strategy for determining whether two instances are
considered equivalent
38. Primitives
A package that helps you work with Java's primitive types.
If you need help doing a primitive task:
① Check the wrapper class (e. g. java.lang.Integer)
② Check java.util.Arrays
③ Check com.google.common.primitives
④ It might not exist! (Write it yourself)
39. Primitives
• com.google.common.primitives contains utility classes for all
primitives, like Booleans, Bytes, Chars, Doubles, Floats, Ints, Longs,
and Shorts.
• Each has the exact same structure (but has only the subset of
operations that make sense for its type).
• Depending on the primitive type, useful methods like: {checked,
saturated}Cast, contains, indexOf, min, max, join, fromByteArray
• There are also alternate versions of some primitive types
like UnsignedLong orUnsignedInteger with corresponding utility
classes.
• Also see Guava's primitives utilities, explained.
40. Primitives - Utilities
• Guava provides a number of these general-purpose
utilities
Primitive Type Guava Utilities
byte Bytes, SignedBytes, UnsignedBytes
short Shorts
int Ints, UnsignedInteger, UnsignedInts
long Longs, UnsignedLong, UnsignedLongs
float Floats
double Doubles
char Chars
boolean Booleans
42. Immutable collections
New collection types
Utility Classes
COM.GOOGLE.COMMON.COLLECT
GUAVA'S EXTENSIONS TO THE JDK COLLECTIONS
ECOSYSTEM. THESE ARE SOME OF THE MOST MATURE AND
POPULAR PARTS OF GUAVA.
43. Guava Collections
What's inside of com.google.common.collect?
• Immutable Collections
• New collection types: Multimap, Multiset, BiMap, Table…
• Forwarding collections, Constrained collections
• Comparator-related utilities like ComparisonChain
• Stuff similar to Apache Commons Collections (but with
consequent support for Generics)
• Some functional programming support (filter, transform, etc.)
46. Why immutable?
• Safe for use by untrusted libraries
• Thread-safe
• More efficient, time & space (analysis)
• Can be used as a constant
• Immutable vs. unmodifiable
– Very easy to use
– Slightly faster
– Use less memory
• Sometimes far less (ImmutableSet, factor of 2~3x)
47. How to create immutable
Immutable** can be created in several ways:
• copyOf(T): e.g. ImmutableSet.copyOf(set)
• of(elements): e.g. ImmutableMap.of(“a”,”b”)
• using a Builder:
public static final ImmutableSet<Color> GOOGLE_COLORS =
ImmutableSet.<Color>builder()
.addAll(WEBSAFE_COLORS)
.add(new Color(0, 191, 255))
.build();
All collections support asList(const. time view)
49. Multiset
• a set of counters; also called a "bag"
– counts the # of times each unique value was added
– meant to replace Map<K, Integer>
– implementations: HashMultiset,LinkedHashMultiset,TreeMultiset
// convention: construct using create() method
Multiset<String> mset = HashMultiset.create();
"the"=7
"if"=2 "of"=1
mset.count("to") "to"=3
"down"=1 "from"=4 3
set.count("boo") "by"=2 "she"=2 0
set.contains("boo") "in"=5 "you"=4 false
"him"=2
multiset
See also com.google.common.collect.Multiset
50. Multiset methods
class.create() creates a new empty multiset,
class.create(collection) or one based on the elements of a collection
add(value) adds 1 occurrence of value to collection; or
add(value, count) adds the given # of occurrences
contains(value) true if set contains ≥ 1 occurrence of value
count(value) returns # of occurrences of value; 0 if not
found
iterator() an object to examine all values in the set
remove(value) removes 1 occurrence of the given value; or
remove(value, count) removes the given # of occurrences
setCount(value, count) causes the given value to have the given count
size() returns sum of all counts
toString() string such as "[a x 4, b x 2, c]"
elementSet(), entrySet() collection views of the multiset
51. Multimap
• a map from keys to collections of values
– meant to replace Map<K, Set<V>> or Map<K, List<V>>
– implementations: ArrayListMultimap, LinkedListMultimap,
HashMultimap, LinkedHashMultimap, TreeMultimap
// political party -> people in it
Multimap<String, String> mmap = TreeMultimap.create();
mmap.put("D", "Gore");
mmap.put("D", "Clinton");
"R" [Obama, Kerry, Gore, Clinton]
"D" [Paul, Johnson]
"I" [Romney, McCain, Bush]
keys
values
See also com.google.common.collect.Multimap
52. Multimap methods
class.create() creates a new empty multimap,
class.create(map) or one based on the elements of a map
clear() removes all key/value pairs
containsKey(key) returns true if the given key is stored
get(key) returns collection of values associated with key
put(key, value) adds value to this key's collection
putAll(key, collection) adds all given values to this key's collection
remove(key, value) removes value from this key's collection
removeAll(key) removes all values associated with this key
size() returns number of key/value pairs
toString() string such as "{a=[b, c], d=[e]}"
asMap(), keys(), keySet(), various collection views of the map's data
values()
53. Choosing a Multimap
• The Multimap has two sub-ADT interfaces:
– ListMultimap ArrayListMultimap, LinkedListMultimap
– SetMultimap Hash, LinkedHash, TreeMultimap
• If you need list-specific methods, declare it as a
ListMultimap.
ListMultimap<String, String> mmap =
ArrayListMultimap.create();
mmap.put("D", "Gore");
mmap.put("D", "Clinton");
System.out.println(mmap.get("D").get(0); // Gore
System.out.println(mmap.get("D").get(1); // Clinton
54. BiMap(Bidirectional Map)
• a two-directional map
– for data where a b and also b a in symmetry
– avoids need to try to "invert" a map or store an inverse map
– implementations: HashBiMap
// state <--> state capital
BiMap<String, String> bmap = HashBiMap.create();
mmap.put("Arizona", "Phoenix");
mmap.put("Washington", "Olympia");
"Washington" "Sacramento"
"California" "Phoenix"
"Arizona" "Olympia"
keys values
See also com.google.common.collect.BiMap
55. Bimap Methods
• all methods from Map are present as well
– clear, containsKey, containsValue, equals, get,
isEmpty, keySet, put, putAll, remove, size, toString
class.create() creates a new empty bi-map,
class.create(map) or one based on the elements of a map
inverse() returns BiMap<V, K> in opposite direction
values() returns set of all values
56. Table
• a two-dimensional (key+key) / value structure
– meant to replace Map<R, Map<C, V>>
– a map stores pairs of form (K, V) where only K is known later;
a table stores triples of form (R, C, V) where R,C are known later
– implementations: HashBasedTable, TreeBasedTable,
ArrayTable
// (name + SSN => age)
Table<String, String, Integer> table =
TreeBasedTable.create();
table.put("Marty Stepp", "597-24-6138", 29);
name SSN age
Marty Stepp 597-24-6138 29
Stuart Reges 703-34-1593 84
See also com.google.common.collect.Table
57. Table Methods
class.create() creates a new empty table, etc.
cellSet() set of all (R, C, V) triples
clear() remove all values
column(C) returns column for given key as Map<R,V>
contains(R, C) true if table has a mapping for the given keys
containsRow(R), true if table has any mapping that includes the
containsColumn(C) given row or column key
get(R, C) returns value for the given keys, or null
isEmpty() true if there are no values
put(R, C, V) stores (R, C, V) triple in the table
putAll(table) adds all of the given table's data to this one
remove(R, C) removes any value mapped from the given keys
row(R) returns row for given key as a Map<C,V>
size() number of triples in table
toString() string such as "{a={b=c, d=e},f={g=h}}"
58. RangeSet
• a group of comparable ranges of values
– like a set, but you can add an entire range at a time
– implementations: TreeRangeSet
// teenagers and old people
RangeSet<Integer> ages = TreeRangeSet.create();
ages.add(Range.closed(13, 19));
ages.add(Range.atLeast(65));
System.out.println(rset.contains(15)); // true
System.out.println(rset.contains(72)); // true
<0 0 ... 12 13 ... 19 20 ... 64 ≥ 65 ...
See also com.google.common.collect.RangeSet
59. Specifying ranges
• Specify a range of values by calling static methods of the Range
class, each of which returns a Range object.
Range.closed(min, max) [min .. max] including both endpoints
Range.open(min, max) (min .. max) excluding min and max
Range.closedOpen(min, max) [min .. max) include min, exclude max
Range.openClosed(min, max) (min .. max] exclude min, include max
Range.atLeast(min) [min .. ∞) including min
Range.greaterThan(min) (min .. ∞) excluding min
Range.atMost(max) (-∞ .. max] including max
Range.lessThan(max) (-∞ .. max) excluding max
Range.all() all possible values, (-∞ .. ∞)
Range.singleton(value) [value]; just a single value
See also com.google.common.collect.Range
60. RangeSet Methods
class.create() creates a new empty range set, etc.
add(range) adds the given range of values
addAll(rangeset) adds all ranges from the given set
clear() removes all ranges
encloses(range) true if set contains the entire given range
enclosesAll(rangeset) true if set contains all ranges in given set
isEmpty() true if there are no ranges
remove(range) removes the given range of values
span() a Range representing all values in this set
subRangeSet(range) subset containing relevant ranges
toString() string such as "[1..3], (6..65]"
61. RangeMap
• like a range set, but stores (range, value) pairs
– implementations: TreeRangeMap
// body mass index -> description
RangeMap<Double, String> bmi =
TreeRangeMap.create();
bmi.put(Range.lessThan(18.5), "underweight");
bmi.put(Range.closedOpen(18.5, 25.0), "normal");
bmi.put(Range.closedOpen(25.0, 30.0), "overweight");
bmi.put(Range.atLeast(30.0), "obese");
System.out.println(bmi.get(27.1)); // "overweight"
< 18.5 18.5 .. 25.0 25.0 .. 30.0 ≥ 30.0
underweight normal overweight obese
See also com.google.common.collect.RangeMap
62. RangeMap Methods
class.create() creates a new empty range map, etc.
put(range, value) adds range/value pair
putAll(rangemap) adds all range/value pairs from given map
clear() removes all ranges
get(key) returns value for range containing key
isEmpty() true if there are no ranges
remove(range) removes all values in the given range
span() a Range representing all keys in this set
subRangeMap(range) submap containing relevant ranges
toString() string such as "{[1..3]=a, (6..65]=b}"
63. Other Cool Features
Static Constructors
Iterables
FluentIterable
MapMaker
Forwarding Decorators
Peeking Iterator
Abstract Iterator
Ordering
UTILITY CLASSES
64. Other Cool Features
• Collections2: utility methods related to all collections
• Lists: utility methods related to lists
• Sets: utility methods related to sets
• Queues: utility methods related to queues
• Multisets, Multimaps: utility methods related to multiset/map
• Tables: utility methods related to tables
• Iterables: utility methods related to collections and for-each
• Iterators: utility methods related to iterators and iteration
• Ranges: utility methods related to range/rangeset/rangemap
• Ordering: easy-to-create comparable and comparator orders
See also Guava's static collections utilities, explained.
65. Static Constructors
• Before
List<TypeThatsTooLongForItsOwnGood> list = new ArrayList<TypeThatsTooLongForItsOwnGood>();
• After
List<TypeThatsTooLongForItsOwnGood> list = Lists.newArrayList();
Map<KeyType, LongishValueType> map = Maps.newLinkedHashMap();
• Initialize collections with their starting elements very conveniently
Set<Type> copySet = Sets.newHashSet(elements);
List<String> theseElements = Lists.newArrayList("alpha", "beta", "gamma");
66. Iterables
• Helper class to work with classes implementing Iterable
• The overwhelming majority of operations in the Iterables class
are lazy
• There is a ”clone” class: Iterators with almost the same methods
as Iterables but working with Iterators
• Examples:
Iterable<Integer> concatenated = Iterables.concat(
Ints.asList(1, 2, 3),
Ints.asList(4, 5, 6));
// concatenated has elements 1, 2, 3, 4, 5, 6
String lastAdded = Iterables.getLast(myLinkedHashSet);
String theElement = Iterables.getOnlyElement(thisSetIsDefinitelyASingleton);
// if this set isn't a singleton, something is wrong!
68. FluentIterable
FluentIterable is a rich interface for manipulating Iterable instances in a
chained fashion.
• Chaining (returns FluentIterable): skip, limit, cycle, filter, transform
• Querying (returns boolean): allMatch, anyMatch, contains, isEmpty
• Converting: to{List, Set, Map, SortedSet, SortedList}, toArray
• Extracting: first, last, firstMatch (returns Optional<E>), get (returns E)
Examples:
FluentIterable
.from(database.getClientList())
.transform(Functions.toStringFunction())
.limit(10)
.toList();
See also com.google.common.collect.FluentIterable.
69. MapMaker
• MapMaker is one of the jewels of com.google.common.collect.
• A builder of ConcurrentMap instances having any combination of
certain features.
ConcurrentMap<User, RecGraph> recommendations =
new MapMaker()
.concurrencyLevel(4)
.weakKeys()
.expiration(10, TimeUnit.MINUTES)
.makeComputingMap(
new Function<User, RecGraph>() {
public RecGraph apply(User user) {
return createExpensiveGraph(user);
}
}
);
• See documentation on com.google.common.collect.MapMaker.
70. Forwarding Decorators
• For all the various collection interfaces, Guava provides
Forwarding abstract classes to simplify using the decorator
pattern.
class AddLoggingList<E> extends ForwardingList<E> {
final List<E> delegate; // backing list
@Override protected List<E> delegate() {
return delegate;
}
@Override public void add(int index, E elem) {
log(index, elem);
super.add(index, elem);
}
@Override public boolean add(E elem) {
return standardAdd(elem); // implements in terms of add(int, E)
}
@Override public boolean addAll(Collection<? extends E> c) {
return standardAddAll(c); // implements in terms of add
}
}
72. Peeking Iterator
• a subtype of Iterator that lets you peek() at the element
• Iterators supports the method Iterators.peekingIterator(Iterator),
which wraps an Iterator and returns a PeekingIterator
• Remove consecutive duplicates:
List<E> result = Lists.newArrayList();
PeekingIterator<E> iter = Iterators.peekingIterator(source.iterator());
while (iter.hasNext()) {
E current = iter.next();
while (iter.hasNext() && iter.peek().equals(current)) {
// skip this duplicate element
iter.next();
}
result.add(current);
}
73. Abstract Iterator
• Implementing your own Iterator.
• Implement only one method, computeNext()
• wrap an iterator so as to skip null values:
public static Iterator<String> skipNulls(final Iterator<String> in) {
return new AbstractIterator<String>() {
protected String computeNext() {
while (in.hasNext()) {
String s = in.next();
if (s != null) {
return s;
}
}
return endOfData();
}
};
}
• Note: AbstractIterator extends UnmodifiableIterator, which forbids the
implementation of remove(). If you need an iterator that supports remove(), you
should not extend AbstractIterator.
74. Ordering(1/4)
Ordering is Guava’s “fluent” Comparator
class, which can be used to manipulate,
extend, and make use of comparators.
Quick examples:
Comparator<String> comparator = new Comparator<String>() {
public int compare(String left, String right) {
return Ints.compare(left.length(), right.length());
}
};
List<String> list = Lists.newArrayList(“1”, “2”, “3”);
if (Ordering.from(comparator).reverse().isOrdered(list)){…}
75. Ordering(2/4) - Creation
Using static factory methods:
• natural(): uses the natural ordering on Comparable types
• usingToString(): Compares Objects by the lexicographical
ordering of their string representations
• arbitary(): Returns an arbitrary ordering over all objects
• from(Comparator): Making a preexisting Comparator into
an Ordering
76. Ordering(3/4) - Manipulation
Ordering can be modified to obtain many other useful
derived orderings
• reverse()
• compound(Comparator)
• onResultOf(Function)
• nullsFirst()
• nullsLast()
• lexicographical()
– (yields an Ordering<Iterable<T>>!)
77. Ordering(4/4) - Application
“Guava provides a number of methods to manipulate or
examine values”
• immutableSortedCopy(Iterable)
• isOrdered(Iterable)
• isStrictlyOrdered(Iterable)
• min(Iterable)
• max(Iterable)
• leastOf(int, Iterable)
• greatestOf(int, Iterable)
Some are even optimized for the specific kind of comparator
you have.
79. Concurrency libraries
First learn the contents of java.util.concurrent.
Then check out guava concurrency libraries:
• ListenableFuture<V>, ListeningExecutorService
• CheckedFuture<V, X>
• Service, ServiceManager
• RateLimiter
• ThreadFactoryBuilder
• MoreExecutors
• AtomicLongMap<K>
• AtomicDouble
• Uninterruptibles
• ...
80. Monitor
Synchronization with Monitor
• Monitor is a synchronization construct
that can be used anywhere you would
use a ReentrantLock.
• Only one thread can occupy a monitor at
any time.
• operations of entering and leaving which
are semantically the same as
the lock and unlock operations in
ReentrantLock
http://codingjunkie.net/google-guava-synchronization-with-monitor/
81. Monitor
ReenterantLock vs. Monitor
http://codingjunkie.net/google-guava-synchronization-with-monitor/
82. Monitor
Monitor Usage Guidelines
• Basic Case
• Condition Case
Methods Descriptions
tryEnterIf Enters this monitor if it is possible to do so immediately and the guard is satisfied. Does
not block acquiring the lock and does not wait for the guard to be satisfied.
enterIf Enters this monitor if the guard is satisfied. Blocks indefinitely acquiring the lock, but does
not wait for the guard to be satisfied.
enterWhen Enters this monitor when the guard is satisfied. Blocks indefinitely, but may be interrupted.
83. ListenableFuture – What?
• Future with one new method:
addListener(Runnable, Executor)
• When the future is done (success,
exception, cancellation), the listener
runs
84. ListenableFuture – Why?
• Callbacks?
service.process(request).addListener(new Runnable() {
public void run() {
try {
Result result = Futures.makeUninterruptible(future).get();
// do something with success |result|
} catch (ExecutionException ee) {
// do something with failure |ee.getCause()|
} catch (RuntimeException e) {
// just to be safe
}
}
}, executor);
service.process(new AsyncCallback<Result>() {
public void success(Result result) {
// do something with success |result|
}
public void failure(Exception e) {
// do something with failure |e|
}
}, executor);
86. ListenableFuture – When?
• (+) Most Futures methods require it.
• (+) It's easier than changing to ListenableFuture
later.
• (+) Providers of utility methods won't need to
provide Future and ListenableFuture variants of
their methods.
• (−) "ListenableFuture" is lengthier than "Future."
• (−) Classes like ExecutorService give you a plain
Future by
• default.
87. ListenableFutuere – How?
• Create ListenableFuture instead of plain
Future:
• ExecutorService.submit(Callable) ➜
– Call MoreExecutors.listeningDecorator on
your executor.
• MyFutureTask.set(V) ➜
– Use SettableFuture.
88. ListenableFuture Example
ListeningExecutorService service = MoreExecutors.listeningDecorator(
Executors.newFixedThreadPool(10));
ListenableFuture<Explosion> explosion = service.submit(new Callable<Explosion>() {
public Explosion call() {
return pushBigRedButton();
}
});
Futures.addCallback(explosion, new FutureCallback<Explosion>() {
// we want this handler to run immediately after we push the big red button!
public void onSuccess(Explosion explosion) {
walkAwayFrom(explosion);
}
public void onFailure(Throwable thrown) {
battleArchNemesis(); // escaped the explosion!
}
});
89. Futures
ListenableFuture<RowKey> rowKeyFuture = indexService.lookUp(query);
AsyncFunction<RowKey, QueryResult> queryFunction =
new AsyncFunction<RowKey, QueryResult>() {
public ListenableFuture<QueryResult> apply(RowKey rowKey) {
return dataService.read(rowKey);
}
};
ListenableFuture<QueryResult> queryFuture = Futures.transform(rowKeyFuture, queryFunction, queryExecutor);
Method Description
transform(ListenableFuture<A>, A Returns a new ListenableFuture whose result is the product of applying the given AsyncFunctio
syncFunction<A, B>, Executor) n to the result of the givenListenableFuture.
transform(ListenableFuture<A>, F Returns a new ListenableFuture whose result is the product of applying the given Function to th
unction<A, B>, Executor) e result of the givenListenableFuture.
allAsList(Iterable<ListenableFuture Creates a new ListenableFuture whose value is a list containing the values of all its input futures,
<V>>) if all succeed. fails if any input fails
successfulAsList(Iterable<Listenabl Creates a new ListenableFuture whose value is a list containing the values of all its successful in
eFuture<V>>) put futures. succeeds, with null in place of failures
90. Service
• An object with an operational state, with
methos start and stop.
• e.g. web servers, RPC servers, monitoring
initialization, ...
91. Service - Lifecycle
• Lifecycle
– Service.State.NEW
– Service.State.STARTING
– Service.State.RUNNING
– Service.State.STOPPING
– Service.State.TERMINATED
• On Failure:
– Service.State.FAILED
A stopped service may not be restarted
93. Service – AbstractIdleService
• AbstractIdleService
– skeleton implements a Service which does
not need to perform any action while in the
"running" state
protected void startUp() {
servlets.add(new GcStatsServlet());
}
protected void shutDown() {}
94. Service -
AbstractExecutionThreadService
• AbstractExecutionThreadService
– performs startup, running, and shutdown actions in
a single thread.
protected void startUp() {
dispatcher.listenForConnections(port, queue);
}
protected void run() {
Connection connection;
while ((connection = queue.take() != POISON)) {
process(connection);
}
}
protected void triggerShutdown() {
dispatcher.stopListeningForConnections(queue);
queue.put(POISON);
}
95. Service -
AbstractScheduledService
• AbstractScheduledService
– performs some periodic task while running
– Similar to AbstractionThreadService
• Override runOneIteration()
• Implement scheduler()
– newFixedRateSchedule
– newFixedDelaySchedule
96. Concurrency libraries
First learn the contents of
java.util.concurrent.
Then check out guava concurrency libraries:
• CheckedFuture<V, X>
• Service, ServiceManager
• RateLimiter
• ThreadFactoryBuilder
• AtomicLongMap<K>
• AtomicDouble
• Uninterruptibles
• ...
97. Why a new hashing API?
JDK solution
Hashing Overview
Bloom Filter
COM.GOOGLE.COMMON.HASH
TOOLS FOR MORE SOPHISTICATED HASHES THAN WHAT'S
PROVIDED BY OBJECT.HASHCODE(), INCLUDING BLOOM FILTERS
98. Why a new hashing API?
• Object.hashCode() implementations tend to be very
fast, but:
– Strictly limited to 32 bits
– Worse, composed hash codes are "collared" down to
32bits during the computation
– No separation between "which data to hash" and "which
algorithm to hash it with"
– Implementations have very bad bit dispersion
• These make it not very useful for a multitude of
hashing applications: a document "fingerprint",
cryptographic hashing, cuckoo hashing, Bloom
filters...
99. JDK solution
To address this shortcoming, the JDK introduced
two interfaces:
– java.security.MessageDigest
– java.util.zip.Checksum
Each named after a specific use case for hashing.
Worse than the split: neither is remotely easy to
use when you aren't hashing raw byte arrays.
100. Guava Hashing Example
HashFunction hf = Hashing.murmur3_128();
HashCode hc = hf.newHasher()
.putLong(id)
.putInt(age)
.putString(name)
.putBytes(someBytes)
.putObject(person, personFunnel)
.hash();
HashCode has asLong(), asBytes(), toString()...
Or put it into a Set, return it from an API, etc.
(It also implements equals() in a special way.)
See the documentation on com.google.common.hash.HashCode and
com.google.common.hash.Hashing.
101. Hashing Overview
The com.google.common.hash API offers:
• A unified user-friendly API for all hash functions
• Seedable 32- and 128-bit implementations of
murmur3
• md5(), sha1(), sha256(), sha512(), murmur3_128(),
murmur3_32() adapters
– change only one line of code to switch between these
and murmur etc.
• goodFastHash(int bits), for when you don't care what
algorithm you use
• General utilities for HashCode instances, like
combineOrdered / combineUnordered
102. BloomFilter
A probabilistic set.
• public boolean mightContain(T);
– true == "probably there"
– false == "definitely not there"
WHY? Consider a spell-checker:
– If syzygy gets red-underlined, that's annoying
– But if yarrzcw doesn't get red-underlined... oh well!
– And the memory savings can be very large
Primary use: short-circuiting an expensive boolean query
BloomFilter<Person> friends = BloomFilter.create(personFunnel, 500, 0.01);
for(Person friend : friendsList) {
friends.put(friend);
}
// much later
if (friends.mightContain(dude)) {
// the probability that dude reached this place if he isn't a friend is 1%
// we might, for example, start asynchronously loading things for dude while we do a more
expensive exact check
}
103. Immutable collections
New collection types
Powerful collection utilities
Extension utilities
COM.GOOGLE.COMMON.CACHE
LOCAL CACHING, DONE RIGHT, AND SUPPORTING A WIDE
VARIETY OF EXPIRATION BEHAVIORS.
104. Caching
• Guava has a powerful on-heap key→value cache.
LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.removalListener(MY_LISTENER)
.build(
new CacheLoader<Key, Graph>() {
public Graph load(Key key) throws AnyException {
return createExpensiveGraph(key);
}
});
105. Caches – Population
• From CacheLoader
LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
.maximumSize(1000)
.build( new CacheLoader<Key, Graph>() {
public Graph load(Key key) throws AnyException {
return createExpensiveGraph(key);
} });
...
try {
return graphs.get(key);
} catch (ExecutionException e) {
throw new OtherException(e.getCause());
}
• From Callable
LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
.expireAfterAccess(10, TimeUnit.MINUTES)
.build(
new CacheLoader<Key, Graph>() {
public Graph load(Key key) { // no checked exception
return createExpensiveGraph(key);
}
});
...
return graphs.getUnchecked(key);
106. Eviction #1
• By Size:
– CacheBuilder.maximumSize(long)
• By custom weight:
– CacheBuilder.weighter(Weighter)
– CacheBuilder.maximumWeight(long)
LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
.maximumWeight(100000)
.weigher(new Weigher<Key, Graph>() {
public int weigh(Key k, Graph g) {
return g.vertices().size();
}
})
.build(
new CacheLoader<Key, Graph>() {
public Graph load(Key key) { // no checked exception
return createExpensiveGraph(key);
}
});
107. Eviction #2
• By Time:
– expireAfterAccess(long, TimeUnit)
– expireAfterWrite(long, TimeUnit)
• By Testing Timed:
– CacheBuilder.ticker(Ticker)
108. Eviction #3
• By Reference-based:
– CacheBuilder.weakKeys()
– CacheBuilder.weakValues()
– CacheBuilder.softValues()
• Note: all of them are using == for
equality and *not* equals()
110. Removal Listeners
• CacheBuilder.removalListener(RemovalListener)
• Be aware of long running listeners. They are blocking the queue.
• CacheBuilder.asynchronous(RemovalListener, Executor)
CacheLoader<Key, DatabaseConnection> loader = new CacheLoader<Key, DatabaseConnection> () {
public DatabaseConnection load(Key key) throws Exception {
return openConnection(key);
}
};
RemovalListener<Key, DatabaseConnection> removalListener = new RemovalListener<Key, DatabaseConnection>() {
public void onRemoval(RemovalNotification<Key, DatabaseConnection> removal) {
DatabaseConnection conn = removal.getValue();
conn.close(); // tear down properly
}
};
return CacheBuilder.newBuilder()
.expireAfterWrite(2, TimeUnit.MINUTES)
.removalListener(removalListener)
.build(loader);
111. Cleanup
• Caches built with CacheBuilder do not perform cleanup and evict
values "automatically“, or instantly after a value expires, or
anything of the sort.
• it performs small amounts of maintenance during write
operations, or during occasional read operations if writes are rare
• Automatic eviction happens on writes Explicit Cache.cleanup()
113. com.google.common.math
Math
• Convenience classes to perform some common
mathematical calculations
• Available classes: IntMath, LongMath, DoubleMath,
and BigIntegerMath
• The utility classes support overflow-aware arithmethics,
so that no silent overflows occur.
• Also see Guava's math utilities, explained.
115. com.google.common.io
I/O
• If what you need pertains to streams, buffers, files and
the like, look to the package com.google.common.io.
In parts similar to Apache Commons I/O.
• Key interfaces:
public interface InputSupplier<T> {
T getInput() throws IOException; // T is typically an InputStream, a Reader, etc.
}
public interface OutputSupplier<T> {
T getOutput() throws IOException; // T is typically an OutputStream, a Writer, etc.
}
• Typically: InputSupplier<InputStream>, OutputSupplier
<Writer>, etc. This lets all the utility classes be useful
for many kinds of I/O.
• Also see Guava's I/O package utilities, explained.
116. com.google.common.io
Streams
Terminology:
• byte stream means "InputStream or OutputStream"
• char stream means "Reader or Writer."
Utilities for these things are in the classes ByteStreams
and CharStreams (which have largely parallel structure).
117. com.google.common.io
ByteStreams
• byte[] toByteArray(InputStream)
• byte[] toByteArray(InputSupplier)
• void readFully(InputStream, byte[])
• void write(byte[], OutputSupplier)
• long copy(InputStream, OutputStream)
• long copy(InputSupplier, OutputSupplier)
• long length(InputSupplier)
• boolean equal(InputSupplier, InputSupplier)
• InputSupplier slice(InputSupplier, long, long)
• InputSupplier join(InputSupplier...)
CharStreams is similar, but deals in Reader, Writer, String and
CharSequence (often requiring you to specify a Charset).
See the documentation on com.google.common.io.ByteStreams and
com.google.common.io.CharStreams.
118. com.google.common.io
Files
• The Files class works one level higher
than ByteStreams and CharStreams, and has a few other tricks.
• In parts superseeded by the NIO.2 classes in JDK 7 or higher.
• byte[] toByteArray(File)
• String toString(File, Charset)
• void write(byte[], File)
• void write(CharSequence, File, Charset)
• long copy(File, File)
• long copy(InputSupplier, File)
• long copy(File, OutputSupplier)
• long copy(File, Charset, Appendable)
• long move(File, File)
• boolean equal(File, File)
• List<String> readLines(File, Charset)
119. com.google.common.eventbus
Overview
Classes from the eventbus package can be used as a simple tool to
implement an in-memory publish-subscrib use case
Besides standard features these classes have some extras:
• checking if someone is listening for an event of given type
• events hierarchy
There are two variants for the event bus:
• EventBus (synchronous)
• AsyncEventBus (asynchronous)
See the documentation on com.google.common.eventbus
120. com.google.common.eventbus
Examples:Listener
Listener class needs only one additional element, a method
annotated with@Subscribe.
Argument of this method defines what type of event this class is
listening for.
There are no restrictions to be an event class. It could also just be
a String orInteger.
One listener can subscribe (listen for) more than one type of event.
public class MyListener {
@Subscribe
public listen(Integer event) {
// ...
}
}
See the documentation on com.google.common.eventbus.Subscribe
121. com.google.common.eventbus
Examples:EventBus
EventBus eventBus = new EventBus("example");
MyListener listener = new MyListener();
eventBus.register(listener);
eventBus.post(42);
// EventBus synchronously calls listener.listen(42)
• See the document on Guava's event bus utility, explained.
122. com.google.common.eventbus
DeadEvent
To handle events without any listener we can use the pre-
defined DeadEvent.
A DeadEvent is posted when the EventBus receives an event without
any listeners to it.
In such situation we can, for example, log a warning message to a
log file.
See the documentation on com.google.common.eventbus.DeadEvent
123. com.google.common.net
Classes in com.google.common.net
• work with literals of: URI, URL, IP(v4/v6)
• never cause DNS services to be accessed (JDK does…)
Examples:
• HostSpecifier: syntactically valid host specifier, suitable for use in
a URI
• InternetDomainName: RFC 1035, i18n domain names
• InetAddresses: utility class pertaining to Inet(4|6)Address instances
• HttpHeaders: constant definitions for the HTTP header field
names
• MediaType: an Internet Media Type (also known as a MIME Type
or Content Type)
124. com.google.common.reflect
Here be dragons!
Utility classes to work with Java reflection.
Please don't use reflection if you're not writing a library. It will lead to breakage
at runtime.
• TypeToken
• TypeToInstanceMap (ImmutableTypeToInstanceMap, MutableTypeToInstanceMap)
• Types
• TypeResolver
• ClassPath
• Reflection
• Invokable (ConstructorInvokable, MethodInvokable)
• Parameter
Also see Guava's new reflection utilities, explained.
125. com.google.common.annotations
• Beta
• VisibleForTesting
• GWTCompatible
• GWTIncompatible
Also see com.google.common.annotations
127. Reference
• Guava on Google Code
• http://www.tfnico.com/presentations/google-guava
• Google Guava- juice up your java
• Using The Google Collections Library For Java
• Silicon Valley Java Users Group Sept 2012 presentation slides
• DevoxxFR 2012 presentation slides
• Caching presentation from Devoxx France 2012
• Guava util.concurrent presentation
• Guava presentation (@ Netflix)
• Collection presentation from Washington University lecture
• Introduction to google guava[KOR]
• Google guava - almost everything you need to know
• Guava Overview. Part 1 @ Bucharest JUG #1
• Guava Overview Part 2 Bucharest JUG #2
• http://bhavintechspace.blogspot.de/2012/12/google-guava-introduction.html