Your SlideShare is downloading. ×
0
Google Guava
Core libraries for Java & Android
@jordi9
11 / oct / 2013
...shameless self-promotion bro!
Write less code
Write cleaner code
Write more readable code
The “wheel”
com.google.guava:guava:15.0
Basics
Basics
Avoid using null
Basics: Avoid using null
“Null sucks”
Doug Lea - JCP, OpenJDK
Basics: Avoid using null
“I call it my billion-dollar mistake”
Sir C.A.R. Hoare - Inventor of null
Basics: Avoid using null
@Google
95% of collections weren’t supposed
to have null values.
map = {Foo: bar, null, Baz: qux}
Basics: Avoid using null
map = {Foo: bar, null, Baz: qux}
map.get(“Foo”);
Basics: Avoid using null
map = {Foo: bar, null, Baz: qux}
map.get(“Foo”); // returns Foo
Basics: Avoid using null
map = {Foo: bar, null, Baz: qux}
map.get(“Foo”);
map.get(“quux”);
Basics: Avoid using null
map = {Foo: bar, null, Baz: qux}
map.get(“Foo”);
map.get(“quux”); // returns null
Basics: Avoid using null
map = {Foo: bar, null, Baz: qux}
map.get(“Foo”);
map.get(“quux”);
map.get(null);
Basics: Avoid using null
map = {Foo: bar, null, Baz: qux}
map.get(“Foo”);
map.get(“quux”);
map.get(null); // returns null
Basics: Avoid using null
map = {Foo: bar, null, Baz: qux}
map.get(“Foo”);
map.get(“quux”); // returns null
map.get(null); // returns null
Basics: A...
map = {Foo: bar, null, Baz: qux}
map.get(“Foo”);
map.get(“quux”); // returns null
map.get(null); // returns null
// Null t...
Optional<T>
Basics: Avoid using null
Optional<T>
Optional<String> foo = Optional.of(“foo”)
Basics: Avoid using null
Optional<T>
Optional<String> foo = Optional.of(“foo”)
foo.isPresent(); // returns true
Basics: Avoid using null
Optional<T>
Optional<String> foo = Optional.of(“foo”)
foo.isPresent();
foo.get(); // returns “foo”
Basics: Avoid using null
Optional.of(foo); // not nullable
Goodies!
RTFM, I mean javadoc
Optional.of(foo);
Optional.absent();
Goodies!
javadoc
Optional.of(foo);
Optional.absent();
Optional.fromNullable(legacyCode);
Goodies!
javadoc
Optional.of(foo);
Optional.absent();
Optional.fromNullable(legacyCode);
foo.get(); // may return “foo”
Goodies!
javadoc
Optional.of(foo);
Optional.absent();
Optional.fromNullable(legacyCode);
foo.get();
foo.or(“bar”); // return “bar” if foo i...
Optional.of(foo);
Optional.absent();
Optional.fromNullable(legacyCode);
foo.get();
foo.or(“bar”);
foo.orNull(); // Deal wi...
Optional<T> is IDIOT-PROOF-NESS
Bottom line
Basics
Preconditions
if (seats <= 0) {
throw new IllegalArgumentException(“Seats must be
positive, but was ” + seats);
}
Basics: Preconditions
if (seats <= 0) {
throw new IllegalArgumentException(“Seats must be
positive, but was ” + seats);
}
checkArgument(seats > ...
// Always use static import
import static com.google.common.base.Preconditions.checkArgument;
checkArgument(seats > 0, “Se...
import static com.google.common.base.Preconditions.checkArgument;
// Check what you expect to be true
checkArgument(seats ...
import static com.google.common.base.Preconditions.checkArgument;
// “%s” specifier is recognized as a placeholder in
// t...
void execute(Job job) {
// serious business
}
Basics: Preconditions
void execute(Job job) {
checkNotNull(job, “Job can’t be null”);
// serious business
}
// checkNotNull() throws NullPointer...
void execute(Job job) {
checkNotNull(job, “Job can’t be null”);
checkArgument(!job.started(), “Job already started”);
// s...
void execute(Job job) {
checkNotNull(job, “Job can’t be null”);
checkArgument(!job.started(), “Job already started”);
// s...
this.foo = checkNotNull(foo); // inline assig
Goodies!
javadoc
this.foo = checkNotNull(foo);
// list, string or array checks
checkElementIndex(index, size);
checkPositionIndex(index, si...
Preconditions will save your ass
Bottom line
Basics
Objects
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null || obj.getClass() != this....
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null || obj.getClass() != this....
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null || obj.getClass() != this....
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null || obj.getClass() != this....
@Override
public boolean equals(Object obj) {
if (obj instanceof Person) {
Person that = (Person) obj;
return Objects.equa...
@Override
public boolean equals(Object obj) {
if (obj instanceof Person) {
Person that = (Person) obj;
return Objects.equa...
@Override
public boolean equals(Object obj) {
if (obj instanceof Person) {
Person that = (Person) obj;
return Objects.equa...
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((firstName == null) ? 0...
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((firstName == null) ? 0...
@Override
public int hashCode() {
return Objects.hashCode(firstName, lastName);
}
Basics: Objects
@Override
public int hashCode() {
// sensible, order-sensitive hash
return Objects.hashCode(firstName, lastName);
}
Basics...
@Override
public int hashCode() {
return Objects.hashCode(firstName, lastName);
}
// JDK 1.7 introduced equivalent Objects...
@Override
public String toString() {
}
Basics: Objects
@Override
public String toString() {
}
Basics: Objects
@Override
public String toString() {
return Objects.toStringHelper(this)
.add("firstName", firstName)
.add("lastName", las...
@Override
public String toString() {
return Objects.toStringHelper(this)
.add("firstName", firstName)
.add("lastName", las...
@Override
public String toString() {
return Objects.toStringHelper(this)
.add("firstName", firstName)
.add("lastName", las...
@Override
public String toString() {
return Objects.toStringHelper(this)
.add("firstName", firstName)
.add("lastName", las...
IntelliJ IDEA support for ToStringHelper()
Generate toString() > Template Objects.ToStringHelper (Guava)
Goodies!
javadoc
So common stuff should ring a bell
Bottom line
Basics
Ordering
Comparator<Person> byDescAgeName = new Comparator<Person>() {
public int compare(Person p1, Person p2) {
int result = p2.g...
Comparator<Person> byDescAgeName = new Comparator<Person>() {
public int compare(Person p1, Person p2) {
int result = p2.g...
Comparator<Person> byDescAgeName = new Comparator<Person>() {
public int compare(Person p1, Person p2) {
return Comparison...
Comparator<Person> byDescAgeName = new Comparator<Person>() {
public int compare(Person p1, Person p2) {
return Comparison...
Comparator<Person> byDescAgeName =
Ordering.natural()
.reverse()
.onResultOf(new Function<Person, Integer>() {
public Inte...
Comparator<Person> byDescAgeName =
Ordering.natural()
.reverse()
.onResultOf(new Function<Person, Integer>() {
public Inte...
Ordering is an “enriched” Comparator. It’s fuuuuuuuun!
Goodies!
javadoc
Ordering is an “enriched” Comparator. It’s fluent.
Goodies!
javadoc
Ordering is an “enriched” Comparator. It’s fluent.
// Subclass Ordering and implement compare(T,T)
Ordering<Throwable> ORD...
Ordering is an “enriched” Comparator. It’s fluent.
// Subclass Ordering and implement compare(T,T)
Ordering<Throwable> ORD...
Ordering is an “enriched” Comparator. It’s fluent.
// Subclass Ordering and implement compare(T,T)
Ordering<Throwable> ORD...
There’s a better way than Comparator
Bottom line
Basics
Throwables
void oneLineOfCode() {
DatagramPacket packet = new DatagramPacket(data, length);
}
Basics: Throwables
void oneLineOfCode() {
DatagramPacket packet = new DatagramPacket(data, length);
}
// Compile error, throws IOException
Ba...
void oneLineOfCode() throws IOException {
DatagramPacket packet = new DatagramPacket(data, length);
}
void someLayer() {
o...
void oneLineOfCode() throws IOException {
DatagramPacket packet = new DatagramPacket(data, length);
}
void someLayer() {
o...
void oneLineOfCode() throws IOException {
DatagramPacket packet = new DatagramPacket(data, length);
}
void someLayer() thr...
void oneLineOfCode() throws IOException {
DatagramPacket packet = new DatagramPacket(data, length);
}
void someLayer() thr...
void oneLineOfCode() throws IOException {
DatagramPacket packet = new DatagramPacket(data, length);
}
void someLayer() thr...
void oneLineOfCode() throws IOException {
DatagramPacket packet = new DatagramPacket(data, address);
}
void someLayer() th...
void oneLineOfCode() {
// Take 2
DatagramPacket packet = new DatagramPacket(data, length);
}
Basics: Throwables
void oneLineOfCode() {
try {
DatagramPacket packet = new DatagramPacket(data, length);
} catch (IOException e) {
}
}
Basic...
void oneLineOfCode() {
try {
DatagramPacket packet = new DatagramPacket(data, length);
} catch (IOException e) {
// Really...
void oneLineOfCode() {
try {
DatagramPacket packet = new DatagramPacket(data, length);
} catch (IOException e) {
SendMeAnE...
void oneLineOfCode() {
try {
DatagramPacket packet = new DatagramPacket(data, length);
} catch (IOException e) {
SendMeAnE...
void oneLineOfCode() {
try {
DatagramPacket packet = new DatagramPacket(data, length);
} catch (IOException e) {
SendMeAnE...
void oneLineOfCode() {
try {
DatagramPacket packet = new DatagramPacket(data, length);
} catch (IOException e) {
SendMeAnE...
void oneLineOfCode() {
try {
DatagramPacket packet = new DatagramPacket(data, address);
} catch (IOException e) {
SendMeAn...
void oneLineOfCode() {
// Take 3
DatagramPacket packet = new DatagramPacket(data, length);
}
Basics: Throwables
void oneLineOfCode() {
try {
DatagramPacket packet = new DatagramPacket(data, length);
} catch (IOException e) {
handle(e)...
void oneLineOfCode() {
try {
DatagramPacket packet = new DatagramPacket(data, length);
} catch (IOException e) {
throw new...
void oneLineOfCode() {
try {
DatagramPacket packet = new DatagramPacket(data, length);
} catch (IOException e) {
throw Thr...
// more forms
propagateIfInstanceOf(throwable,exceptionClass);
Goodies… or gotcha’s!
javadoc
// more forms
propagateIfInstanceOf(throwable,exceptionClass);
propagateIfPossible(throwable); // Only if RuntimeException...
// more forms
propagateIfInstanceOf(throwable,exceptionClass);
propagateIfPossible(throwable);
propagateIfPossible(throwab...
// more forms
propagateIfInstanceOf(throwable,exceptionClass);
propagateIfPossible(throwable);
propagateIfPossible(throwab...
// more forms
propagateIfInstanceOf(throwable,exceptionClass);
propagateIfPossible(throwable);
propagateIfPossible(throwab...
// more forms
propagateIfInstanceOf(throwable,exceptionClass);
propagateIfPossible(throwable);
propagateIfPossible(throwab...
Think your fraking Exceptions
Bottom line
Strings
Strings
Splitter
We have String.split bro!
Strings: Splitter
We have String.split bro!
“,f,,o, o,”.split(“,”) returns:
Strings: Splitter
We have String.split bro!
“,f,,o, o,”.split(“,”) returns:
a. [“”, “f”, “”, “o”, “ o”,””]
Strings: Splitter
We have String.split bro!
“,f,,o, o,”.split(“,”) returns:
a. [“”, “f”, “”, “o”, “ o”,””]
b. [null, “f”, null, “o” ,”o”, nu...
We have String.split bro!
“,f,,o, o,”.split(“,”) returns:
a. [“”, “f”, “”, “o”, “ o”,””]
b. [null, “f”, null, “o” ,”o”, nu...
We have String.split bro!
“,f,,o, o,”.split(“,”) returns:
a. [“”, “f”, “”, “o”, “ o”,””]
b. [null, “f”, null, “o” ,”o”, nu...
We have String.split bro!
“,f,,o, o,”.split(“,”) returns:
a. [“”, “f”, “”, “o”, “ o”,””]
b. [null, “f”, null, “o” ,”o”, nu...
We have String.split bro!
“,f,,o, o,”.split(“,”) returns:
a. [“”, “f”, “”, “o”, “ o”,””]
b. [null, “f”, null, “o” ,”o”, nu...
We have String.split bro!
“,f,,o, o,”.split(“,”) returns:
a. [“”, “f”, “”, “o”, “ o”,””]
b. [null, “f”, null, “o” ,”o”, nu...
We have String.split bro!
“,f,,o, o,”.split(“,”) returns:
a. [“”, “f”, “”, “o”, “ o”,””]
b. [null, “f”, null, “o” ,”o”, nu...
We have String.split bro!
“,f,,o, o,”.split(“,”) returns:
a. [“”, “f”, “”, “o”, “ o”,””]
b. [null, “f”, null, “o” ,”o”, nu...
“,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”]
Strings: Splitter
“,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”]
Splitter.on(‘,’)
.split(“,f,,o, o,”);
Strings: Splitter
“,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”]
Splitter.on(‘,’)
.split(“,f,,o, o,”);
// returns [“”,”f”,””,”o”,” o”...
“,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”]
Splitter.on(‘,’)
.omitEmptyStrings()
.split(“,f,,o, o,”);
Strings: S...
“,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”]
Splitter.on(‘,’)
.omitEmptyStrings()
.split(“,f,,o, o,”);
// returns...
“,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”]
Splitter.on(‘,’)
.omitEmptyStrings()
.trimResults()
.split(“,f,,o, o...
“,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”]
Splitter.on(‘,’)
.omitEmptyStrings()
.trimResults()
.split(“,f,,o, o...
“,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”]
static final Splitter COMMA = Splitter.on(‘,’)
.omitEmptyStrings()
....
Strings
Joiner
[“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”]
Strings: Joiner
[“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”]
Joiner.on(“, “)
.join(twentyFour);
Strings: Joiner
[“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”]
Joiner.on(“, “)
.join(twentyFour);
// throws NullPointerException!
Strings...
[“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”]
Joiner.on(“, “)
.join(twentyFour);
// throws NullPointerException!
// null...
[“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”]
Joiner.on(“, “)
.skipNulls();
.join(twentyFour);
// returns “Jack, Chloe, ...
[“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”]
Joiner.on(“, “)
.useForNull(“Bill”);
.join(twentyFour);
// returns “Jack, ...
Always think how to avoid null-idioty
Bottom line
Strings
CharMatcher
Your StringUtils replacement
Strings: CharMatcher
Your StringUtils replacement
CharMatcher.JAVA_ISO_CONTROL.removeFrom(string); // remove control chars
Strings: CharMatcher
Your StringUtils replacement
CharMatcher.JAVA_ISO_CONTROL.removeFrom(string);
CharMatcher.DIGIT.retainFrom(“jordi9”); // r...
Your StringUtils replacement
CharMatcher.JAVA_ISO_CONTROL.removeFrom(string);
CharMatcher.DIGIT.retainFrom(“jordi9”);
Char...
Your StringUtils replacement
CharMatcher.JAVA_ISO_CONTROL.removeFrom(string);
CharMatcher.DIGIT.retainFrom(“jordi9”);
Char...
// More matchers
CharMatcher.ANY;
CharMatcher.BREAKING_WHITESPACE;
CharMatcher.WHITESPACE;
CharMatcher.INVISIBLE;
CharMatc...
// More matchers
CharMatcher.ANY;
CharMatcher.BREAKING_WHITESPACE;
CharMatcher.WHITESPACE;
CharMatcher.INVISIBLE;
CharMatc...
Strings
Escapers
HtmlEscapers.htmlEscaper().escape("Foo > bar");
// returns Foo &gt; bar
Escapers
HtmlEscapers.htmlEscaper().escape("Foo > bar");
XmlEscapers.xmlAttributeEscaper().escape("foo "bar"");
// returns foo &quo...
HtmlEscapers.htmlEscaper().escape("Foo > bar");
XmlEscapers.xmlAttributeEscaper().escape("foo "bar"");
XmlEscapers.xmlCont...
HtmlEscapers.htmlEscaper().escape("Foo > bar");
XmlEscapers.xmlAttributeEscaper().escape("foo "bar"");
XmlEscapers.xmlCont...
Collections
Collections: Functional Idiom
Collections: Functional Idiom
Collections: Functional Idiom
Function<String, Integer> lengthFunction = new Function<String, Integer>() {
public Integer apply(String string) {
return ...
Function<String, Integer> lengthFunction = new Function<String, Integer>() {
public Integer apply(String string) {
return ...
Multiset<Integer> lengths = HashMultiset.create();
for (String string : strings) {
if (CharMatcher.JAVA_UPPER_CASE.matches...
Multiset<Integer> lengths = HashMultiset.create();
for (String string : strings) {
if (CharMatcher.JAVA_UPPER_CASE.matches...
Multiset<Integer> lengths = HashMultiset.create();
for (String string : strings) {
if (CharMatcher.JAVA_UPPER_CASE.matches...
Immutable = Thread-safe
Collections: Immutable types
Immutable = Thread-safe
static final ImmutableSet<String> FOO_NAMES =
ImmutableSet.of(“foo”, “bar”, “baz”);
Collections: I...
Immutable = Thread-safe
static final ImmutableSet<String> FOO_NAMES =
ImmutableSet.of(“foo”, “bar”, “baz”);
// ImmutableLi...
Immutable = Thread-safe
static final ImmutableSet<String> FOO_NAMES =
ImmutableSet.of(“foo”, “bar”, “baz”);
ImmutableList<...
Immutable = Thread-safe
static final ImmutableSet<String> FOO_NAMES =
ImmutableSet.of(“foo”, “bar”, “baz”);
ImmutableList<...
A bag
Collections: Multiset<E>
A bag
Just like a Set<E> with repeated values
Collections: Multiset<E>
A bag
Just like a Set<E> with repeated values
You’ve done this with ArrayList<E> or Map<E, Integer>
Collections: Multiset<...
A bag
Just like a Set<E> with repeated values
You’ve done this with ArrayList<E> or Map<E, Integer>
Multiset<Person> ppl =...
A bag
Just like a Set<E> with repeated values
You’ve done this with ArrayList<E> or Map<E, Integer>
Multiset<Person> ppl =...
A bag
Just like a Set<E> with repeated values
You’ve done this with ArrayList<E> or Map<E, Integer>
Multiset<Person> ppl =...
A bag
Just like a Set<E> with repeated values
You’ve done this with ArrayList<E> or Map<E, Integer>
Multiset<Person> ppl =...
A bag
Just like a Set<E> with repeated values
You’ve done this with ArrayList<E> or Map<E, Integer>
Multiset<Person> ppl =...
A bag
Just like a Set<E> with repeated values
You’ve done this with ArrayList<E> or Map<E, Integer>
Multiset<Person> ppl =...
A Map<K, V> with multiple values
Collections: Multimap<K, V>
A Map<K, V> with multiple values
You’ve done this with Map<K, List<V>>
Collections: Multimap<K, V>
A Map<K, V> with multiple values
You’ve done this with Map<K, List<V>>
Multimap<Person, Ticket> ticketsByPerson =
ArrayLis...
A Map<K, V> with multiple values
You’ve done this with Map<K, List<V>>
Multimap<Person, Ticket> ticketsByPerson =
ArrayLis...
A Map<K, V> with multiple values
You’ve done this with Map<K, List<V>>
Multimap<Person, Ticket> ticketsByPerson =
ArrayLis...
A Map<K, V> with multiple values
You’ve done this with Map<K, List<V>>
Multimap<Person, Ticket> ticketsByPerson =
ArrayLis...
// Bi-directional map, keys and values are unique
BiMap<K1, K2>
Goodies!
javadoc
// Bi-directional map, keys and values are unique
BiMap<K1, K2>
// Two-tier map, or a map with two keys
Table<R, C, V>
Goo...
// Bi-directional map, keys and values are unique
BiMap<K1, K2>
// Two-tier map, or a map with two keys
Table<R, C, V>
// ...
// Bi-directional map, keys and values are unique
BiMap<K1, K2>
// Two-tier map, or a map with two keys
Table<R, C, V>
// ...
Tons of good abstractions for you to use
Bottom line
Hashing
Freaking PHP: md5($string)
Hashing: JDK
Freaking PHP: md5($string)
public static String md5Java(String message) {
String digest = null;
try {
MessageDigest md = M...
Freaking PHP: md5($string)
public static String md5Java(String message) {
String digest = null;
try {
MessageDigest md = M...
HashFunction hf = Hashing.md5();
Hashing: Hasher
HashFunction hf = Hashing.md5();
HashCode hc = hf.newHasher()
.putLong(id)
.putString(name, Charsets.UTF_8)
.putObject(per...
HashFunction hf = Hashing.md5();
HashCode hc = hf.newHasher()
.putLong(id)
.putString(name, Charsets.UTF_8)
.putObject(per...
HashFunction hf = Hashing.md5();
HashCode hc = hf.newHasher()
.putLong(id)
.putString(name, Charsets.UTF_8) // HINT: remem...
HashFunction hf = Hashing.md5();
HashCode hc = hf.newHasher()
.putLong(id)
.putString(name, Charsets.UTF_8)
.putObject(per...
// More hash functions!
Hashing.md5();
Hashing.murmur3_32();
Hashing.murmur3_128();
Hashing.sha1();
Hashing.sha256();
Hash...
// More hash functions!
Hashing.md5();
Hashing.murmur3_32();
Hashing.murmur3_128();
Hashing.sha1();
Hashing.sha256();
Hash...
I/O
Binary encoding scheme, RFC 4648
I/O: BaseEncoding
Binary encoding scheme, RFC 4648 -- Serious stuff
I/O: BaseEncoding
Binary encoding scheme, RFC 4648
BaseEncoding
.base32()
.encode("foo".getBytes(Charsets.US_ASCII));
I/O: BaseEncoding
Binary encoding scheme, RFC 4648
BaseEncoding
.base32()
.encode("foo".getBytes(Charsets.US_ASCII));
// returns MZXW6===
I/...
Binary encoding scheme, RFC 4648
BaseEncoding
.base32()
.encode("foo".getBytes(Charsets.US_ASCII));
// returns MZXW6===
by...
Binary encoding scheme, RFC 4648
BaseEncoding
.base32()
.encode("foo".getBytes(Charsets.US_ASCII));
// returns MZXW6===
by...
// More schemas
BaseEncoding.base16();
BaseEncoding.base32();
BaseEncoding.base64();
BaseEncoding.base64Url(); // Useful a...
KIA
KIA
Caches EventBus
KIA
Caches
Networking
EventBus
Concurrency
KIA
Caches
Networking
Math
EventBus
Concurrency
More I/O
KIA
Caches
Networking
Math
Reflection
EventBus
Concurrency
More I/O
Collect
KIA
Caches
Networking
Math
Reflection
Primitives
EventBus
Concurrency
More I/O
Collect
Grumpy
Your friends
Wiki
Your friends
Wiki
javadoc
Remember
The “wheel”
Remember
Read this code
Remember
No Grumpy Cats were
harmed in the making of
this presentation
Thanks!
jordi@donky.org
@jordi9
Q & A
jordi@donky.org
@jordi9
Google Guava - Core libraries for Java & Android
Upcoming SlideShare
Loading in...5
×

Google Guava - Core libraries for Java & Android

7,820

Published on

Talk at GDG DevFest Barcelona 2013.

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.

Published in: Technology, News & Politics
0 Comments
45 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
7,820
On Slideshare
0
From Embeds
0
Number of Embeds
11
Actions
Shares
0
Downloads
210
Comments
0
Likes
45
Embeds 0
No embeds

No notes for slide

Transcript of "Google Guava - Core libraries for Java & Android"

  1. 1. Google Guava Core libraries for Java & Android @jordi9 11 / oct / 2013
  2. 2. ...shameless self-promotion bro!
  3. 3. Write less code
  4. 4. Write cleaner code
  5. 5. Write more readable code
  6. 6. The “wheel”
  7. 7. com.google.guava:guava:15.0
  8. 8. Basics
  9. 9. Basics Avoid using null
  10. 10. Basics: Avoid using null “Null sucks” Doug Lea - JCP, OpenJDK
  11. 11. Basics: Avoid using null “I call it my billion-dollar mistake” Sir C.A.R. Hoare - Inventor of null
  12. 12. Basics: Avoid using null @Google 95% of collections weren’t supposed to have null values.
  13. 13. map = {Foo: bar, null, Baz: qux} Basics: Avoid using null
  14. 14. map = {Foo: bar, null, Baz: qux} map.get(“Foo”); Basics: Avoid using null
  15. 15. map = {Foo: bar, null, Baz: qux} map.get(“Foo”); // returns Foo Basics: Avoid using null
  16. 16. map = {Foo: bar, null, Baz: qux} map.get(“Foo”); map.get(“quux”); Basics: Avoid using null
  17. 17. map = {Foo: bar, null, Baz: qux} map.get(“Foo”); map.get(“quux”); // returns null Basics: Avoid using null
  18. 18. map = {Foo: bar, null, Baz: qux} map.get(“Foo”); map.get(“quux”); map.get(null); Basics: Avoid using null
  19. 19. map = {Foo: bar, null, Baz: qux} map.get(“Foo”); map.get(“quux”); map.get(null); // returns null Basics: Avoid using null
  20. 20. map = {Foo: bar, null, Baz: qux} map.get(“Foo”); map.get(“quux”); // returns null map.get(null); // returns null Basics: Avoid using null
  21. 21. map = {Foo: bar, null, Baz: qux} map.get(“Foo”); map.get(“quux”); // returns null map.get(null); // returns null // Null to indicate absence // vs null value Basics: Avoid using null
  22. 22. Optional<T> Basics: Avoid using null
  23. 23. Optional<T> Optional<String> foo = Optional.of(“foo”) Basics: Avoid using null
  24. 24. Optional<T> Optional<String> foo = Optional.of(“foo”) foo.isPresent(); // returns true Basics: Avoid using null
  25. 25. Optional<T> Optional<String> foo = Optional.of(“foo”) foo.isPresent(); foo.get(); // returns “foo” Basics: Avoid using null
  26. 26. Optional.of(foo); // not nullable Goodies! RTFM, I mean javadoc
  27. 27. Optional.of(foo); Optional.absent(); Goodies! javadoc
  28. 28. Optional.of(foo); Optional.absent(); Optional.fromNullable(legacyCode); Goodies! javadoc
  29. 29. Optional.of(foo); Optional.absent(); Optional.fromNullable(legacyCode); foo.get(); // may return “foo” Goodies! javadoc
  30. 30. Optional.of(foo); Optional.absent(); Optional.fromNullable(legacyCode); foo.get(); foo.or(“bar”); // return “bar” if foo is absent Goodies! javadoc
  31. 31. Optional.of(foo); Optional.absent(); Optional.fromNullable(legacyCode); foo.get(); foo.or(“bar”); foo.orNull(); // Deal with code that need nulls, duh Goodies! javadoc
  32. 32. Optional<T> is IDIOT-PROOF-NESS Bottom line
  33. 33. Basics Preconditions
  34. 34. if (seats <= 0) { throw new IllegalArgumentException(“Seats must be positive, but was ” + seats); } Basics: Preconditions
  35. 35. if (seats <= 0) { throw new IllegalArgumentException(“Seats must be positive, but was ” + seats); } checkArgument(seats > 0, “Seats must be positive, but was %s”, seats); Basics: Preconditions
  36. 36. // Always use static import import static com.google.common.base.Preconditions.checkArgument; checkArgument(seats > 0, “Seats must be positive, but was %s”, seats); Basics: Preconditions
  37. 37. import static com.google.common.base.Preconditions.checkArgument; // Check what you expect to be true checkArgument(seats > 0, “Seats must be positive, but was %s”, seats); Basics: Preconditions
  38. 38. import static com.google.common.base.Preconditions.checkArgument; // “%s” specifier is recognized as a placeholder in // these messages (the only one) checkArgument(seats > 0, “Seats must be positive, but was %s”, seats); Basics: Preconditions
  39. 39. void execute(Job job) { // serious business } Basics: Preconditions
  40. 40. void execute(Job job) { checkNotNull(job, “Job can’t be null”); // serious business } // checkNotNull() throws NullPointerException Basics: Preconditions
  41. 41. void execute(Job job) { checkNotNull(job, “Job can’t be null”); checkArgument(!job.started(), “Job already started”); // serious business } // checkArgument() throws IllegalArgumentException // checkNotNull() throws NullPointerException Basics: Preconditions
  42. 42. void execute(Job job) { checkNotNull(job, “Job can’t be null”); checkArgument(!job.started(), “Job already started”); // serious business checkState(seatsAvailabe <= totalSeats, “You’ve sold more seats than available! This should never happen. %s/%s”, seatsAvailable, totalSeats); } // checkState() throws IllegalStateException // checkArgument() throws IllegalArgumentException // checkNotNull() throws NullPointerException Basics: Preconditions
  43. 43. this.foo = checkNotNull(foo); // inline assig Goodies! javadoc
  44. 44. this.foo = checkNotNull(foo); // list, string or array checks checkElementIndex(index, size); checkPositionIndex(index, size); checkPositionIndexes(start, end, size); Goodies! javadoc
  45. 45. Preconditions will save your ass Bottom line
  46. 46. Basics Objects
  47. 47. @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj == null || obj.getClass() != this.getClass()) { return false; } Person guest = (Person) obj; return id == guest.id && (firstName == guest.firstName || (firstName != null && firstName.equals(guest.getFirstName()))) && (lastName == guest.lastName || (lastName != null && lastName.equals(guest.getLastName()))); } Basics: Objects
  48. 48. @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj == null || obj.getClass() != this.getClass()) { return false; } Person guest = (Person) obj; return id == guest.id && (firstName == guest.firstName || (firstName != null && firstName.equals(guest.getFirstName()))) && (lastName == guest.lastName || (lastName != null && lastName.equals(guest.getLastName()))); } Basics: Objects F
  49. 49. @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj == null || obj.getClass() != this.getClass()) { return false; } Person guest = (Person) obj; return id == guest.id && (firstName == guest.firstName || (firstName != null && firstName.equals(guest.getFirstName()))) && (lastName == guest.lastName || (lastName != null && lastName.equals(guest.getLastName()))); } Basics: Objects FM
  50. 50. @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj == null || obj.getClass() != this.getClass()) { return false; } Person guest = (Person) obj; return id == guest.id && (firstName == guest.firstName || (firstName != null && firstName.equals(guest.getFirstName()))) && (lastName == guest.lastName || (lastName != null && lastName.equals(guest.getLastName()))); } Basics: Objects FML
  51. 51. @Override public boolean equals(Object obj) { if (obj instanceof Person) { Person that = (Person) obj; return Objects.equal(firstName, that.firstName) && Objects.equal(lastName, that.lastName); } else { return false; } } Basics: Objects
  52. 52. @Override public boolean equals(Object obj) { if (obj instanceof Person) { Person that = (Person) obj; return Objects.equal(firstName, that.firstName) // null safe! && Objects.equal(lastName, that.lastName); // null safe x2! } else { return false; } } Basics: Objects
  53. 53. @Override public boolean equals(Object obj) { if (obj instanceof Person) { Person that = (Person) obj; return Objects.equal(firstName, that.firstName) && Objects.equal(lastName, that.lastName); } else { return false; } } // JDK 1.7 introduced equivalent Objects.equals() method. Basics: Objects
  54. 54. @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((firstName == null) ? 0 : firstName.hashCode()); result = prime * result + id; result = prime * result + ((lastName == null) ? 0 : lastName.hashCode()); return result; } Basics: Objects
  55. 55. @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((firstName == null) ? 0 : firstName.hashCode()); result = prime * result + id; result = prime * result + ((lastName == null) ? 0 : lastName.hashCode()); return result; } // oh, grumpy cat! Basics: Objects
  56. 56. @Override public int hashCode() { return Objects.hashCode(firstName, lastName); } Basics: Objects
  57. 57. @Override public int hashCode() { // sensible, order-sensitive hash return Objects.hashCode(firstName, lastName); } Basics: Objects
  58. 58. @Override public int hashCode() { return Objects.hashCode(firstName, lastName); } // JDK 1.7 introduced equivalent Objects.hash() method. Basics: Objects
  59. 59. @Override public String toString() { } Basics: Objects
  60. 60. @Override public String toString() { } Basics: Objects
  61. 61. @Override public String toString() { return Objects.toStringHelper(this) .add("firstName", firstName) .add("lastName", lastName) .add("catName", catName) .toString(); } Basics: Objects
  62. 62. @Override public String toString() { return Objects.toStringHelper(this) .add("firstName", firstName) .add("lastName", lastName) .add("catName", catName) .toString(); } // returns Person{firstName=Solid, lastName=Snake, catName=null} Basics: Objects
  63. 63. @Override public String toString() { return Objects.toStringHelper(this) .add("firstName", firstName) .add("lastName", lastName) .add("catName", catName) .omitNullValues() .toString(); } Basics: Objects
  64. 64. @Override public String toString() { return Objects.toStringHelper(this) .add("firstName", firstName) .add("lastName", lastName) .add("catName", catName) .omitNullValues() .toString(); } // returns Person{firstName=Solid, lastName=Snake} Basics: Objects
  65. 65. IntelliJ IDEA support for ToStringHelper() Generate toString() > Template Objects.ToStringHelper (Guava) Goodies! javadoc
  66. 66. So common stuff should ring a bell Bottom line
  67. 67. Basics Ordering
  68. 68. Comparator<Person> byDescAgeName = new Comparator<Person>() { public int compare(Person p1, Person p2) { int result = p2.getAge() - p1.getAge(); // ugh! return (result == 0) ? p1.compareTo(p2) : result; } }; // Ok, it’s not that bad -- But it’s pretty hard to get Basics: Ordering
  69. 69. Comparator<Person> byDescAgeName = new Comparator<Person>() { public int compare(Person p1, Person p2) { int result = p2.getAge() - p1.getAge(); // ugh! return (result == 0) ? p1.compareTo(p2) : result; } }; // Ok, it’s not that bad -- But it’s pretty hard to get // We’re lucky ints and Person are Comparable, otherwise you’ll // have to implement it Basics: Ordering
  70. 70. Comparator<Person> byDescAgeName = new Comparator<Person>() { public int compare(Person p1, Person p2) { return ComparisonChain.start() .compare(p2.getAge(), p1.getAge()) .compare(p1, p2) .result(); } }; Basics: Ordering
  71. 71. Comparator<Person> byDescAgeName = new Comparator<Person>() { public int compare(Person p1, Person p2) { return ComparisonChain.start() .compare(p2.getAge(), p1.getAge()) .compare(p1, p2) .result(); } }; // Short-circuits: If one comparison is not equals, stop and return Basics: Ordering
  72. 72. Comparator<Person> byDescAgeName = Ordering.natural() .reverse() .onResultOf(new Function<Person, Integer>() { public Integer apply(Person person) { return person.getAge(); }}) .compound(Ordering.natural()); } }; Basics: Ordering
  73. 73. Comparator<Person> byDescAgeName = Ordering.natural() .reverse() .onResultOf(new Function<Person, Integer>() { public Integer apply(Person person) { return person.getAge(); }}) .compound(Ordering.natural()); } }; // Read backwards Basics: Ordering
  74. 74. Ordering is an “enriched” Comparator. It’s fuuuuuuuun! Goodies! javadoc
  75. 75. Ordering is an “enriched” Comparator. It’s fluent. Goodies! javadoc
  76. 76. Ordering is an “enriched” Comparator. It’s fluent. // Subclass Ordering and implement compare(T,T) Ordering<Throwable> ORDER_BY_CLASS_NAME = (left, right) -> { return Ordering.usingToString() .compare(left.getClass(), right.getClass()); }; Goodies! javadoc
  77. 77. Ordering is an “enriched” Comparator. It’s fluent. // Subclass Ordering and implement compare(T,T) Ordering<Throwable> ORDER_BY_CLASS_NAME = (left, right) -> { return Ordering.usingToString() .compare(left.getClass(), right.getClass()); }; // Or create one Ordering.from(comparator); Ordering.natural(); Goodies! javadoc
  78. 78. Ordering is an “enriched” Comparator. It’s fluent. // Subclass Ordering and implement compare(T,T) Ordering<Throwable> ORDER_BY_CLASS_NAME = (left, right) -> { return Ordering.usingToString() .compare(left.getClass(), right.getClass()); }; // Or create one Ordering.from(comparator); Ordering.natural(); // And chain! ORDER_BY_CLASS_NAME.nullsFirst().reverse().compound(comparator); Goodies! javadoc
  79. 79. There’s a better way than Comparator Bottom line
  80. 80. Basics Throwables
  81. 81. void oneLineOfCode() { DatagramPacket packet = new DatagramPacket(data, length); } Basics: Throwables
  82. 82. void oneLineOfCode() { DatagramPacket packet = new DatagramPacket(data, length); } // Compile error, throws IOException Basics: Throwables
  83. 83. void oneLineOfCode() throws IOException { DatagramPacket packet = new DatagramPacket(data, length); } void someLayer() { oneLineOfCode(); } Basics: Throwables
  84. 84. void oneLineOfCode() throws IOException { DatagramPacket packet = new DatagramPacket(data, length); } void someLayer() { oneLineOfCode(); } // Compile error, throws IOException Basics: Throwables
  85. 85. void oneLineOfCode() throws IOException { DatagramPacket packet = new DatagramPacket(data, length); } void someLayer() throws IOException { oneLineOfCode(); } void someCoolAbstraction() { someLayer(); } Basics: Throwables
  86. 86. void oneLineOfCode() throws IOException { DatagramPacket packet = new DatagramPacket(data, length); } void someLayer() throws IOException { oneLineOfCode(); } void someCoolAbstraction() { someLayer(); } // Compile error, AGAIN Basics: Throwables
  87. 87. void oneLineOfCode() throws IOException { DatagramPacket packet = new DatagramPacket(data, length); } void someLayer() throws IOException { oneLineOfCode(); } void someCoolAbstraction() throws IOException { someLayer(); } Basics: Throwables
  88. 88. void oneLineOfCode() throws IOException { DatagramPacket packet = new DatagramPacket(data, address); } void someLayer() throws IOException { oneLineOfCode(); } void someCoolAbstraction() throws IOException { someLayer(); } // c’mon... Basics: Throwables
  89. 89. void oneLineOfCode() { // Take 2 DatagramPacket packet = new DatagramPacket(data, length); } Basics: Throwables
  90. 90. void oneLineOfCode() { try { DatagramPacket packet = new DatagramPacket(data, length); } catch (IOException e) { } } Basics: Throwables
  91. 91. void oneLineOfCode() { try { DatagramPacket packet = new DatagramPacket(data, length); } catch (IOException e) { // Really? Swallow? Sure? At least explain why! } } Basics: Throwables
  92. 92. void oneLineOfCode() { try { DatagramPacket packet = new DatagramPacket(data, length); } catch (IOException e) { SendMeAnEmail.error(); } } Basics: Throwables
  93. 93. void oneLineOfCode() { try { DatagramPacket packet = new DatagramPacket(data, length); } catch (IOException e) { SendMeAnEmail.error(); Oh.theLogger().fatal(“WHY Y U FATAL NOW?”); } } Basics: Throwables
  94. 94. void oneLineOfCode() { try { DatagramPacket packet = new DatagramPacket(data, length); } catch (IOException e) { SendMeAnEmail.error(); Oh.theLogger().fatal(“WHY Y U FATAL NOW?”); // repeat for every catch block } } Basics: Throwables
  95. 95. void oneLineOfCode() { try { DatagramPacket packet = new DatagramPacket(data, length); } catch (IOException e) { SendMeAnEmail.error(); Oh.theLogger().fatal(“WHY Y U FATAL NOW?”); // repeat for every catch block // AGAIN AND AGAIN } } Basics: Throwables
  96. 96. void oneLineOfCode() { try { DatagramPacket packet = new DatagramPacket(data, address); } catch (IOException e) { SendMeAnEmail.error(); Oh.theLogger().fatal(“WHY Y U FATAL NOW?”); // repeat for every catch block // AGAIN AND AGAIN } } Basics: Throwables
  97. 97. void oneLineOfCode() { // Take 3 DatagramPacket packet = new DatagramPacket(data, length); } Basics: Throwables
  98. 98. void oneLineOfCode() { try { DatagramPacket packet = new DatagramPacket(data, length); } catch (IOException e) { handle(e); } } // We know what to do with this Exception, like recover Basics: Throwables
  99. 99. void oneLineOfCode() { try { DatagramPacket packet = new DatagramPacket(data, length); } catch (IOException e) { throw new MyException(e); } } // Translate the Exception to another one more suitable Basics: Throwables
  100. 100. void oneLineOfCode() { try { DatagramPacket packet = new DatagramPacket(data, length); } catch (IOException e) { throw Throwables.propagate(e); } } // Propagates the throwable as-is if it is a RuntimeException or // an Error, or wraps it in a RuntimeException and throws it // otherwise. Basics: Throwables
  101. 101. // more forms propagateIfInstanceOf(throwable,exceptionClass); Goodies… or gotcha’s! javadoc
  102. 102. // more forms propagateIfInstanceOf(throwable,exceptionClass); propagateIfPossible(throwable); // Only if RuntimeException or Error Goodies… or gotcha’s! javadoc
  103. 103. // more forms propagateIfInstanceOf(throwable,exceptionClass); propagateIfPossible(throwable); propagateIfPossible(throwable, exceptionClass); Goodies… or gotcha’s! javadoc
  104. 104. // more forms propagateIfInstanceOf(throwable,exceptionClass); propagateIfPossible(throwable); propagateIfPossible(throwable, exceptionClass); General practice: Convert checked exceptions to unchecked exceptions Goodies… or gotcha’s! javadoc
  105. 105. // more forms propagateIfInstanceOf(throwable,exceptionClass); propagateIfPossible(throwable); propagateIfPossible(throwable, exceptionClass); General practice: Convert checked exceptions to unchecked exceptions Checked exceptions... are a bad idea? Goodies… or gotcha’s! javadoc
  106. 106. // more forms propagateIfInstanceOf(throwable,exceptionClass); propagateIfPossible(throwable); propagateIfPossible(throwable, exceptionClass); General practice: Convert checked exceptions to unchecked exceptions Checked exceptions... are a bad idea? Don’t use propagate() to ignore IOExceptions and so on Goodies… or gotcha’s! javadoc
  107. 107. Think your fraking Exceptions Bottom line
  108. 108. Strings
  109. 109. Strings Splitter
  110. 110. We have String.split bro! Strings: Splitter
  111. 111. We have String.split bro! “,f,,o, o,”.split(“,”) returns: Strings: Splitter
  112. 112. We have String.split bro! “,f,,o, o,”.split(“,”) returns: a. [“”, “f”, “”, “o”, “ o”,””] Strings: Splitter
  113. 113. We have String.split bro! “,f,,o, o,”.split(“,”) returns: a. [“”, “f”, “”, “o”, “ o”,””] b. [null, “f”, null, “o” ,”o”, null] Strings: Splitter
  114. 114. We have String.split bro! “,f,,o, o,”.split(“,”) returns: a. [“”, “f”, “”, “o”, “ o”,””] b. [null, “f”, null, “o” ,”o”, null] c. [“f”, null, “o”, “o”] Strings: Splitter
  115. 115. We have String.split bro! “,f,,o, o,”.split(“,”) returns: a. [“”, “f”, “”, “o”, “ o”,””] b. [null, “f”, null, “o” ,”o”, null] c. [“f”, null, “o”, “o”] d. [“f”, ”o”, ”o”] Strings: Splitter
  116. 116. We have String.split bro! “,f,,o, o,”.split(“,”) returns: a. [“”, “f”, “”, “o”, “ o”,””] b. [null, “f”, null, “o” ,”o”, null] c. [“f”, null, “o”, “o”] d. [“f”, ”o”, ”o”] e. None of above Strings: Splitter
  117. 117. We have String.split bro! “,f,,o, o,”.split(“,”) returns: a. [“”, “f”, “”, “o”, “ o”,””] b. [null, “f”, null, “o” ,”o”, null] c. [“f”, null, “o”, “o”] d. [“f”, ”o”, ”o”] e. None of above Strings: Splitter
  118. 118. We have String.split bro! “,f,,o, o,”.split(“,”) returns: a. [“”, “f”, “”, “o”, “ o”,””] b. [null, “f”, null, “o” ,”o”, null] c. [“f”, null, “o”, “o”] d. [“f”, ”o”, ”o”] e. None of above Strings: Splitter
  119. 119. We have String.split bro! “,f,,o, o,”.split(“,”) returns: a. [“”, “f”, “”, “o”, “ o”,””] b. [null, “f”, null, “o” ,”o”, null] c. [“f”, null, “o”, “o”] d. [“f”, ”o”, ”o”] e. None of above Returns: [“”, “f”, “”, “o”, “ o”] Strings: Splitter
  120. 120. We have String.split bro! “,f,,o, o,”.split(“,”) returns: a. [“”, “f”, “”, “o”, “ o”,””] b. [null, “f”, null, “o” ,”o”, null] c. [“f”, null, “o”, “o”] d. [“f”, ”o”, ”o”] e. None of above Returns: [“”, “f”, “”, “o”, “ o”] Only trailing empty strings are skipped. Strings: Splitter
  121. 121. “,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”] Strings: Splitter
  122. 122. “,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”] Splitter.on(‘,’) .split(“,f,,o, o,”); Strings: Splitter
  123. 123. “,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”] Splitter.on(‘,’) .split(“,f,,o, o,”); // returns [“”,”f”,””,”o”,” o”,””] // Doesn’t discard trailing separators! Strings: Splitter
  124. 124. “,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”] Splitter.on(‘,’) .omitEmptyStrings() .split(“,f,,o, o,”); Strings: Splitter
  125. 125. “,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”] Splitter.on(‘,’) .omitEmptyStrings() .split(“,f,,o, o,”); // returns [”f”,”o”,” o”] // Empty space is respected Strings: Splitter
  126. 126. “,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”] Splitter.on(‘,’) .omitEmptyStrings() .trimResults() .split(“,f,,o, o,”); Strings: Splitter
  127. 127. “,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”] Splitter.on(‘,’) .omitEmptyStrings() .trimResults() .split(“,f,,o, o,”); // returns [”f”,”o”,”o”] -- yay! Strings: Splitter
  128. 128. “,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”] static final Splitter COMMA = Splitter.on(‘,’) .omitEmptyStrings() .trimResults() .split(“,f,,o, o,”); // Best practice: declare Splitters as static final Strings: Splitter javadoc
  129. 129. Strings Joiner
  130. 130. [“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”] Strings: Joiner
  131. 131. [“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”] Joiner.on(“, “) .join(twentyFour); Strings: Joiner
  132. 132. [“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”] Joiner.on(“, “) .join(twentyFour); // throws NullPointerException! Strings: Joiner
  133. 133. [“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”] Joiner.on(“, “) .join(twentyFour); // throws NullPointerException! // null-hostile operations everywhere, good thing ;) Strings: Joiner
  134. 134. [“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”] Joiner.on(“, “) .skipNulls(); .join(twentyFour); // returns “Jack, Chloe, Tony, Nina, Logan” Strings: Joiner
  135. 135. [“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”] Joiner.on(“, “) .useForNull(“Bill”); .join(twentyFour); // returns “Jack, Chloe, Tony, Bill, Nina, Logan” Strings: Joiner javadoc
  136. 136. Always think how to avoid null-idioty Bottom line
  137. 137. Strings CharMatcher
  138. 138. Your StringUtils replacement Strings: CharMatcher
  139. 139. Your StringUtils replacement CharMatcher.JAVA_ISO_CONTROL.removeFrom(string); // remove control chars Strings: CharMatcher
  140. 140. Your StringUtils replacement CharMatcher.JAVA_ISO_CONTROL.removeFrom(string); CharMatcher.DIGIT.retainFrom(“jordi9”); // returns 9 Strings: CharMatcher
  141. 141. Your StringUtils replacement CharMatcher.JAVA_ISO_CONTROL.removeFrom(string); CharMatcher.DIGIT.retainFrom(“jordi9”); CharMatcher.DIGIT.removeFrom(“jordi9”); // returns jordi Strings: CharMatcher
  142. 142. Your StringUtils replacement CharMatcher.JAVA_ISO_CONTROL.removeFrom(string); CharMatcher.DIGIT.retainFrom(“jordi9”); CharMatcher.DIGIT.removeFrom(“jordi9”); CharMatcher.DIGIT.or(CharMatcher.JAVA_UPPER_CASE).retainFrom(“Jordi9”); // returns J9 Strings: CharMatcher
  143. 143. // More matchers CharMatcher.ANY; CharMatcher.BREAKING_WHITESPACE; CharMatcher.WHITESPACE; CharMatcher.INVISIBLE; CharMatcher.DIGIT; // Unicode CharMatcher.JAVA_DIGIT; // Java’s definition CharMatcher.is(char); CharMatcher.isNot(char); Goodies! javadoc
  144. 144. // More matchers CharMatcher.ANY; CharMatcher.BREAKING_WHITESPACE; CharMatcher.WHITESPACE; CharMatcher.INVISIBLE; CharMatcher.DIGIT; // Unicode CharMatcher.JAVA_DIGIT; // Java’s definition CharMatcher.is(char); CharMatcher.isNot(char); // And operations .replaceFrom(charSequence, replacement); .collapseFrom(charSequence, replacement); .trimFrom(charSequence, replacement); Goodies! javadoc
  145. 145. Strings Escapers
  146. 146. HtmlEscapers.htmlEscaper().escape("Foo > bar"); // returns Foo &gt; bar Escapers
  147. 147. HtmlEscapers.htmlEscaper().escape("Foo > bar"); XmlEscapers.xmlAttributeEscaper().escape("foo "bar""); // returns foo &quot;bar&quot; Escapers
  148. 148. HtmlEscapers.htmlEscaper().escape("Foo > bar"); XmlEscapers.xmlAttributeEscaper().escape("foo "bar""); XmlEscapers.xmlContentEscaper().escape("foo "bar""); // returns foo “bar” Escapers
  149. 149. HtmlEscapers.htmlEscaper().escape("Foo > bar"); XmlEscapers.xmlAttributeEscaper().escape("foo "bar""); XmlEscapers.xmlContentEscaper().escape("foo "bar""); Escaper myEscaper = Escapers.builder() // custom Escaper .addEscape(‘’’, “‘’”) .addEscape(‘&’, “&”) .build(); Escapers javadoc
  150. 150. Collections
  151. 151. Collections: Functional Idiom
  152. 152. Collections: Functional Idiom
  153. 153. Collections: Functional Idiom
  154. 154. Function<String, Integer> lengthFunction = new Function<String, Integer>() { public Integer apply(String string) { return string.length(); } }; Predicate<String> allCaps = new Predicate<String>() { public boolean apply(String string) { return CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string); } }; Multiset<Integer> lengths = HashMultiset.create( Iterables.transform(Iterables.filter(strings, allCaps), lengthFunction)); Collections: Functional Idiom
  155. 155. Function<String, Integer> lengthFunction = new Function<String, Integer>() { public Integer apply(String string) { return string.length(); } }; Predicate<String> allCaps = new Predicate<String>() { public boolean apply(String string) { return CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string); } }; Multiset<Integer> lengths = HashMultiset.create( Iterables.transform(Iterables.filter(strings, allCaps), lengthFunction)); Collections: Functional Idiom
  156. 156. Multiset<Integer> lengths = HashMultiset.create(); for (String string : strings) { if (CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string)) { lengths.add(string.length()); } } Collections: Functional Idiom
  157. 157. Multiset<Integer> lengths = HashMultiset.create(); for (String string : strings) { if (CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string)) { lengths.add(string.length()); } } // Use Imperative, you’ve already survived! Collections: Functional Idiom
  158. 158. Multiset<Integer> lengths = HashMultiset.create(); for (String string : strings) { if (CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string)) { lengths.add(string.length()); } } // Use Imperative, you’ve already survived! // Wait for Java 8! Collections: Functional Idiom explain
  159. 159. Immutable = Thread-safe Collections: Immutable types
  160. 160. Immutable = Thread-safe static final ImmutableSet<String> FOO_NAMES = ImmutableSet.of(“foo”, “bar”, “baz”); Collections: Immutable types
  161. 161. Immutable = Thread-safe static final ImmutableSet<String> FOO_NAMES = ImmutableSet.of(“foo”, “bar”, “baz”); // ImmutableList, ImmutableMap... Collections: Immutable types
  162. 162. Immutable = Thread-safe static final ImmutableSet<String> FOO_NAMES = ImmutableSet.of(“foo”, “bar”, “baz”); ImmutableList<String> defensiveCopy = ImmutableList.copyOf(someList); Collections: Immutable types
  163. 163. Immutable = Thread-safe static final ImmutableSet<String> FOO_NAMES = ImmutableSet.of(“foo”, “bar”, “baz”); ImmutableList<String> defensiveCopy = ImmutableList.copyOf(someList); // Prefer Immutable collections over JDK Collections.unmodifiableXX // for efficiency and consistency Collections: Immutable types explain
  164. 164. A bag Collections: Multiset<E>
  165. 165. A bag Just like a Set<E> with repeated values Collections: Multiset<E>
  166. 166. A bag Just like a Set<E> with repeated values You’ve done this with ArrayList<E> or Map<E, Integer> Collections: Multiset<E>
  167. 167. A bag Just like a Set<E> with repeated values You’ve done this with ArrayList<E> or Map<E, Integer> Multiset<Person> ppl = HashMultiset.create(); Collections: Multiset<E>
  168. 168. A bag Just like a Set<E> with repeated values You’ve done this with ArrayList<E> or Map<E, Integer> Multiset<Person> ppl = HashMultiset.create(); ppl.add(jack); ppl.add(charles); ppl.add(jack); Collections: Multiset<E>
  169. 169. A bag Just like a Set<E> with repeated values You’ve done this with ArrayList<E> or Map<E, Integer> Multiset<Person> ppl = HashMultiset.create(); ppl.add(jack); ppl.add(charles); ppl.add(jack); // prints [jack x 2, charles x 1] Collections: Multiset<E>
  170. 170. A bag Just like a Set<E> with repeated values You’ve done this with ArrayList<E> or Map<E, Integer> Multiset<Person> ppl = HashMultiset.create(); ppl.add(jack); ppl.add(charles); ppl.add(jack); ppl.count(jack); Collections: Multiset<E>
  171. 171. A bag Just like a Set<E> with repeated values You’ve done this with ArrayList<E> or Map<E, Integer> Multiset<Person> ppl = HashMultiset.create(); ppl.add(jack); ppl.add(charles); ppl.add(jack); ppl.count(jack); // returns 2 Collections: Multiset<E>
  172. 172. A bag Just like a Set<E> with repeated values You’ve done this with ArrayList<E> or Map<E, Integer> Multiset<Person> ppl = HashMultiset.create(); ppl.add(jack); ppl.add(charles); ppl.add(jack); ppl.count(jack); // Goodies: elementSet(), entrySet(), setCount(E, int)... Collections: Multiset<E> explain
  173. 173. A Map<K, V> with multiple values Collections: Multimap<K, V>
  174. 174. A Map<K, V> with multiple values You’ve done this with Map<K, List<V>> Collections: Multimap<K, V>
  175. 175. A Map<K, V> with multiple values You’ve done this with Map<K, List<V>> Multimap<Person, Ticket> ticketsByPerson = ArrayListMultimap.create(); Collections: Multimap<K, V>
  176. 176. A Map<K, V> with multiple values You’ve done this with Map<K, List<V>> Multimap<Person, Ticket> ticketsByPerson = ArrayListMultimap.create(); ticketsByPerson.put(jack, ctu); ticketsByPerson.put(jack, division); Collections: Multimap<K, V>
  177. 177. A Map<K, V> with multiple values You’ve done this with Map<K, List<V>> Multimap<Person, Ticket> ticketsByPerson = ArrayListMultimap.create(); ticketsByPerson.put(jack, ctu); ticketsByPerson.put(jack, division); ticketsByPerson.get(jack); // returns a view of the associated values, a List. // With SetMultimap returns a Set. Collections: Multimap<K, V>
  178. 178. A Map<K, V> with multiple values You’ve done this with Map<K, List<V>> Multimap<Person, Ticket> ticketsByPerson = ArrayListMultimap.create(); ticketsByPerson.put(jack, ctu); ticketsByPerson.put(jack, division); ticketsByPerson.get(jack); // asMap(), entries(), values()... Collections: Multimap<K, V> explain
  179. 179. // Bi-directional map, keys and values are unique BiMap<K1, K2> Goodies! javadoc
  180. 180. // Bi-directional map, keys and values are unique BiMap<K1, K2> // Two-tier map, or a map with two keys Table<R, C, V> Goodies! javadoc
  181. 181. // Bi-directional map, keys and values are unique BiMap<K1, K2> // Two-tier map, or a map with two keys Table<R, C, V> // < JDK 7, no diamond support List<String> list = Lists.newArrayList(); // Sets, Maps... Goodies! javadoc
  182. 182. // Bi-directional map, keys and values are unique BiMap<K1, K2> // Two-tier map, or a map with two keys Table<R, C, V> // < JDK 7, no diamond support List<String> list = Lists.newArrayList(); // Sets, Maps... // Ranges RangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Range.closed(1, 10)); // {[1, 10]} Goodies! javadoc
  183. 183. Tons of good abstractions for you to use Bottom line
  184. 184. Hashing
  185. 185. Freaking PHP: md5($string) Hashing: JDK
  186. 186. Freaking PHP: md5($string) public static String md5Java(String message) { String digest = null; try { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] hash = md.digest(message.getBytes("UTF-8")); String StringBuilder sb = new StringBuilder(2*hash.length); for(byte b : hash){ sb.append(String.format("%02x", b&0xff)); } digest = sb.toString(); } catch (UnsupportedEncodingException ex) { throw Throwables.propagate(ex); } catch (NoSuchAlgorithmException ex) { throw Throwables.propagate(ex); } return digest; } Hashing: JDK
  187. 187. Freaking PHP: md5($string) public static String md5Java(String message) { String digest = null; try { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] hash = md.digest(message.getBytes("UTF-8")); String StringBuilder sb = new StringBuilder(2*hash.length); for(byte b : hash){ sb.append(String.format("%02x", b&0xff)); } digest = sb.toString(); } catch (UnsupportedEncodingException ex) { throw Throwables.propagate(ex); } catch (NoSuchAlgorithmException ex) { throw Throwables.propagate(ex); } return digest; } Hashing: JDK
  188. 188. HashFunction hf = Hashing.md5(); Hashing: Hasher
  189. 189. HashFunction hf = Hashing.md5(); HashCode hc = hf.newHasher() .putLong(id) .putString(name, Charsets.UTF_8) .putObject(person, personFunnel) .hash(); Hashing: Hasher
  190. 190. HashFunction hf = Hashing.md5(); HashCode hc = hf.newHasher() .putLong(id) .putString(name, Charsets.UTF_8) .putObject(person, personFunnel) // Defines how to hash .hash(); Hashing: Hasher
  191. 191. HashFunction hf = Hashing.md5(); HashCode hc = hf.newHasher() .putLong(id) .putString(name, Charsets.UTF_8) // HINT: remember this! .putObject(person, personFunnel) .hash(); Hashing: Hasher
  192. 192. HashFunction hf = Hashing.md5(); HashCode hc = hf.newHasher() .putLong(id) .putString(name, Charsets.UTF_8) .putObject(person, personFunnel) .hash(); hc.asBytes(); // byte[] hc.asInt(); // value in little-endian order hc.toString(); // hexadecimal in lower case Hashing: Hasher
  193. 193. // More hash functions! Hashing.md5(); Hashing.murmur3_32(); Hashing.murmur3_128(); Hashing.sha1(); Hashing.sha256(); Hashing.sha512(); Goodies! javadoc
  194. 194. // More hash functions! Hashing.md5(); Hashing.murmur3_32(); Hashing.murmur3_128(); Hashing.sha1(); Hashing.sha256(); Hashing.sha512(); // Bloom Filter public boolean mightContain(T); if true, T is probably there if false, T for sure is not there Goodies! javadoc
  195. 195. I/O
  196. 196. Binary encoding scheme, RFC 4648 I/O: BaseEncoding
  197. 197. Binary encoding scheme, RFC 4648 -- Serious stuff I/O: BaseEncoding
  198. 198. Binary encoding scheme, RFC 4648 BaseEncoding .base32() .encode("foo".getBytes(Charsets.US_ASCII)); I/O: BaseEncoding
  199. 199. Binary encoding scheme, RFC 4648 BaseEncoding .base32() .encode("foo".getBytes(Charsets.US_ASCII)); // returns MZXW6=== I/O: BaseEncoding
  200. 200. Binary encoding scheme, RFC 4648 BaseEncoding .base32() .encode("foo".getBytes(Charsets.US_ASCII)); // returns MZXW6=== byte[] decoded = BaseEncoding .base32() .decode("MZXW6==="); I/O: BaseEncoding
  201. 201. Binary encoding scheme, RFC 4648 BaseEncoding .base32() .encode("foo".getBytes(Charsets.US_ASCII)); // returns MZXW6=== byte[] decoded = BaseEncoding .base32() .decode("MZXW6==="); // returns the ASCII bytes of String “foo” I/O: BaseEncoding
  202. 202. // More schemas BaseEncoding.base16(); BaseEncoding.base32(); BaseEncoding.base64(); BaseEncoding.base64Url(); // Useful all the time Goodies! javadoc
  203. 203. KIA
  204. 204. KIA Caches EventBus
  205. 205. KIA Caches Networking EventBus Concurrency
  206. 206. KIA Caches Networking Math EventBus Concurrency More I/O
  207. 207. KIA Caches Networking Math Reflection EventBus Concurrency More I/O Collect
  208. 208. KIA Caches Networking Math Reflection Primitives EventBus Concurrency More I/O Collect Grumpy
  209. 209. Your friends Wiki
  210. 210. Your friends Wiki javadoc
  211. 211. Remember The “wheel”
  212. 212. Remember Read this code
  213. 213. Remember No Grumpy Cats were harmed in the making of this presentation
  214. 214. Thanks! jordi@donky.org @jordi9
  215. 215. Q & A jordi@donky.org @jordi9
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×