0% found this document useful (0 votes)
75 views63 pages

An Overview of Guava: Google Core Libraries For Java

Guava is a free open-source library for Java developed by Google that contains utility classes and methods across 14 packages. It includes commonly needed classes and methods for strings, collections, caching, primitives, concurrency, and more. The library is designed using patterns like utility objects that separate configuration from processing to provide flexible yet simple to use classes like Joiner, Splitter, CharMatcher, and Optional that handle common tasks in a comprehensive way.

Uploaded by

Nivaldo Monteiro
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
75 views63 pages

An Overview of Guava: Google Core Libraries For Java

Guava is a free open-source library for Java developed by Google that contains utility classes and methods across 14 packages. It includes commonly needed classes and methods for strings, collections, caching, primitives, concurrency, and more. The library is designed using patterns like utility objects that separate configuration from processing to provide flexible yet simple to use classes like Joiner, Splitter, CharMatcher, and Optional that handle common tasks in a comprehensive way.

Uploaded by

Nivaldo Monteiro
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 63

An Overview of Guava:

Google Core Libraries


for Java
Kevin Bourrillion
Java Core Libraries Team
Google, Inc.
Presented at QCon November 8, 2012

Google Confidential and Proprietary

What's Guava?
Free open-source library for Java, GWT, Android.
14 packages chock full of utility classes and methods:
annotations
base
cache
collect
collect.testing
eventbus
hash

io
math
net
primitives
reflect
testing
util.concurrent

(These packages live under com.google.common.)


Google Confidential and Proprietary

Where does it come from?


We are the Java Core Libraries Team at Google.
What do we do?
Why do we release Guava?
It's a junk drawer then?
Why are you here talking about it?

Google Confidential and Proprietary

Actual User Quotes


On any new Java project, the first thing I do is add a
dependency to Guava; I just know Im going to need it.
Writing Java without Guava was like coding with one hand
tied behind my back.
Guava makes Java bearable again.
(We happen to think Java is more than bearable anyway,
but still: Guava makes writing Java programs easier.)

*paraphrased. But I swear people really said these things. Honest.

Google Confidential and Proprietary

About this presentation

Google Confidential and Proprietary

com.google.common.base

Google Confidential and Proprietary

String joining
Who here has ever written this utility?
public class StringUtil {
public static String join(
String separator, Iterable<String> pieces) {
// any of ~5 common implementations goes here
}
}

Google Confidential and Proprietary

String joining 2
But what about all the variations?
What to do with nulls?
skip over them? skip but leave separator? substitute
"null" or some other string? Just die?
Joining an Iterable, Iterator, varargs/array?
Return a String, or append to an Appendable?
We could be looking at 18 to 48 different methods here.
To cover all these bases we made Joiner:
return Joiner.on(", ")
.skipNulls()
.join("one", null, "two", "three");
Google Confidential and Proprietary

Joiner: what's going on here?


To get a Joiner:
static Joiner on(String)
static Joiner on(char)
To get an altered Joiner from that:
Joiner skipNulls()
Joiner useForNull(String)
To actually join stuff:
String join(Itera___)
String join(Object...)
Appendable appendTo(Appendable, Itera___)
Appendable appendTo(Object...)
Google Confidential and Proprietary

