113

Clean code with google guava jee conf

Embed Size (px)

DESCRIPTION

The Guava project contains several of Google’s core libraries that we rely on in our Java-based projects: collections, caching, primitives support, concurrency libraries, common annotations, string processing, I/O, and so forth. There will be the slides presenting most useful and interesting features of Guava (v.12) that makes stuff simpler, better and code cleaner. We will cover most of the com.google.common.base.* classes and basic use of functions in collection and Google collections and few other features that are part of Guava and I find them very useful. Some of you will think that there is an overlap with Apache commons – and it’s true, but Guava is built with expectation that there is a Function and a Predicate class as well as various builders which makes it really cool and simple for many use cases.

Citation preview

Page 1: Clean code with google guava jee conf
Page 3: Clean code with google guava jee conf

Guava is…

Page 4: Clean code with google guava jee conf

Guava is… a fruit

https://en.wikipedia.org/wiki/Guava

Page 5: Clean code with google guava jee conf
Page 6: Clean code with google guava jee conf
Page 7: Clean code with google guava jee conf
Page 8: Clean code with google guava jee conf

What is Google Guava?

annotations

basic utilities

collections

concurrency

comparison

strings

primitives

ranges

functional idioms

I/o

caching

hashing

event bus

math

reflection

net/http

Page 9: Clean code with google guava jee conf

What in this presentation?

annotations

basic utilities

collections

concurrency

comparison

strings

primitives

ranges

functional idioms

I/O

caching

hashing

event bus

math

reflection

net/http

Page 10: Clean code with google guava jee conf
Page 11: Clean code with google guava jee conf
Page 12: Clean code with google guava jee conf
Page 13: Clean code with google guava jee conf

Why Guava? The goal is for you to write less code ...

Make code more readable, cleaner and simpler

Helps developers to focus on business logic rather than writing java utilities

Saves time, resources and improve productivity

Popular API and active development

Mainstream

Basically... a painkiller and natural extension for Java

Page 14: Clean code with google guava jee conf
Page 15: Clean code with google guava jee conf

I Could've Invented That

Page 16: Clean code with google guava jee conf

ref. Effective Java

Item 47, "Know and use the libraries“

Page 17: Clean code with google guava jee conf
Page 18: Clean code with google guava jee conf

Guava Releases About every 3 months, with significant new

functionality and fixes

Release 14.0.1 was released on March 15, 2013

All releases are either major or patch releases

Never minor

Page 19: Clean code with google guava jee conf
Page 20: Clean code with google guava jee conf
Page 21: Clean code with google guava jee conf

Let’s get some Guava!

Page 22: Clean code with google guava jee conf

@annotations

Page 23: Clean code with google guava jee conf
Page 24: Clean code with google guava jee conf

Guava Basic Utilities

String Utilities Preconditions

Objects Helper

Avoiding Nulls

StopWatch

Page 25: Clean code with google guava jee conf

String Utilities

Joiner

Splitter

CharMatcher

Page 26: Clean code with google guava jee conf

Joining Strings 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 } }

Page 27: Clean code with google guava jee conf

Joining Strings Converts collections into single String object

Joining an Iterable, Iterator, varargs/array

Return a String, or append to an Appendable

Throws a NPE on null objects, unless:

.skipNulls()

.useForNull(String)

It also works with Maps

We could be looking at 18 to 48 different methods

Page 28: Clean code with google guava jee conf

Joining Strings (cont.)

List<String> fruits = Arrays.asList( "apple", null, "orange", null, null, "guava"); String joined = Joiner.on(", ").skipNulls().join(fruits); >> "apple, orange, guava"

Page 29: Clean code with google guava jee conf

Joining Strings (cont.)

List<String> fruits = Arrays.asList( "apple", null, "orange", null, null, "guava"); String joined = Joiner.on(", ").skipNulls().join(fruits); >> "apple, orange, guava" String joined = Joiner.on(",").useForNull("banana").join(fruits); >> "apple, banana, orange, banana, banana, guava"

Page 30: Clean code with google guava jee conf

Splitting Strings Working in the opposite direction than Joiner

Allows to split String into collection of elements

String.split() on steroids

A better, more intuitive String.split()

Doesn't silently discard trailing separators

Handles empty pieces predictably

Page 31: Clean code with google guava jee conf

Splitter

