2. Common Myths
Guava is a fruit
Guavas (singular Guava, English pronunciation: /ËgwÉË.vÉ/[2]) are
plants in the Myrtle family (Myrtaceae) genus Psidium (meaning
"pomegranate" in Latin)
Guava is Google Collections
Guava misuses functional idioms
4. Why Guava?
⢠Guava is a productivity multiplier
⢠I Could've Invented That
⢠"Know and use the librariesâ
⢠Don't reinvent the wheel.
⢠Could not be included into Java API
5. Guava Design Principles
⢠API is the best solution for use case.
⢠Obvious and intuitive outside. "Smart" inside.
⢠Encourage good code habits.
⢠Generic tools that can be composed.
⢠Emphasize maintainability.
7. Generated
private String firstName;
private String secondName;
@Override
public String toString() {
return "PersonGenerated [firstName=" + firstName
+ ", secondName=" + secondName + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((firstName == null) ? 0 : firstName.hashCode());
result = prime * result
+ ((secondName == null) ? 0 : secondName.hashCode());
return result;
}
8. Generate
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PersonGenerated other = (PersonGenerated) obj;
if (firstName == null) {
if (other.firstName != null)
return false;
} else if (!firstName.equals(other.firstName))
return false;
if (secondName == null) {
if (other.secondName != null)
return false;
} else if (!secondName.equals(other.secondName))
return false;
return true;
}
9. Objects
private String firstName;
private String secondName;
@Override
public int hashCode() {
return Objects.hashCode(firstName, secondName);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof PersonGuava) {
PersonGuava other = (PersonGuava) obj;
return Objects.equal(firstName, other.firstName)
&& Objects.equal(secondName, other.secondName);
}
return false;
}
@Override
public String toString() {
return Objects.toStringHelper(this)
.add("firstName", firstName)
.add("secondName", secondName)
.toString();
}
10. Puzzler
Objects.hashCode(a) == a.hashCode() ?
Arrays.hashCode(new Object[] { a }) == a.hashCode() ?
public static int hashCode(Object a[]) {
if (a == null)
return 0;
int result = 1;
for (Object element : a)
result = 31 * result
+ (element == null ? 0 : element.hashCode());
return result;
}
11. Compare while equal
public class PairOfInts {
private int first;
private int second;
public static Comparator<PairOfInts> comparator() {
return new Comparator<PairOfInts>() {
@Override
public int compare(PairOfInts p1, PairOfInts p2) {
if (p1.first < p2.first) {
return -1;
}
if (p1.first == p2.first) {
if (p1.second < p2.second) {
return -1;
}
if (p1.second == p2.second) {
return 0;
}
}
return 1;
}
};
}
}
12. Compare while equal
public class PairOfInts {
private int first;
private int second;
comparatorInts() {
public static Comparator<PairOfInts> comparator() {
return new Comparator<PairOfInts>() {
@Override
public int compare(PairOfInts p1, PairOfInts p2) {
int res = Ints.compare(p1.first, p2.first);
if (p1.first < p2.first) {
if (res == 0) {
return -1;
} return Ints.compare(p1.second, p2.second);
}
if (p1.first == p2.first) {
return res;
if (p1.second < p2.second) {
} return -1;
}; }
} if (p1.second == p2.second) {
return 0;
}
}
return 1;
}
};
}
}
13. Compare while equal
public class PairOfInts {
private int first;
private int second;
public static Comparator<PairOfInts> comparator() {
Ordering<PairOfInts> ordering() {
comparatorInts() {
Ordering.from(new Comparator<PairOfInts>() {
return new Comparator<PairOfInts>() {
@Override
public int compare(PairOfInts p1, PairOfInts p2) {
return = Ints.compare(p1.first, p2.first);
int resInts.compare(p1.first, p2.first);
if (p1.first < p2.first) {
} if (res == 0) {
return -1;
}).compound(new Comparator<PairOfInts>() { p2.second);
} return Ints.compare(p1.second,
@Override
}
if (p1.first == p2.first) {
public int res;
return compare(PairOfInts p1, PairOfInts p2) {
if (p1.second < p2.second) {
} return Ints.compare(p1.second, p2.second);
return -1;
}; } }
} }); if (p1.second == p2.second) {
} return 0;
}
}
return 1;
}
};
}
}
14. Compare while equal
public class PairOfInts {
private int first;
private int second;
public static Comparator<PairOfInts> comparator() {
Ordering<PairOfInts> ordering() {
orderingLexicographical() {
comparatorInts() {
Ordering.<Comparable<?>> natural()
Ordering.from(new Comparator<PairOfInts>() {
return new Comparator<PairOfInts>() {
.lexicographical().onResultOf(
@Override
public int compare(PairOfIntsIterable<Comparable<?>>>() {
new Function<PairOfInts, p1, PairOfInts p2) {
return = Ints.compare(p1.first, p2.first);
int resInts.compare(p1.first, p2.first);
@Override
if (p1.first < p2.first) {
} if (res == 0) {
public Iterable<Comparable<?>> apply(PairOfInts pair) {
return -1;
}).compound(new Comparator<PairOfInts>() { p2.second);
} return Ints.compare(p1.second,
return ImmutableList.<Comparable<?>>
@Override
} of(pair.first, pair.second);
if (p1.first == p2.first) {
public int res;
return compare(PairOfInts p1, PairOfInts p2) {
}
if (p1.second < p2.second) {
} });
return Ints.compare(p1.second, p2.second);
return -1;
} }; } }
} }); if (p1.second == p2.second) {
} return 0;
}
}
return 1;
}
};
}
}
15. Compare while equal
public class PairOfInts {
private int first;
private int second;
public static Comparator<PairOfInts> comparator() {
Ordering<PairOfInts> ordering() {
orderingLexicographical() {
comparatorInts() {
Ordering.<Comparable<?>> natural()
Ordering.from(new Comparator<PairOfInts>() {
return new Comparator<PairOfInts>() {
.lexicographical().onResultOf(
@Override
public int compare(PairOfIntsIterable<Comparable<?>>>() {
new Function<PairOfInts, p1, PairOfInts p2) {
return = Ints.compare(p1.first, p2.first);
int resInts.compare(p1.first, p2.first);
@Override
if (p1.first < p2.first) {
} if (res == 0) {
public Iterable<Comparable<?>> apply(PairOfInts pair) {
return -1;
}).compound(new Comparator<PairOfInts>() { p2.second);
} return Ints.compare(p1.second,
return ImmutableList.<Comparable<?>>
@Override
} of(pair.first, pair.second);
if (p1.first == p2.first) {
public int res;
return compare(PairOfInts p1, PairOfInts p2) {
}
if (p1.second < p2.second) {
} });
return Ints.compare(p1.second, p2.second);
return -1;
} }; } }
} }); if (p1.second == p2.second) {
} return 0;
}
}
return 1;
}
};
}
}
16. Better Nulls
public class BetterNulls {
public static final String DEFAULT = "default";
public String neverNullDefault(String value) {
return Objects.firstNonNull(value, DEFAULT);
}
public String neverNullEmpty(String value) {
return Strings.nullToEmpty(value);
}
public String getValueByKey(String key, Map<String, String> map) {
return Functions.forMap(map, DEFAULT).apply(key);
}
public Optional<String> getValueByKeyOptional(String key, Map<String, String> map) {
if (map.containsKey(key)) {
return Optional.fromNullable(map.get(key));
}
return null;
}
}
17. Failfast and Join with Joy
public class PreconditionsJoiner {
public String joinStrings(Iterable<String> strings) {
Preconditions.checkNotNull(strings, "Strings should not be null");
return Joiner.on(", ").skipNulls().join(strings);
}
}
18. Measure everything
public void measureSomething() {
Stopwatch stopwatch = new Stopwatch();
for (int i = 0; i < COUNT; i++) {
stopwatch.start();
doSomething();
stopwatch.stop();
doUnimpotantThing();
stopwatch.start();
doOtherThing();
stopwatch.stop();
}
System.out.println("Average execution time "
+ stopwatch.elapsedTime(TimeUnit.NANOSECONDS) / COUNT + "ns");
}
19. Fast and Immutable
public List<Integer> createList(int[] elements) {
return ImmutableList.copyOf(Ints.asList(elements));
}
public Map<String, String> createMap() {
return ImmutableMap.of("key1", "val1", "key2", "val2");
}
public Map<String, String> buildMap() {
return ImmutableMap.<String, String> builder()
.put("key1", "val1")
.put("key2", "val2")
.build();
}
26. Functional Idioms
public static Multiset<Integer> one(Iterable<String> strings) { {
three(Iterable<String> strings)
Function<String, Integer> lengthFunction = new Function<String, Integer>() {
Multiset<Integer> lengths = HashMultiset.create();
for @Override
(String string : strings) {
public Integer apply(String string) {
if (CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string)) {
return string.length();
lengths.add(string.length());
}
};
}
Predicate<String> allCaps = new Predicate<String>() {
return lengths;
} @Override
public boolean apply(String string) {
return CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string);
}
};
return HashMultiset.create(Iterables.transform(
Iterables.filter(strings, allCaps), lengthFunction));
}
27. Catching a Bus
public class BaseEvent {
}
public class SpecificEvent extends BaseEvent {
}
public class OtherSpecificEvent extends BaseEvent {
}
public interface EventListener {
void handleSpecific(SpecificEvent event);
void handleOtherSpecific(OtherSpecificEvent event);
}
public class EventListenerAdapter implements EventListener {
@Override
public void handleSpecific(SpecificEvent event) {
}
@Override
public void handleOtherSpecific(OtherSpecificEvent event) {
}
}
28. Catching a Bus
public class EventDispatcher {
private List<EventListener> listeners = new CopyOnWriteArrayList<EventListener>();
public void addListener(EventListener listener) {
listeners.add(listener);
}
public void removeListener(EventListener listener) {
listeners.add(listener);
}
public void fireSpecific(SpecificEvent event) {
for (EventListener listener : listeners) {
listener.handleSpecific(event);
}
}
public void fireOtherSpecific(OtherSpecificEvent event) {
for (EventListener listener : listeners) {
listener.handleOtherSpecific(event);
}
}
}
29. Event Bus
public class BaseEvent {
}
public class SpecificEvent extends BaseEvent {
}
public class OtherSpecificEvent extends BaseEvent {
}
30. Event Bus
public class EBExample {
private static final EventBus eventBus = new EventBus();
public static void main(String[] args) {
eventBus.register(new Object() {
@Subscribe
public void handle(SpecificEvent event) {
System.out.println("SpecificEvent: " + event.getClass());
}
});
eventBus.register(new Object() {
@Subscribe
@AllowConcurrentEvents
public void handle(BaseEvent event) {
System.out.println("BaseEvent: " + event.getClass());
}
});
eventBus.post(new SpecificEvent());
}
}
31. Even more...
⢠IO
⢠Net
⢠Reflect
⢠Throwables
⢠Hashing
⢠Math
⢠CaseFormat
⢠Concurrency
32. Apache Commons
⢠Just another library
⢠Commons > Guava (BCEL, Fvs, Email)
⢠Guava is more consistent
⢠Guava uses generics
⢠Guava Commons != {}
⢠Guava doesn't solve global tasks
⢠Don't shoot yourself in the foot with
Guava