Splitter
Similar! But in the other direction.
return Splitter.on("|")
.omitEmptyStrings()
.split("|Harry||Ron|||Hermione
// returns "Harry", "Ron", "Hermione

||");
";

These classes use what we (tentatively) call the "Utility


Object pattern."

Google Confidential and Proprietary

CharMatcher (motivation)
Once upon a time we had a StringUtil class. Soon it was
overflowing with static methods:
allAscii, collapse, collapseControlChars,
collapseWhitespace, indexOfChars, lastIndexNotOf,
numSharedChars, removeChars, removeCrLf, replaceChars,
retainAllChars, strip, stripAndCollapse,
stripNonDigits...

Each dealt with two orthogonal concerns:


(a) what does it consider a matching character?
(b) what do we do with these matching characters?
One static method per combination would not scale.
Google Confidential and Proprietary

CharMatcher
Once again we use the Utility Object pattern.
A CharMatcher instance represents the set of "matching"
characters (part "a"). Methods on that instance provide the
operations (part "b").
// "_34-425==" becomes "34425"
String sanitized =
CharMatcher.anyOf("-=_")
.removeFrom(input);
Separates "configuration" from "processing".

Google Confidential and Proprietary

Getting a CharMatcher
Use a predefined constant (examples)
CharMatcher.WHITESPACE (Unicode)
CharMatcher.ASCII
CharMatcher.ANY
Use a factory method (examples)
CharMatcher.is('x')
CharMatcher.isNot('_')
CharMatcher.oneOf("aeiou")
CharMatcher.inRange('a', 'z')
.or(inRange('A', 'Z')).negate()
Or subclass CharMatcher, implement matches(char).
Google Confidential and Proprietary

Using your new CharMatcher


boolean matchesAllOf(CharSequence)
boolean matchesAnyOf(CharSequence)
boolean matchesNoneOf(CharSequence)
int indexIn(CharSequence, int)
int lastIndexIn(CharSequence, int)
int countIn(CharSequence)
String
String
String
String
String
String
String
String

removeFrom(CharSequence)
retainFrom(CharSequence)
trimFrom(CharSequence)
trimLeadingFrom(CharSequence)
trimTrailingFrom(CharSequence)
collapseFrom(CharSequence, char)
trimAndCollapseFrom(CharSequence, char)
replaceFrom(CharSequence, char)
Google Confidential and Proprietary

CharMatcher (last)
Putting it back together... to scrub an id number, you might
use
String seriesId =
CharMatcher.DIGIT.or(CharMatcher.is('-'))
.retainFrom(input);
In a loop? Move the definition above or to a constant.
static final CharMatcher ID_CHARS =
CharMatcher.DIGIT.or(CharMatcher.is('-'));
...
String id = SERIES_ID_CHARS.retainFrom(input);
Google Confidential and Proprietary

One problem with null


Consider looking up a phone number.
PhoneNumber phone = phoneBook.lookUp("Barack");
if (phone == null) {
// what does this mean?
}
No entry? Or entry exists but the phone number is unlisted?
Or consider a nickname field. null means no nickname, or
we just don't know?

Google Confidential and Proprietary

Optional<T>
Guava's Optional class lets you have a "second kind of
not-there" -- a "positive negative."
// Yes, has a nickname
Optional<String> nickname = Optional.of("Barry");
// Yes, we have no nickname
Optional<String> nickname = Optional.absent();
// Information missing/unknown
Optional<String> nickname = null;
// wat? Throws an exception.
Optional<String> nickname = Optional.of(null);
Google Confidential and Proprietary

Optional<T> basic usage


Optional<String> nickname = person.nickname();
if (nickname == null) return;
if (nickname.isPresent()) {
say("I hear people call you " + nickname.get());
} else {
// calling get() would throw an exception!
say("Your friends are not creative.");
}

Google Confidential and Proprietary

Optional<T> cooler usages


for (String actualNick : nickname.asSet()) {
doSomething(actualNick);
}
or
String firstName = person.firstName();
say("Hello, " + nickname.or(firstName));

Google Confidential and Proprietary

For null-unfriendly
collections
Many collections, including the JDK's Queue and
ConcurrentMap implementations, don't allow null elements.
Queue<Optional<Foo>> is a simple and natural solution!

Google Confidential and Proprietary

Optional<T>: the anti-null?


Some users use Optional even when they have only one
"kind of not-there". They use it as a null replacement.
Before:
Foo foo = someMethodThatMightReturnNull();
foo.whoops(); // I just forgot to check!
After:
Optional<Foo> foo = someMethod();
foo.get().whoops(); // same mistake!
Same mistake possible, but less likely to some degree.
Especially appropriate for public method return types.
Google Confidential and Proprietary

Stopwatch
For measuring elapsed time. Don't use System.
currentTimeMillis()!
Stopwatch watch = new Stopwatch().start();
doSomeOperation();
long micros = watch.elapsedTime(MICROSECONDS);
Stopwatch uses nanoTime() but exposes only relative
timings, a meaningless absolute value
an alternate time source can be substituted using
Ticker
has the same functions as a physical stopwatch
toString() gives human readable format
Google Confidential and Proprietary

Other things in base


... that we're not really going into ...

Preconditions
Objects.toStringHelper()
Objects.firstNonNull(T, T)
Throwables.propagate(Throwable)
CaseFormat
Strings.repeat(String, int)
Equivalence<T>
Function, Predicate, Supplier

Google Confidential and Proprietary

com.google.common.collect

Google Confidential and Proprietary

Collection Types (review)


Set:
doesn't guarantee order, has "unordered equality"
collapses duplicates
List:
guarantees order, has "ordered equality"
allows duplicates (multiple "occurrences")
Aren't these two orthogonal concerns?

Google Confidential and Proprietary

Basic Collection Types

Ordered?

Y
N
+------------+----------+
Y |
List
|
?
|
Dups?
+------------+----------+
N |
?
|
Set
|
+------------+----------+

Google Confidential and Proprietary

Basic Collection Types

Ordered?

Y
N
+------------+----------+
Y |
List
| Multiset |
Dups?
+------------+----------+
N |(UniqueList)|
Set
|
+------------+----------+

Google Confidential and Proprietary

Multiset<E>
Implements Collection<E>.
List:
[a, c, b, b, c, a, a, b]
Set:
[a, c, b]
Multiset: [a, a, a, c, c, b, b, b]
So a Multiset implementation only needs to store one
occurrence of each element, plus a count!
[a x 3, c x 2, b x 3]

Google Confidential and Proprietary

Counting without Multiset


Map<String, Integer> tags = new HashMap<>();
for (BlogPost post : getAllBlogPosts()) {
for (String tag : post.getTags()) {
int value = tags.containsKey(tag) ? tags.get(tag) : 0;
tags.put(tag, value + 1);
}
}
distinct tags: tags.keySet()
count for "java" tag:
tags.containsKey("java") ? tags.get("java") : 0;
total count: // uh oh...

Google Confidential and Proprietary

Counting with Multiset


Multiset<String> tags = HashMultiset.create();
for (BlogPost post : getAllBlogPosts()) {
tags.addAll(post.getTags());
}

distinct tags: tags.elementSet();


count for "java" tag: tags.count("java");
total count: tags.size();

Impls include ConcurrentHashMultiset, EnumMultiset...


Google Confidential and Proprietary

Next...
Map:
a1
b2
c3
d4

Google Confidential and Proprietary

Multimap<K, V>
Map:
a1
b2
c3
d4

Multimap:
a1
b2
c3
a4
Of course, we often also
want to view this as:
a 1, 4
b2
c3

Google Confidential and Proprietary

Multimap<K, V>
Like a Map (key-value pairs), but may have duplicate keys
The values related to a single key can be viewed as a
collection (set or list)
Consistent design to Map<K, V>
(analogy holds: Map : Set :: Multimap : Multiset)
Typically use instead of a Map<K, Collection<V>>
can view as that type using asMap()
Almost always want variable type to be either
ListMultimap or SetMultimap (and not Multimap)
Implementations include HashMultimap,
ArrayListMultimap...
Not going to say much more about these...
Google Confidential and Proprietary

Immutable Collections
ImmutableSet<Integer> luckyNumbers =
ImmutableSet.of(4, 8, 15, 16, 23, 42);
unlike Collections.unmodifiableXXX, they
perform a copy (not a view / wrapper)
type conveys immutability
offered for all collection types, including JDK ones
inherently thread-safe
deterministic, specified iteration order
reduced memory footprint
slightly improved CPU performance

Prefer immutability!
Google Confidential and Proprietary

FluentIterable<T>
You should all know Iterable<T>:
public interface Iterable<T> {
Iterator<T> iterator();
}
Guava can turn your iterables into fluent iterables:
FluentIterable<Thing> things =
FluentIterable.from(getThings());
... but why? ...

Google Confidential and Proprietary

FluentIterable
Because operations! (note: "lazy")
return FluentIterable.from(database.getClientList())
.filter(
new Predicate<Client>() {
public boolean apply(Client client) {
return client.activeInLastMonth();
}
})
.transform(Functions.toStringFunction())
.limit(10)
.toList();
Google Confidential and Proprietary

FluentIterable API
Chaining methods (return FluentIterable<T>)
filter(Predicate)
transform(Function)
skip(int), limit(int)
cycle()
Query methods (return boolean)
allMatch(Predicate), anyMatch(Predicate)
contains(Object)
isEmpty()
Extraction methods (return Optional<T>)
first(), last(), firstMatch(Predicate), get(int)
Conversion methods (return a copied Collection<T>)
toList(), toSet(), toSortedSet(), toArray()
Google Confidential and Proprietary

Functional Programming
Multiset<Integer> lengths = HashMultiset.create(
FluentIterable.from(strings)
.filter(new Predicate<String>() {
@Override public boolean apply(String s) {
return JAVA_UPPER_CASE.matchesAllOf(s);
}
})
.transform(new Function<String, Integer>() {
@Override public Integer apply(String s) {
return s.length();
}
}));

Google Confidential and Proprietary

w/o Functional Programming


Multiset<Integer> lengths = HashMultiset.create();
for (String s : strings) {
if (UPPER_CASE.matchesAllOf(s)) {
lengths.add(s.length());
}
}

Moral: just be careful out there.


Functional style can be great but it's not automatically the
better way to go.
JDK 8 will make functional programming in Java way better
(JSR-335).

Google Confidential and Proprietary

Comparators
Who loves implementing comparators by hand?
Comparator<String> byReverseOffsetThenName =
new Comparator<String>() {
public int compare(String tzId1, String tzId2) {
int offset1 = getOffsetForTzId(tzId1);
int offset2 = getOffsetForTzId(tzId2);
int result = offset2 - offset1; // careful!
return (result == 0)
? tzId1.compareTo(tzId2)
: result;
}
};

Google Confidential and Proprietary

ComparisonChain example
Here's one way to rewrite this:
Comparator<String> byReverseOffsetThenName =
new Comparator<String>() {
public int compare(String tzId1, String tzId2) {
return ComparisonChain.start()
.compare(getOffset(tzId2), getOffset(tzId1))
.compare(tzId1, tzId2)
.result();
}
};

Never allocates. Short-circuits (kind of).

Google Confidential and Proprietary

Ordering example
Here's another:
Ordering<String> byReverseOffsetThenName =
Ordering.natural()
.reverse()
.onResultOf(tzToOffsetFn())
.compound(Ordering.natural());
// okay, this should actually go above
Function<String, Integer> tzToOffsetFn =
new Function<String, Integer>() {
public Integer apply(String tzId) {
return getOffset(tzId);
}
};

Google Confidential and Proprietary

Ordering details 1/3


Implements Comparator, and adds delicious goodies!
(Could have been called FluentComparator.)
Common ways to get an Ordering to start with:
Ordering.natural()
new Ordering() { public int compare(...) {...} }
Ordering.from(preExistingComparator);
Ordering.explicit("alpha", "beta", "gamma", "delta");

... then ...

Google Confidential and Proprietary

Ordering details 2/3


... then you can use the chaining methods to get an altered
version of that Ordering:

reverse()
compound(Comparator)
onResultOf(Function)
nullsFirst()
nullsLast()

... now you've got your Comparator! But also ...

Google Confidential and Proprietary

Ordering details 3/3


Ordering has some handy operations:

immutableSortedCopy(Iterable)
isOrdered(Iterable)
isStrictlyOrdered(Iterable)
min(Iterable)
max(Iterable)
leastOf(int, Iterable)
greatestOf(int, Iterable)

Google Confidential and Proprietary

... which is better?


Ordering or ComparisonChain?
Answer: it depends, and that's why we have both.
Either is better than writing comparators by hand (why?).
When implementing a Comparator with ComparisonChain,
still extend Ordering anyway!

Google Confidential and Proprietary

Glimpses of other stuff

Google Confidential and Proprietary

Static utils for primitives

Google Confidential and Proprietary

Concurrency libraries
First learn the contents of java.util.concurrent.
Then check out our:
ListenableFuture<V>, ListeningExecutorService
CheckedFuture<V, X>
Service, ServiceManager
RateLimiter
ThreadFactoryBuilder
MoreExecutors
AtomicLongMap<K>
AtomicDouble
Uninterruptibles
...
Google Confidential and Proprietary

Caching
Guava has a powerful on-heap keyvalue cache.
LoadingCache<Key, Graph> cache = CacheBuilder.newBuilder()
.maximumSize(50000)
.expireAfterWrite(33, MINUTES)
.removalListener(notifyMe)
.build(
new CacheLoader<Key, Graph>() {
public Graph load(Key key) throws AnyException {
return createExpensiveGraph(key);
}
});
. . .
return cache.getUnchecked(myKey);

Google Confidential and Proprietary

Unified Hashing API


Object.hashCode() is good enough for in-memory hash
tables. What about more advanced hashing use cases
(fingerprinting, cryptographic, bloom filters...)?
HashCode hash = Hashing.murmur3_128().newHasher()
.putInt(person.getId())
.putString(person.getFirstName())
.putBytes(person.getSomeBytes())
.putObject(person.getPet(), petFunnel)
.hash(); // asLong(), asBytes(), toString()...
You can use murmur3 or JDK-provided algorithms (sha1,
crc32, etc.) with one consistent, user-friendly API.
Google Confidential and Proprietary

Coda

Google Confidential and Proprietary

How to contact us
Need help with a specific problem?
Post to Stack Overflow! Use the "guava" tag.
Report a defect, request an enhancement?

http://code.google.com/p/guava-libraries/issues/entry

Start an email discussion?


Send to [email protected]

Google Confidential and Proprietary

Requesting a new feature


It is hard to sell a new feature to Guava -- even for me!
Your best bet: a really well-documented feature request.
Try to search closed issues first, but don't worry (dups
happen).
1. What are you trying to do?
2. What's the best code you can write to accomplish that
using only today's Guava?
3. What would that same code look like if we added your
feature?
4. How do we know this problem comes up often enough
in real life to belong in Guava?
(Don't rush to code up a patch yet.)
Google Confidential and Proprietary

Q&A

Google Confidential and Proprietary

Some FAQs
... in case you don't ask enough questions!

Google Confidential and Proprietary

1. Y U NO Apache Commons?
Should you use Guava or Apache Commons?
We may be biased, so consult this question on Stack
Overflow:
http://tinyurl.com/guava-vs-apache

Google Confidential and Proprietary

2. Why is Guava monolithic?


Why don't we release separate "guava-collections", "guavaio", "guava-primitives", etc.?
For many usages, binary size isn't an issue.
When it is, a split like this won't actually help! Most users
use a little bit from each package.
Our favorite solution: ProGuard.
A single release is much simpler for us and you.

Google Confidential and Proprietary

3. What about GWT?


A significant subset is available for use with Google Web
Toolkit.
Every class marked @GwtCompatible... minus the
members marked @GwtIncompatible.
Note: We haven't spent much time optimizing for GWT.

Google Confidential and Proprietary

4. What about Android?


Everything should work on Android.
Guava 13.0 requires Gingerbread (has been out 2 years).
Targeting Froyo or earlier? There's a backport, guavajdk5.
Note: We haven't spent much time optimizing for Android.

Google Confidential and Proprietary

5. What is "google-collect"?
Heard of the Google Collections Library 1.0?
It's Guava 0.0, essentially. It's the old name of the project
before we had to rename it to Guava.
So please do not use google-collect.jar! Seek and destroy!
Classpath catastrophe will ensue otherwise!
(More history: if you see a funny version like "guava-r07", it
actually means Guava 7.0. Very sorry!)

Google Confidential and Proprietary

6. Where are fold, reduce, etc?


We're not trying to be the end-all be-all of functional
programming in Java!
We have Predicates and Functions, filter() and transform(),
because we had specific needs for them.
If you code in Java but love the FP ethos, then Java 8 will
be the first thing to really make you happy.

Google Confidential and Proprietary

Thanks!

Google Confidential and Proprietary

You might also like