Upload
mite-mitreski
View
50
Download
4
Embed Size (px)
Citation preview
@mitemitreski
The core libraries you always wanted
Google Guava
What is Google Guava?
com.google.common.annotationcom.google.common.basecom.google.common.collectcom.google.common.iocom.google.common.netcom.google.common.primitivescom.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.*
@Testpublic 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 - EE62. edu.umd.cs.findbugs.annotations.NonNull – Findbugs, Sonar3. javax.annotation.Nonnull – JSR-3054. 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 MatchersUse 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 numbersCache<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 PredicatesFunction<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
reSettableFuture.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// oldwayMap<String, Map<Long, List<String>>> mapOld = new HashMap<String, Map<Long, List<String>>>();// the guava wayMap<String, Map<Long, List<String>>> map = Maps.newHashMap();// listImmutableList<String> of = ImmutableList.of("a", "b", "c");// Same one for mapImmutableMap<String, String> theMap = ImmutableMap.of("key1", "value1", "key2", "value2");//list of intsList<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);
HashingHashFunction hf = Hashing.md5();
Customer c = new Customer();// into is a primitive sinkFunnel<? 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 filterBloomFilter<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 itseems
•With a library, other people will make your code faster and betterfor You
Major stuff I did not mentioned
EventBusIOReflectionMathRanges
BG-JUG and JugMK community