String input = ",, ,apple, orange ,,, banana,, ,guava, ,,"; Iterable<String> split = Splitter.on(',') .omitEmptyStrings() .trimResults() .split(input);

>> [ "apple", "orange", "banana", "guava" ]

The default behavior is simplistic

If you want extra features, ask for them!

Page 32: Clean code with google guava jee conf

Splitter

String input = ",, ,apple, orange ,,, banana,, ,guava, ,,"; Iterable<String> split = Splitter.on(',') .omitEmptyStrings() .trimResults() .split(input);

>> [ "apple", "orange", "banana", "guava" ]

The default behavior is simplistic

If you want extra features, ask for them!

By default, assumes nothing about whitespace

These classes use what Googlers (tentatively) call the "Utility Object pattern."

Page 33: Clean code with google guava jee conf

Splitter more…

Splitter.onPattern("\\d+").split("Java3Scala4Haskell0Brainfuck5Kotlin"); >> [ "Java ", "Scala", "Haskell", "Brainfuck", "Kotlin" ] Splitter.on(CharMatcher.inRange('3','5')) .split("Java3Scala4Haskell0Brainfuck5Kotlin"); >> [ "Java", "Scala", "Haskell0Brainfuck", "Kotlin" ]

Split using regular expression

Split using CharMatcher

Page 34: Clean code with google guava jee conf

CharMatcher CharMatcher provides many text processing

methods based on “matching character” notation

Separates "configuration" from "processing"

CharMatcher represents two notions:

What constitutes a matching character?

What to do with those matching characters?

Can also be used to "filter" chars

Page 35: Clean code with google guava jee conf

CharMatcher (cont.) Allows to check if a sequence of characters satisfies

given condition:

WHITESPACE, ASCII, ANY, DIGIT (many pre-defined sets)

is('x')

isNot('_')

oneOf("aeiou")

inRange('a', 'z') .or (inRange('A', 'Z')).negate()

Page 36: Clean code with google guava jee conf

All that you can do... CharMatcher

Provides methods to modify char sequences:

boolean matchesAllOf(CharSequence)

boolean matchesAnyOf(CharSequence)

boolean matchesNoneOf(CharSequence)

int indexIn(CharSequence, int)

int lastIndexIn(CharSequence, int)

int countIn(CharSequence)

String removeFrom(CharSequence)

String retainFrom(CharSequence)

String trimFrom(CharSequence)

String trimLeadingFrom(CharSequence)

String trimTrailingFrom(CharSequence)

String collapseFrom(CharSequence, char)

String trimAndCollapseFrom(CharSequence, char)

String replaceFrom(CharSequence, char)

Page 37: Clean code with google guava jee conf

CharMatcher (example)

