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.
34. if (seats <= 0) {
throw new IllegalArgumentException(“Seats must be
positive, but was ” + seats);
}
Basics: Preconditions
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. // 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
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. @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. @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. @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. @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
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. 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. 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. 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
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. 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. 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. 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. void oneLineOfCode() {
// Take 3
DatagramPacket packet = new DatagramPacket(data, length);
}
Basics: Throwables
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. 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. 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
112. We have String.split bro!
“,f,,o, o,”.split(“,”) returns:
a. [“”, “f”, “”, “o”, “ o”,””]
Strings: Splitter
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. 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. 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. 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. 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. 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. 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. 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
165. A bag
Just like a Set<E> with repeated values
Collections: Multiset<E>
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. 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. 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. 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. 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. 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. 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. A Map<K, V> with multiple values
Collections: Multimap<K, V>
174. A Map<K, V> with multiple values
You’ve done this with Map<K, List<V>>
Collections: Multimap<K, V>
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. 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. 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. 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
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. // 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. // 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. Tons of good abstractions for you to use
Bottom line
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