Google Guava
-
Upload
neueda -
Category
Technology
-
view
807 -
download
1
Transcript of Google Guava
Google Guava
by Yuriy KrutkoJava Developer
Common Myths
Guava is a fruitGuavas (singular Guava, English pronunciation: /ˈgwɑː.və/[2]) are plants in the Myrtle family (Myrtaceae) genus Psidium (meaning "pomegranate" in Latin)
Guava misuses functional idioms
Guava is Google Collections
What's inside
Preconditions
Ordering Throwables
Caches
Strings
PrimitivesRanges
I/OHashing
EventBus
Math
ReflectionObjects
CollectionsConcurrency
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
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.
equals, hashCode, toString
Code it yourself
Generate using tools (e.g. Eclipse)
Use Guava Objects class
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; }
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; }
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(); }
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; }
Compare while equalpublic 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; } }; } }
Compare while equalpublic 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; } }; } }
public static Comparator<PairOfInts> comparatorInts() { return new Comparator<PairOfInts>() { @Override public int compare(PairOfInts p1, PairOfInts p2) { int res = Ints.compare(p1.first, p2.first); if (res == 0) { return Ints.compare(p1.second, p2.second); } return res; } }; }
Compare while equalpublic 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; } }; } }
public static Comparator<PairOfInts> comparatorInts() { return new Comparator<PairOfInts>() { @Override public int compare(PairOfInts p1, PairOfInts p2) { int res = Ints.compare(p1.first, p2.first); if (res == 0) { return Ints.compare(p1.second, p2.second); } return res; } }; }
public static Ordering<PairOfInts> ordering() { return Ordering.from(new Comparator<PairOfInts>() { @Override public int compare(PairOfInts p1, PairOfInts p2) { return Ints.compare(p1.first, p2.first); } }).compound(new Comparator<PairOfInts>() { @Override public int compare(PairOfInts p1, PairOfInts p2) { return Ints.compare(p1.second, p2.second); } }); }
Compare while equalpublic 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; } }; } }
public static Comparator<PairOfInts> comparatorInts() { return new Comparator<PairOfInts>() { @Override public int compare(PairOfInts p1, PairOfInts p2) { int res = Ints.compare(p1.first, p2.first); if (res == 0) { return Ints.compare(p1.second, p2.second); } return res; } }; }
public static Ordering<PairOfInts> ordering() { return Ordering.from(new Comparator<PairOfInts>() { @Override public int compare(PairOfInts p1, PairOfInts p2) { return Ints.compare(p1.first, p2.first); } }).compound(new Comparator<PairOfInts>() { @Override public int compare(PairOfInts p1, PairOfInts p2) { return Ints.compare(p1.second, p2.second); } }); }
public static Ordering<PairOfInts> orderingLexicographical() { return Ordering.<Comparable<?>> natural() .lexicographical().onResultOf( new Function<PairOfInts, Iterable<Comparable<?>>>() { @Override public Iterable<Comparable<?>> apply(PairOfInts pair) { return ImmutableList.<Comparable<?>> of(pair.first, pair.second); } }); }
Compare while equalpublic 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; } }; } }
public static Comparator<PairOfInts> comparatorInts() { return new Comparator<PairOfInts>() { @Override public int compare(PairOfInts p1, PairOfInts p2) { int res = Ints.compare(p1.first, p2.first); if (res == 0) { return Ints.compare(p1.second, p2.second); } return res; } }; }
public static Ordering<PairOfInts> ordering() { return Ordering.from(new Comparator<PairOfInts>() { @Override public int compare(PairOfInts p1, PairOfInts p2) { return Ints.compare(p1.first, p2.first); } }).compound(new Comparator<PairOfInts>() { @Override public int compare(PairOfInts p1, PairOfInts p2) { return Ints.compare(p1.second, p2.second); } }); }
public static Ordering<PairOfInts> orderingLexicographical() { return Ordering.<Comparable<?>> natural() .lexicographical().onResultOf( new Function<PairOfInts, Iterable<Comparable<?>>>() { @Override public Iterable<Comparable<?>> apply(PairOfInts pair) { return ImmutableList.<Comparable<?>> of(pair.first, pair.second); } }); }
Better Nullspublic 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; }}
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); }}
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"); }
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(); }
More collections public void biMap() { BiMap<Integer, String> biMap = HashBiMap.create(); BiMap<String, Integer> inverseBiMap = biMap.inverse(); } public void multimap() { Multimap<Integer, String> multiMap = ArrayListMultimap.create(); multiMap.put(10, "val1"); multiMap.put(10, "val2"); Collection<String> values = multiMap.get(10); }
Table<Vertex, Vertex, Double> weightedGraph = HashBasedTable.create(); weightedGraph.put(v1, v2, 4.0); weightedGraph.put(v1, v3, 20.0); weightedGraph.put(v2, v3, 5.0); Map<Vertex, Double> row = weightedGraph.row(v1); Map<Vertex, Double> column = weightedGraph.column(v3);
Double checked lockingpublic class DCL { private static final Supplier<Object> supplier = Suppliers .memoize(new Supplier<Object>() { @Override public Object get() { return loadResource(); } });
private static Object loadResource() { return new Object(); } public static Object getResource() { return supplier.get(); }}
Memoize and Expirepublic class DCLExp { private static final Supplier<Object> supplier = Suppliers .memoizeWithExpiration(new Supplier<Object>() { @Override public Object get() { return loadResource(); } }, 10, TimeUnit.MINUTES);
private static Object loadResource() { return new Object(); } public static Object getResource() { return supplier.get(); }}
Cachepublic class CacheSample { private final LoadingCache<String, Object> cache = CacheBuilder.newBuilder() .maximumSize(1000) .initialCapacity(100) .concurrencyLevel(10) .expireAfterAccess(30, TimeUnit.SECONDS) .recordStats() .build(new CacheLoader<String, Object>() { @Override public Object load(String key) throws Exception { return loadResourceByKey(key); } });
private Object loadResourceByKey(String key) { return new Object(); } public Object getCachedValue(String key) { return cache.getUnchecked(key); } public CacheStats getStats() { return cache.stats(); }}
Functional Idioms public static Multiset<Integer> one(Iterable<String> strings) { Function<String, Integer> lengthFunction = new Function<String, Integer>() { @Override public Integer apply(String string) { return string.length(); } }; Predicate<String> allCaps = new Predicate<String>() { @Override public boolean apply(String string) { return CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string); } }; return HashMultiset.create(Iterables.transform(
Iterables.filter(strings, allCaps), lengthFunction)); }
Functional Idioms public static Multiset<Integer> two(Iterable<String> strings) { return HashMultiset.create( FluentIterable.from(strings) .filter(new Predicate<String>() { @Override public boolean apply(String string) { return CharMatcher.JAVA_UPPER_CASE
.matchesAllOf(string); } }) .transform(new Function<String, Integer>() { @Override public Integer apply(String string) { return string.length(); } })); }
public static Multiset<Integer> one(Iterable<String> strings) { Function<String, Integer> lengthFunction = new Function<String, Integer>() { @Override public Integer apply(String string) { return string.length(); } }; Predicate<String> allCaps = new Predicate<String>() { @Override public boolean apply(String string) { return CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string); } }; return HashMultiset.create(Iterables.transform(
Iterables.filter(strings, allCaps), lengthFunction)); }
Functional Idioms public static Multiset<Integer> three(Iterable<String> strings) { Multiset<Integer> lengths = HashMultiset.create(); for (String string : strings) { if (CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string)) { lengths.add(string.length()); } } return lengths; }
Catching a Buspublic 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) { }}
Catching a Buspublic 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); } }}
Event Bus
public class BaseEvent {}
public class SpecificEvent extends BaseEvent {}
public class OtherSpecificEvent extends BaseEvent {}
Event Buspublic 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()); }}
Even more...
• IO
•Net
•Reflect
•Throwables
•Hashing
•Math
•CaseFormat
•Concurrency
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