CharMatcher matcher = CharMatcher.DIGIT .or(CharMatcher.inRange('a', 'z') .or(CharMatcher.inRange('A', 'Z'))); if (matcher.matchesAllOf("this1will2match3")) { // ... }

Page 38: Clean code with google guava jee conf

CharMatcher (example)

// eliminate all characters that aren't digits or lowercase String lowerAndDigit = CharMatcher.DIGIT .or(CharMatcher.JAVA_LOWER_CASE) .retainFrom(input);

CharMatcher matcher = CharMatcher.DIGIT .or(CharMatcher.inRange('a', 'z') .or(CharMatcher.inRange('A', 'Z'))); if (matcher.matchesAllOf("this1will2match3")) { // ... }

Page 39: Clean code with google guava jee conf

CharMatcher (example)

String pass = “$$$ secret passcode $$$"; String result = CharMatcher.is(“$”).trimFrom(pass); >> “ secret password "

trimLeadingFrom(), trimTrailingFrom() or trimAndCollapseFrom()

Page 40: Clean code with google guava jee conf

Guava Basic Utilities String Utilities

Preconditions Objects Helper

Avoiding Nulls

StopWatch

Page 41: Clean code with google guava jee conf

checkState(boolean)

Throws IllegalStateException if false

Used to check object state

if (state != State.PLAYABLE) { throw new IllegalStateException( "Can't play movie; state is " + state); }

Page 42: Clean code with google guava jee conf

checkState(boolean)

Throws IllegalStateException if false

Used to check object state

… or…

if (state != State.PLAYABLE) { throw new IllegalStateException( "Can't play movie; state is " + state); }

Preconditions.checkState(state == State.PLAYABLE, "Can't play movie; state is %s", state);

(what's the difference? none!)

Page 43: Clean code with google guava jee conf

checkNotNull(T) Throws NullPointerException if null

Returns the value. Can be used inline.

public Car(Engine engine) { this.engine = Preconditions.checkNotNull(engine); }

Page 44: Clean code with google guava jee conf

checkNotNull(T) Throws NullPointerException if null

Returns the value. Can be used inline.

. . . with using static import . . .

public Car(Engine engine) { this.engine = Preconditions.checkNotNull(engine); }

public Car(Engine engine) { this.engine = checkNotNull(engine, “engine cannot be null”); }

Page 45: Clean code with google guava jee conf

checkArgument(boolean) Throws IllegalArgumentException if false

Used to validate method arguments

public void drive(double speed) { Preconditions.checkArgument(speed > 0.0, "Speed (%s) must be positive", speed); }

Page 46: Clean code with google guava jee conf

Why Preconditions?

Defensive coding

Useful for validation

Each method has three variants: No extra arguments

An extra object for error message

An extra String & Objects. String.format like but only allows %s

Recommended to be used as static imports

Page 47: Clean code with google guava jee conf

Guava Basic Utilities String Utilities

Preconditions

Objects Helper Avoiding Nulls

StopWatch

Page 48: Clean code with google guava jee conf

Object common methods

Objects.equal(Object, Object)

Objects.hashCode(Object...)

Objects.toStringHelper(Object)

Objects.firstNonNull(T, T)

Page 49: Clean code with google guava jee conf

equal(…) & hashCode(…)

public class Person { private final String name, nickname; private final Movie favoriteMovie;

@Override public boolean equals(Object object) { if (object instanceof Person) { Person that = (Person) object; return Objects.equal(this.name, that.name) && Objects.equal(this.nickname, that.nickname) && Objects.equal(this.favoriteMovie, that.favoriteMovie); } return false; }

@Override public int hashCode() { return Objects.hashCode(name, nickname, favoriteMovie);

}

Page 50: Clean code with google guava jee conf

toStringHelper(…) & firstNonNull(T, T)

@Override public String toString() { // speakers is @Nullable! return Objects.toStringHelper(this) .add("conference", name) .add(“location", location) .add("speakers", speakers) .omitNullValues().toString(); } >> "Person{name=JeeConf, location=Kiev}“ // w/o omitNullValues() >> "Person{name=JeeConf, location=Kiev, speakers=null}“

public String preferredLocation() { return Objects.firstNonNull(location, name); }

Page 51: Clean code with google guava jee conf

Guava Basic Utilities String Utilities

Preconditions

Objects Helper

Avoiding Nulls StopWatch

Page 52: Clean code with google guava jee conf

Null is ambiguous

if (x != null && x.someM() != null && ..) { // some code… }

Page 53: Clean code with google guava jee conf

Problem with Null

No entry? Or entry exists but the nickname is unlisted?

Person person = personService.findByNickname(“Andy"); if (person == null) { // what does this mean? }

Page 54: Clean code with google guava jee conf

Problem with Null

No entry? Or entry exists but the nickname is unlisted? The value in the map is null, or the value is not in the map. Null can mean failure, can mean success, can mean almost anything.

Person person = personService.findByNickname(“Andy"); if (person == null) { // what does this mean? }

Map.get(key)

Page 55: Clean code with google guava jee conf
Page 56: Clean code with google guava jee conf

Optional<T> vs. null null is "hidden", Optional is ”explicit” An immutable wrapper that is either:

present: contains a non-null reference absent: contains nothing Note that it never "contains null"

Possible uses: return type

“a T that must be present" "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

Page 57: Clean code with google guava jee conf

Optional<T>

// Make optional of given type Optional<String> possible = Optional.of(“Ido”); Optional<String> value = Optional.fromNullable(str); if (value.isPresent()) { // ... } // returns true if nonNull possible.isPresent(); // returns this possible value or default possible.or(“Nick”); // returns Ido possible.get();

Page 58: Clean code with google guava jee conf

Making an Optional Optional.of(T) - make optional of given non-null

value or fail fast on null

Optional.absent() - return an absent optional of some type

Optional.fromNullable(T) - turn value in Optional and treat null as absent

Page 59: Clean code with google guava jee conf

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!

Page 60: Clean code with google guava jee conf

Others… Strings Methods are primarily for interfacing with

unpleasant APIs that equate null strings and empty strings:

Strings.emptyToNull(String)

Strings.isNullOrEmpty(String)

Strings.nullToEmpty(String)

Page 62: Clean code with google guava jee conf

Guava Basic Utilities String Utilities

Preconditions

Objects Helper

Avoiding Nulls

StopWatch

Page 63: Clean code with google guava jee conf

StopWatch Class for measuring elapsed time

Prefer StopWatch over System.nanoTime()

Don't use System.currentTimeMillis()!

Provides methods that automatically calculate time between start() and stop() execution

Page 64: Clean code with google guava jee conf

StopWatch

public void measureElapsedTime(Collection<String> input) { Stopwatch stopwatch = new Stopwatch().start(); doSomeOperation(input); long nanos = stopwatch.elapsed(TimeUnit.NANOSECONDS); }

Page 65: Clean code with google guava jee conf

StopWatch Pros StopWatch uses nanoTime() but exposes only relative

timings, a meaningless absolute value

Alternate time sources can be substituted using Ticker (read() returns nanoseconds)

Can be easily mocked with custom passing time provider

Returns counted time using different units

toString() gives human readable format

Page 66: Clean code with google guava jee conf

Functional Concepts brought to Java

Many things in Guava are inspired by functional concepts from other programming languages

In Java can only be approximated through awkward and verbose use of anonymous classes

Expected to change in Java 8

Guava is currently aimed at users of Java 5 and above

Page 67: Clean code with google guava jee conf

Core concepts Key functional concepts Guava uses:

Page 68: Clean code with google guava jee conf

Core concepts Key functional concepts Guava uses:

Function<F, T> == F => T

=> to transform a collection

public interface Function<F, T> { @Nullable T apply(@Nullable F input); }

Page 69: Clean code with google guava jee conf

Core concepts Key functional concepts Guava uses:

Function<F, T> == F => T

=> to transform a collection

Predicate<T> == T => Boolean

=> filter out a collection

public interface Function<F, T> { @Nullable T apply(@Nullable F input); }

public interface Predicate<T> { boolean apply(@Nullable T input); }

Page 70: Clean code with google guava jee conf

Function<F,T> usage

Iterables.transform()

FluentIterable.transform()

Iterators.transform()

Collections2.transform()

Lists.transform()

Maps, Multimaps … etc.

Main usage with transform()

Tools to manipulate collections using Function:

Page 71: Clean code with google guava jee conf

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()

Page 72: Clean code with google guava jee conf

Function <F,T>

Java 7 doesn't have lambda expressions, but Guava helps us out (a bit) with Function

public void demo(Collection<String> input) { Function<String, String> toUpperCase = new Function<String, String>() {

@Override public String apply(String string) { return string.toUpperCase(); } };

Collection<String> transformed = Collections2.transform(input, toUpperCase); }

Page 73: Clean code with google guava jee conf

Predicate<T> usage

Predicate checks if condition is met for passed object

Tools to manipulate collections using Predicate:

FluentIterables.filter()

Iterables.filter()

Iterators.filter()

Collections2.filter()

Sets.filter()

Maps, MultiMaps, … etc.

Page 74: Clean code with google guava jee conf

Predicate <T> Quite similar to Function but does NOT extend it

Predicate<User> onlyAwesome = new Predicate<User>() { @Override public boolean apply(User in) { return Optional.fromNullable(in) .or(User.NOT_AWESOME).isAwesome(); } };

Page 75: Clean code with google guava jee conf

Predicate <T> Let's use it on a collection:

Iterable<User> users = getMixedUsers(); // find all awesome users Iterable<User> onlyAwesomeUsers = Iterables.filter(users, onlyAwesome); // find one (first) awesome user User awesomeUser = Iterables.find(users, onlyAwesome); // or better Optional<User> awesomeOrAbsent = Iterables.tryFind(users, onlyAwesome);

Page 76: Clean code with google guava jee conf

Putting it together

private Iterable<Integer> puttingItTogether(Iterable<Integer> numbers) { FluentIterable<Integer> squaresOfEvens = FluentIterable.from(numbers) .filter(new Predicate<Integer>() { @Override public boolean apply(Integer input) { checkNotNull(input, "nulls are not allowed here!"); return input % 2 == 0; }}).transform(new Function<Integer, Integer>() { @Override public Integer apply(Integer input) { checkNotNull(input, "nulls are not allowed here!"); return input * input; } }); return squaresOfEvens; }

Page 77: Clean code with google guava jee conf

… Or

List<Integer> squaresOfEvens = Lists.newArrayList(); for (Integer number : givenNumbers) { if (number % 2 == 0) { squaresOfEvens.add(number * number); } } >> [ 4, 16, 36, 64, 100 ]

Page 78: Clean code with google guava jee conf

… Moral

List<Integer> squaresOfEvens = Lists.newArrayList(); for (Integer number : givenNumbers) { if (number % 2 == 0) { squaresOfEvens.add(number * number); } } >> [ 4, 16, 36, 64, 100 ]

Just be careful!!

Functional style can be great but it's not automatically the better way to go.

Page 79: Clean code with google guava jee conf
Page 80: Clean code with google guava jee conf

Java Caching

Page 81: Clean code with google guava jee conf

Java Caching with Guava Guava has a powerful on-heap key→value cache

Thread-safe implementation

More or less internally similar to ConcurrentMap + automatic eviction

No explicit support for distributed caching

Page 82: Clean code with google guava jee conf

Types of Caches Provides two types of caches:

LoadingCache - knows how to load entries when a cache miss occurs LoadingCache.get(key) returns the value associated with

key, loading it first if necessary

Cache - does not automatically load entries

We're going to focus on the loading case here; it's usually what you want

Page 83: Clean code with google guava jee conf

Caches (example)

CacheLoader<String, Graph> loader = new CacheLoader<String, Graph>() {

@Override public Graph load(String key) { return createExpensiveGraph(key); }

}; LoadingCache<String, Graph> cache = CacheBuilder.newBuilder().build(loader);

Page 84: Clean code with google guava jee conf

CacheBuilder The CacheBuilder has next properties:

Cache size

Time to expire entries after last access

Time based expiration of entries after being updated

Use of weak or soft references for keys/values

Setting RemovalListener that can receive events once an entry is removed fro the cache.

Concurrency level for update operations (defaults to 4)

Enable recording caching stats

Page 85: Clean code with google guava jee conf

CacheBuilder (example)

LoadingCache<String, String> cache = CacheBuilder.newBuilder() .maximumSize(1000) .expireAfterAccess(10, TimeUnit.SECONDS) .recordStats() .build(new CacheLoader<String, String>() { @Override public String load(String key) throws Exception { return key.toUpperCase(); } });

Page 86: Clean code with google guava jee conf

Concurrency Cache instances are internally implemented very

similar to ConcurrentHashMap (thus thread-safe)

CacheLoader.load will be invoked a single time for each key, regardless of the number of requesting threads

The result will be returned to all requesting threads and inserted into the cache using the equivalent of putIfAbsent

Page 87: Clean code with google guava jee conf

Cache Eviction By size

.maximumSize(long)

By custom weight:

.weigher(Weigher)

.maximumWeight(long)

By time:

.expireAfterAccess(long, TimeUnit)

.expireAfterWrite(long, TimeUnit)

Page 88: Clean code with google guava jee conf

Cache Eviction (cont.) Reference-based eviction:

.weakKeys()

.weakValues()

.softValues()

Explicit:

.invalidate(key)

.invalidateAll(keys)

.invalidateAll()

Page 89: Clean code with google guava jee conf

Checked Exceptions What if loading causes a checked exception?

CacheLoader<String, String> checkedLoader = new CacheLoader<String, String>() { @Override public String load(String key) throws IOException { return loadFromDisk(key); } };

Page 90: Clean code with google guava jee conf

Checked Exceptions (cont.)

LoadingCache<String, String> cache = CacheBuilder.newBuilder().build(checkedLoader); try { cache.get(key); } catch (ExecutionException e) { // ensure stack trace is for this thread throw new IOException(e.getCause()); }

Page 91: Clean code with google guava jee conf

Cache Stats hitCount – number of times Cache returned the

cached value

missCount – number of times Cache returned uncached value

loadSuccessCount – number of times Cache loaded new value successfully

Page 92: Clean code with google guava jee conf

Cache Stats (example)

LoadingCache<String, String> cache = CacheBuilder.newBuilder() .recordStats().build(checkedLoader); // cumulative stats since cache creation CacheStats stats = cache.stats(); CacheStats{ hitCount=4, missCount=3, loadSuccessCount=3, loadExceptionCount=0, totalLoadTime=676064, evictionCount=0 }

Page 93: Clean code with google guava jee conf

…Collections

Page 94: Clean code with google guava jee conf

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]

Page 95: Clean code with google guava jee conf

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<E> implementation only needs to store one occurrence of each element, plus a count!

[a x 3, c x 2, b x 3]

Page 96: Clean code with google guava jee conf

MultiSet<E>

Add multiple instances of a given element

Counts how many occurrences exist

Similar to a Map<E, Integer>, but...

only positive counts

size() returns total # of items, not # keys

count() for a non-existent key is 0

iterator() goes over each element

Usage: i.e. Track frequencies of elements, e.g. "word counting"

Page 97: Clean code with google guava jee conf

MultiSet<E> Implementations HashMultiset

TreeMultiset

LinkedHashMultiset

ConcurrentHashMultiset

ImmutableMultiset

Page 98: Clean code with google guava jee conf

Tired of this? Map<String, List<String>>

Page 99: Clean code with google guava jee conf

Tired of this? Map<String, List<String>> {a=1, a=2, b=3, c=4, c=5, c=6}

Page 100: Clean code with google guava jee conf

Try …

Page 101: Clean code with google guava jee conf

MultiMap<K, V> Like Map (key-value pairs), but may have duplicates

The values related to a single key can be viewed as a collection (set or list)

Similar to a Map<K, Collection<V>>, but...

get() never returns null (returns an empty collection)

containsKey() is true only if 1 or more values exist

entries() returns all entries for all keys

size() returns total number of entries, not keys

asMap() to view it as a Map<K, Collection<V>>

Page 102: Clean code with google guava jee conf

MultiMap<K, V>

Multimap<String, String> mm = ArrayListMultimap.create(); Collection<String> smiths = mm.get("Smith"); >> empty collection (never null) mm.put("Smith", "John"); mm.put("Smith", "Alice"); mm.put("Smith", "Diane"); smiths = mm.get("Smith"); >> [ "John", "Alice", "Diane" ]

Page 103: Clean code with google guava jee conf

MultiMap Implementations ArrayListMultimap

HashMultimap

LinkedListMultima

LinkedHashMultimap

TreeMultimap

ImmutableListMultimap

ImmutableSetMultimap

Page 104: Clean code with google guava jee conf

BiMap<K1, K2>

Bi-directional Map

Both keys and values are unique

Can view the inverse map with inverse()

Use instead of maintaining two separate maps: Map<K1, K2>

Map<K2, K1>

Page 105: Clean code with google guava jee conf

Static utilities In classes with name ending with an s Lists

Maps

Multimaps

Multisets

Sets

SortedMaps

Tables

Iterators

Iterables

Collections2

Page 106: Clean code with google guava jee conf

Static factories methods

Rather than typing

you type

Map<String, Class<? extends Handler>> m = new HashMap<String, Class<? extends Handler>>();

Map<String, Class<? extends Handler>> m2 = Maps.newHashMap();

Page 107: Clean code with google guava jee conf

Guava Alternatives

Should you use Guava or Apache Commons?

We may be biased, so consult this question on Stack Overflow:

http://tinyurl.com/guava-vs-apache

The large number of upvotes for the top answers shows a pretty strong community consensus

Page 108: Clean code with google guava jee conf

Need help with a problem? Post to Stack Overflow! Use the "guava" tag

Report a defect, request an enhancement?

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

Start an email discussion?

Send to [email protected]

General discussion takes place on

http://groups.google.com/group/guava-discuss

The Guava team is generally highly active in all of these areas

Page 109: Clean code with google guava jee conf

Time to Play

Page 110: Clean code with google guava jee conf
Page 111: Clean code with google guava jee conf

What to Remember Functional flavor of collection handling

CharMatcher / Splitter / Joiner

Avoid null where possible

Ease of Preconditions

Caching

Multimap / Multiset / Bimap

Page 112: Clean code with google guava jee conf

Q&A

http://www.flickr.com/photos/wwworks/4759535950/sizes/o/in/photostream/