@mitemitreski
The core libraries you
always wanted
Google Guava
What is Google Guava?
com.google.common.annotation
com.google.common.base
com.google.common.collect
com.google.common.io
com.google.common.net
com.google.common.primitives
com.google.common.util.concurrent
...
Code in slides
Apache 2 license
latest release is 18.0,
released August 25, 2014.
Guava facts
NULL it is
"Null sucks." - Doug Lea
"I call it my billion-dollar
mistake." - C. A. R. Hoare
Null is ambiguous
if ( x != null && x.someM()!=null && ) {
// work with x.someM()
}
Boolean isAwesome ; // can be NULL, TRUE, FALSE
Assert.notNull(x);
Assert.notNull(x.someM());
// work with x.someM()
import com.google.common.base.*
@Test
public void optionalExample() {
Optional<Integer> possible = Optional.of(3); // Make optional of given type
possible.isPresent(); // evaluate to true if nonNull
possible.or(10); // evaluate to possible's value or default
possible.get(); // evaluate to 3
}
import com.google.common.base.*
public void testNeverNullWithoutGuava() {
Integer defaultId = null;
Integer id = theUnknowMan.getId() != null ? theUnknowMan.getId() : defaultId;
assertNotNull(id);
}
public void firstNotNull() {
Integer a = Objects.firstNonNull(null, 3); // will evaluate to 3
Integer b = Objects.firstNonNull(9, 3); // //will evaluate to 9
assertEquals(Integer.valueOf(3), a);
assertEquals(Integer.valueOf(9), b);
}
import static com.google.common.base.Preconditions.*;
private Customer theUnknowMan = new Customer();
@Test(expected = IllegalArgumentException.class)
public void somePreconditions() {
checkNotNull(theUnknowMan.getId()); // Will throw NPE
checkState(!theUnknowMan.isSick()); // Will throw IllegalStateException
checkArgument(theUnknowMan.getAddress() != null,
"We couldn't find the description for customer with id %s", theUnknowMan.
getId());
}
JSR-305 Annotations for software defect detection
@Nullable @NotNull
1. javax.validation.constraints.NotNull - EE6
2. edu.umd.cs.findbugs.annotations.NonNull – Findbugs, Sonar
3. javax.annotation.Nonnull – JSR-305
4. com.intellij.annotations.NotNull - IntelliJIDEA
The Executive Committee voted to list this JSR as dormant in May 2012.
But JDK 8 has java.util.Optional
… and java.util.Objects
… and guava has com.google.common.base.MoreObjects
import static com.google.common.base.Preconditions.*;
private Customer theUnknowMan = new Customer();
@Test(expected = IllegalArgumentException.class)
public void somePreconditions() {
checkNotNull(theUnknowMan.getId()); // Will throw NPE
checkState(!theUnknowMan.isSick()); // Will throw IllegalStateException
checkArgument(theUnknowMan.getAddress() != null,
"We couldn't find the description for customer with id %s", theUnknowMan.
getId());
}
JDK8+ just use java.util.
Objects + Optional
API Deprecation
@Beta annotated API is subject to change any
time
@Deprecated annotated API is removed
in 18+ months after depreciation
Serialization compatibility is NOT
guaranteed
Guava's "fluent" Comparator class.
Ordering<Customer> ordering = Ordering
.natural()
.nullsFirst().onResultOf(
new Function<Customer, Comparable>() {
@Override
public Comparable apply(Customer customer) {
return customer.getName();
}
}
);
Wrapper overload
Character Matchers
Use a predefined constant (examples)
• CharMatcher.WHITESPACE (tracks Unicode defn.)
• CharMatcher.JAVA_DIGIT
• CharMatcher.ASCII
• CharMatcher.ANY
Use a factory method (examples)
• CharMatcher.is('x')
• CharMatcher.isNot('_')
• CharMatcher.oneOf("aeiou").negate()
• CharMatcher.inRange('a', 'z').or(inRange('A','Z'))
Character Matchers
String noControl = CharMatcher.JAVA_ISO_CONTROL.removeFrom(string);
String theDigits = CharMatcher.DIGIT.retainFrom(string);
String lowerAndDigit = CharMatcher.or(CharMatcher.JAVA_DIGIT,
CharMatcher.JAVA_LOWER_CASE).retainFrom(string);
import com.google.common.cache.*;
Cache<Integer, Customer> cache =
CacheBuilder.newBuilder()
.maximumSize(10000)
.build();
Eviction
Cache<Integer, Customer> cache =
CacheBuilder.newBuilder()
.expireAfterWrite(2, TimeUnit.MINUTES)
.build();
Cache<Integer, Customer> cache =
CacheBuilder.newBuilder()
.expireAfterAccess(2,TimeUnit.MINUTES)
.build();
Eviction
Cache<Integer, Customer> cache =
CacheBuilder.newBuilder()
.weigher(new Weigher<Integer, Customer>() {
@Override
public int weigh(Integer key, Customer value) {
return value.getName().length();
}
}).maximumWeight(20)
//0 all good 21 evict something
.build();
import com.google.common.cache.*;
Cache<Integer, Customer> cache =
CacheBuilder.newBuilder()
.weakKeys()
.maximumSize(10000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build();
It’s all about the numbers
Cache<Integer, Customer> cache =
CacheBuilder.newBuilder()
.recordStats()
.build();
CacheStats stats = cache.stats();
stats.hitRate();
stats.averageLoadPenalty();
stats.missCount();
stats.missRate();
Map != Cache
● Map.get causes a type-safety hole
● Map.get is a read operation and users don't
expect it to also write
● Map.equals is not symmetric on a self-populating
Map
com.google.common.collect.*;
• Immutable Collections
• Multimaps, Multisets, BiMaps... aka Google-
Collections
• Comparator-related utilities
• Stuff similar to Apache commons collections
• Some functional programming support
(filter/transform/etc.)
MultiMap
BiMap
● BiMap<K, V> is Map<K,V> with unique values
● Operations: all Map, inverse(), values() as Set
● Throws an IllegalArgumentException if you attempt to
map a key to an already-present value
Functions and Predicates
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);
}
};
Functions and Predicates
Function<String, Integer> lengthFunction = String::length;
Predicate<String> allCaps = CharMatcher.JAVA_UPPER_CASE::matchesAllOf;
Functional aka Single Abstract Method
interfaces - SAM
Functionality Guava JDK 8
Predicate apply(T input) test(T input)
Combining predicates Predicates.and/or/not Predicate.and/or/negate
Supplier Suplier.get Supplier.get
Joiner/StringJoiner Joiner.join() StringJoiner.add()
SettableFuture/CompletableFutu
re
SettableFuture.set(T input) CompletableFuture.complete(T input)
Optional Optional.of/ofNullable/empty Optional.of/fromNullable/absent
Filter collections
SortedMap<String, String> map = new TreeMap<>();
map.put("1", "one");
map.put("2", "two");
map.put("3", null);
map.put("4", "four");
SortedMap<String, String> filtered =
Maps.filterValues(map, Predicates.notNull());
assertThat(filtered.size(), is(3)); // null entry for "3" is gone!
Filter collections
Transform collections
Java 8 - aggregate operations
http://docs.oracle.com/javase/tutorial/collections/streams/index.html
roster
.stream()
.filter(e -> e.getGender() == Person.Sex.MALE)
.forEach(e -> System.out.println(e.getName());
Java 8 - aggregate operations
http://docs.oracle.com/javase/tutorial/collections/streams/index.html
double average = roster
.stream()
.filter(p -> p.getGender() == Person.Sex.MALE)
.mapToInt(Person::getAge)
.average()
.getAsDouble();
Collection goodies
// oldway
Map<String, Map<Long, List<String>>> mapOld = new
HashMap<String, Map<Long, List<String>>>();
// the guava way
Map<String, Map<Long, List<String>>> map = Maps.newHashMap();
// list
ImmutableList<String> of = ImmutableList.of("a", "b", "c");
// Same one for map
ImmutableMap<String, String> theMap = ImmutableMap.of("key1",
"value1", "key2", "value2");
//list of ints
List<Integer> theList = Ints.asList(1, 2, 3, 4, 522, 5, 6);
Load resources
Resources.getResource("com/tfnico/examples/guava/BaseTest.class");
// instead of this:
String location = "com/tfnico/examples/guava/BaseTest.class";
URL resource2 = this.getClass().getClassLoader().getResource(location);
Preconditions.checkArgument(resource2 != null, "resource %s not found",
location);
Hashing
HashFunction hf = Hashing.md5();
Customer c = new Customer();
// into is a primitive sink
Funnel<? super Customer> customerFunnel = (from, into) -> {
into.putString(from.getName(),Charsets.UTF_8);
into.putInt(from.getId());
};
HashCode hc = hf.newHasher()
.putLong(2)
.putString("Mite", Charsets.UTF_8)
.putObject(c, customerFunnel)
.hash();
Bloom filter
BloomFilter<Customer> awesomeCusumers =
BloomFilter.create(customerFunnel, 500, 0.01);
List<Customer> friendsList = Lists.newArrayList(
new Customer(),
new Customer());
for(Customer friend : friendsList) {
awesomeCusumers.put(friend);
}
Customer thatStrangeGuy = new Customer();
if (awesomeCusumers.mightContain(thatStrangeGuy)) {
//that strange guy is not a cusumer and we have reachet this line
//probablility 0.01
}
Bloom filter
When to use Guava?
● Temporary collections
● Mutable collections
● String Utils
● Check if (x==null)
● Always ?
Why use a Guava?
"I could just write that myself."
But… These things are much easier to mess up than it
seems
•With a library, other people will make your code faster and better
for You
Major stuff I did not mentioned
EventBus
IO
Reflection
Math
Ranges
BG-JUG and JugMK community

The core libraries you always wanted - Google Guava

  • 1.
    @mitemitreski The core librariesyou always wanted Google Guava
  • 3.
    What is GoogleGuava? com.google.common.annotation com.google.common.base com.google.common.collect com.google.common.io com.google.common.net com.google.common.primitives com.google.common.util.concurrent ...
  • 4.
  • 5.
    Apache 2 license latestrelease is 18.0, released August 25, 2014. Guava facts
  • 6.
    NULL it is "Nullsucks." - Doug Lea "I call it my billion-dollar mistake." - C. A. R. Hoare
  • 7.
    Null is ambiguous if( x != null && x.someM()!=null && ) { // work with x.someM() } Boolean isAwesome ; // can be NULL, TRUE, FALSE Assert.notNull(x); Assert.notNull(x.someM()); // work with x.someM()
  • 8.
    import com.google.common.base.* @Test public voidoptionalExample() { Optional<Integer> possible = Optional.of(3); // Make optional of given type possible.isPresent(); // evaluate to true if nonNull possible.or(10); // evaluate to possible's value or default possible.get(); // evaluate to 3 }
  • 9.
    import com.google.common.base.* public voidtestNeverNullWithoutGuava() { Integer defaultId = null; Integer id = theUnknowMan.getId() != null ? theUnknowMan.getId() : defaultId; assertNotNull(id); } public void firstNotNull() { Integer a = Objects.firstNonNull(null, 3); // will evaluate to 3 Integer b = Objects.firstNonNull(9, 3); // //will evaluate to 9 assertEquals(Integer.valueOf(3), a); assertEquals(Integer.valueOf(9), b); }
  • 10.
    import static com.google.common.base.Preconditions.*; privateCustomer theUnknowMan = new Customer(); @Test(expected = IllegalArgumentException.class) public void somePreconditions() { checkNotNull(theUnknowMan.getId()); // Will throw NPE checkState(!theUnknowMan.isSick()); // Will throw IllegalStateException checkArgument(theUnknowMan.getAddress() != null, "We couldn't find the description for customer with id %s", theUnknowMan. getId()); }
  • 11.
    JSR-305 Annotations forsoftware defect detection @Nullable @NotNull 1. javax.validation.constraints.NotNull - EE6 2. edu.umd.cs.findbugs.annotations.NonNull – Findbugs, Sonar 3. javax.annotation.Nonnull – JSR-305 4. com.intellij.annotations.NotNull - IntelliJIDEA The Executive Committee voted to list this JSR as dormant in May 2012.
  • 12.
    But JDK 8has java.util.Optional … and java.util.Objects … and guava has com.google.common.base.MoreObjects
  • 13.
    import static com.google.common.base.Preconditions.*; privateCustomer theUnknowMan = new Customer(); @Test(expected = IllegalArgumentException.class) public void somePreconditions() { checkNotNull(theUnknowMan.getId()); // Will throw NPE checkState(!theUnknowMan.isSick()); // Will throw IllegalStateException checkArgument(theUnknowMan.getAddress() != null, "We couldn't find the description for customer with id %s", theUnknowMan. getId()); } JDK8+ just use java.util. Objects + Optional
  • 14.
  • 15.
    @Beta annotated APIis subject to change any time @Deprecated annotated API is removed in 18+ months after depreciation Serialization compatibility is NOT guaranteed
  • 16.
    Guava's "fluent" Comparatorclass. Ordering<Customer> ordering = Ordering .natural() .nullsFirst().onResultOf( new Function<Customer, Comparable>() { @Override public Comparable apply(Customer customer) { return customer.getName(); } } );
  • 17.
  • 18.
    Character Matchers Use apredefined constant (examples) • CharMatcher.WHITESPACE (tracks Unicode defn.) • CharMatcher.JAVA_DIGIT • CharMatcher.ASCII • CharMatcher.ANY Use a factory method (examples) • CharMatcher.is('x') • CharMatcher.isNot('_') • CharMatcher.oneOf("aeiou").negate() • CharMatcher.inRange('a', 'z').or(inRange('A','Z'))
  • 19.
    Character Matchers String noControl= CharMatcher.JAVA_ISO_CONTROL.removeFrom(string); String theDigits = CharMatcher.DIGIT.retainFrom(string); String lowerAndDigit = CharMatcher.or(CharMatcher.JAVA_DIGIT, CharMatcher.JAVA_LOWER_CASE).retainFrom(string);
  • 20.
    import com.google.common.cache.*; Cache<Integer, Customer>cache = CacheBuilder.newBuilder() .maximumSize(10000) .build();
  • 21.
    Eviction Cache<Integer, Customer> cache= CacheBuilder.newBuilder() .expireAfterWrite(2, TimeUnit.MINUTES) .build(); Cache<Integer, Customer> cache = CacheBuilder.newBuilder() .expireAfterAccess(2,TimeUnit.MINUTES) .build();
  • 22.
    Eviction Cache<Integer, Customer> cache= CacheBuilder.newBuilder() .weigher(new Weigher<Integer, Customer>() { @Override public int weigh(Integer key, Customer value) { return value.getName().length(); } }).maximumWeight(20) //0 all good 21 evict something .build();
  • 23.
    import com.google.common.cache.*; Cache<Integer, Customer>cache = CacheBuilder.newBuilder() .weakKeys() .maximumSize(10000) .expireAfterWrite(10, TimeUnit.MINUTES) .build();
  • 24.
    It’s all aboutthe numbers Cache<Integer, Customer> cache = CacheBuilder.newBuilder() .recordStats() .build(); CacheStats stats = cache.stats(); stats.hitRate(); stats.averageLoadPenalty(); stats.missCount(); stats.missRate();
  • 25.
    Map != Cache ●Map.get causes a type-safety hole ● Map.get is a read operation and users don't expect it to also write ● Map.equals is not symmetric on a self-populating Map
  • 26.
    com.google.common.collect.*; • Immutable Collections •Multimaps, Multisets, BiMaps... aka Google- Collections • Comparator-related utilities • Stuff similar to Apache commons collections • Some functional programming support (filter/transform/etc.)
  • 27.
  • 28.
    BiMap ● BiMap<K, V>is Map<K,V> with unique values ● Operations: all Map, inverse(), values() as Set ● Throws an IllegalArgumentException if you attempt to map a key to an already-present value
  • 29.
    Functions and Predicates 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); } };
  • 30.
    Functions and Predicates Function<String,Integer> lengthFunction = String::length; Predicate<String> allCaps = CharMatcher.JAVA_UPPER_CASE::matchesAllOf;
  • 31.
    Functional aka SingleAbstract Method interfaces - SAM
  • 32.
    Functionality Guava JDK8 Predicate apply(T input) test(T input) Combining predicates Predicates.and/or/not Predicate.and/or/negate Supplier Suplier.get Supplier.get Joiner/StringJoiner Joiner.join() StringJoiner.add() SettableFuture/CompletableFutu re SettableFuture.set(T input) CompletableFuture.complete(T input) Optional Optional.of/ofNullable/empty Optional.of/fromNullable/absent
  • 33.
    Filter collections SortedMap<String, String>map = new TreeMap<>(); map.put("1", "one"); map.put("2", "two"); map.put("3", null); map.put("4", "four"); SortedMap<String, String> filtered = Maps.filterValues(map, Predicates.notNull()); assertThat(filtered.size(), is(3)); // null entry for "3" is gone!
  • 34.
  • 35.
  • 36.
    Java 8 -aggregate operations http://docs.oracle.com/javase/tutorial/collections/streams/index.html roster .stream() .filter(e -> e.getGender() == Person.Sex.MALE) .forEach(e -> System.out.println(e.getName());
  • 37.
    Java 8 -aggregate operations http://docs.oracle.com/javase/tutorial/collections/streams/index.html double average = roster .stream() .filter(p -> p.getGender() == Person.Sex.MALE) .mapToInt(Person::getAge) .average() .getAsDouble();
  • 38.
    Collection goodies // oldway Map<String,Map<Long, List<String>>> mapOld = new HashMap<String, Map<Long, List<String>>>(); // the guava way Map<String, Map<Long, List<String>>> map = Maps.newHashMap(); // list ImmutableList<String> of = ImmutableList.of("a", "b", "c"); // Same one for map ImmutableMap<String, String> theMap = ImmutableMap.of("key1", "value1", "key2", "value2"); //list of ints List<Integer> theList = Ints.asList(1, 2, 3, 4, 522, 5, 6);
  • 39.
    Load resources Resources.getResource("com/tfnico/examples/guava/BaseTest.class"); // insteadof this: String location = "com/tfnico/examples/guava/BaseTest.class"; URL resource2 = this.getClass().getClassLoader().getResource(location); Preconditions.checkArgument(resource2 != null, "resource %s not found", location);
  • 40.
    Hashing HashFunction hf =Hashing.md5(); Customer c = new Customer(); // into is a primitive sink Funnel<? super Customer> customerFunnel = (from, into) -> { into.putString(from.getName(),Charsets.UTF_8); into.putInt(from.getId()); }; HashCode hc = hf.newHasher() .putLong(2) .putString("Mite", Charsets.UTF_8) .putObject(c, customerFunnel) .hash();
  • 41.
    Bloom filter BloomFilter<Customer> awesomeCusumers= BloomFilter.create(customerFunnel, 500, 0.01); List<Customer> friendsList = Lists.newArrayList( new Customer(), new Customer()); for(Customer friend : friendsList) { awesomeCusumers.put(friend); } Customer thatStrangeGuy = new Customer(); if (awesomeCusumers.mightContain(thatStrangeGuy)) { //that strange guy is not a cusumer and we have reachet this line //probablility 0.01 }
  • 42.
  • 43.
    When to useGuava? ● Temporary collections ● Mutable collections ● String Utils ● Check if (x==null) ● Always ?
  • 44.
    Why use aGuava? "I could just write that myself." But… These things are much easier to mess up than it seems •With a library, other people will make your code faster and better for You
  • 45.
    Major stuff Idid not mentioned EventBus IO Reflection Math Ranges
  • 47.