Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Clean code with google guava jee conf

9 290 vues

Publié le

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. There will be the slides presenting most useful and interesting features of Guava (v.12) that makes stuff simpler, better and code cleaner. We will cover most of the com.google.common.base.* classes and basic use of functions in collection and Google collections and few other features that are part of Guava and I find them very useful. Some of you will think that there is an overlap with Apache commons – and it’s true, but Guava is built with expectation that there is a Function and a Predicate class as well as various builders which makes it really cool and simple for many use cases.

Publié dans : Technologie, Formation
  • Thanks for for this overview of the Guava features, i didn't know anything about this library but now that i've read a little about it, i want to know more, it's going to be really useful
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici

Clean code with google guava jee conf

  1. 1. 
  2. 2. Guava is…
  3. 3. Guava is…a fruithttps://en.wikipedia.org/wiki/Guava
  4. 4. What is Google Guava?annotationsbasic utilitiescollectionsconcurrencycomparisonstringsprimitivesrangesfunctional idiomsI/ocachinghashingevent busmathreflectionnet/http
  5. 5. What in this presentation?annotationsbasic utilitiescollectionsconcurrencycomparisonstringsprimitivesrangesfunctional idiomsI/Ocachinghashingevent busmathreflectionnet/http
  6. 6. Why Guava? The goal is for you to write less code ... Make code more readable, cleaner and simpler Helps developers to focus on business logic ratherthan writing java utilities Saves time, resources and improve productivity Popular API and active development Mainstream Basically... a painkiller and natural extension for Java
  7. 7. I Couldve Invented That
  8. 8. ref. Effective JavaItem 47, "Know and use the libraries“
  9. 9. Guava Releases About every 3 months, with significant newfunctionality and fixes Release 14.0.1 was released on March 15, 2013 All releases are either major or patch releases Never minor
  10. 10. Let’s get some Guava!
  11. 11. @annotations
  12. 12. Guava Basic Utilities String Utilities Preconditions Objects Helper Avoiding Nulls StopWatch
  13. 13. String Utilities Joiner Splitter CharMatcher
  14. 14. Joining Strings Who here has ever written this utility?public class StringUtil {public static String join(String separator, Iterable<String> pieces) {// any of ~5 common implementations goes here}}
  15. 15. Joining Strings Converts collections into single String object Joining an Iterable, Iterator, varargs/array Return a String, or append to an Appendable Throws a NPE on null objects, unless: .skipNulls() .useForNull(String) It also works with Maps We could be looking at 18 to 48 different methods
  16. 16. Joining Strings (cont.)List<String> fruits = Arrays.asList("apple", null, "orange", null, null, "guava");String joined = Joiner.on(", ").skipNulls().join(fruits);>> "apple, orange, guava"
  17. 17. Joining Strings (cont.)List<String> fruits = Arrays.asList("apple", null, "orange", null, null, "guava");String joined = Joiner.on(", ").skipNulls().join(fruits);>> "apple, orange, guava"String joined = Joiner.on(",").useForNull("banana").join(fruits);>> "apple, banana, orange, banana, banana, guava"
  18. 18. Splitting Strings Working in the opposite direction than Joiner Allows to split String into collection of elements String.split() on steroids  A better, more intuitive String.split() Doesnt silently discard trailing separators Handles empty pieces predictably
  19. 19. SplitterString input = ",, ,apple, orange ,,, banana,, ,guava, ,,";Iterable<String> split = Splitter.on(,).omitEmptyStrings().trimResults().split(input);>> [ "apple", "orange", "banana", "guava" ] The default behavior is simplistic If you want extra features, ask for them!
  20. 20. SplitterString input = ",, ,apple, orange ,,, banana,, ,guava, ,,";Iterable<String> split = Splitter.on(,).omitEmptyStrings().trimResults().split(input);>> [ "apple", "orange", "banana", "guava" ] The default behavior is simplistic If you want extra features, ask for them! By default, assumes nothing about whitespace These classes use what Googlers (tentatively) call the "Utility Object pattern."
  21. 21. Splitter more…Splitter.onPattern("d+").split("Java3Scala4Haskell0Brainfuck5Kotlin");>> [ "Java ", "Scala", "Haskell", "Brainfuck", "Kotlin" ]Splitter.on(CharMatcher.inRange(3,5)).split("Java3Scala4Haskell0Brainfuck5Kotlin");>> [ "Java", "Scala", "Haskell0Brainfuck", "Kotlin" ] Split using regular expression Split using CharMatcher
  22. 22. CharMatcher CharMatcher provides many text processingmethods based on “matching character” notation Separates "configuration" from "processing" CharMatcher represents two notions: What constitutes a matching character? What to do with those matching characters? Can also be used to "filter" chars
  23. 23. CharMatcher (cont.) Allows to check if a sequence of characters satisfiesgiven condition:WHITESPACE, ASCII, ANY, DIGIT (many pre-defined sets)is(x)isNot(_)oneOf("aeiou")inRange(a, z) .or (inRange(A, Z)).negate()
  24. 24. All that you can do... CharMatcher Provides methods to modify char sequences:boolean matchesAllOf(CharSequence)boolean matchesAnyOf(CharSequence)boolean matchesNoneOf(CharSequence)int indexIn(CharSequence, int)int lastIndexIn(CharSequence, int)int countIn(CharSequence)String removeFrom(CharSequence)String retainFrom(CharSequence)String trimFrom(CharSequence)String trimLeadingFrom(CharSequence)String trimTrailingFrom(CharSequence)String collapseFrom(CharSequence, char)String trimAndCollapseFrom(CharSequence, char)String replaceFrom(CharSequence, char)
  25. 25. CharMatcher (example)CharMatcher matcher = CharMatcher.DIGIT.or(CharMatcher.inRange(a, z).or(CharMatcher.inRange(A, Z)));if (matcher.matchesAllOf("this1will2match3")) {// ...}
  26. 26. CharMatcher (example)// eliminate all characters that arent digits or lowercaseString lowerAndDigit = CharMatcher.DIGIT.or(CharMatcher.JAVA_LOWER_CASE).retainFrom(input);CharMatcher matcher = CharMatcher.DIGIT.or(CharMatcher.inRange(a, z).or(CharMatcher.inRange(A, Z)));if (matcher.matchesAllOf("this1will2match3")) {// ...}
  27. 27. CharMatcher (example)String pass = “$$$ secret passcode $$$";String result = CharMatcher.is(“$”).trimFrom(pass);>> “ secret password "trimLeadingFrom(), trimTrailingFrom() or trimAndCollapseFrom()
  28. 28. Guava Basic Utilities String Utilities Preconditions Objects Helper Avoiding Nulls StopWatch
  29. 29. checkState(boolean) Throws IllegalStateException if false Used to check object stateif (state != State.PLAYABLE) {throw new IllegalStateException("Cant play movie; state is " + state);}
  30. 30. checkState(boolean) Throws IllegalStateException if false Used to check object state… or…if (state != State.PLAYABLE) {throw new IllegalStateException("Cant play movie; state is " + state);}Preconditions.checkState(state == State.PLAYABLE,"Cant play movie; state is %s", state);(whats the difference? none!)
  31. 31. checkNotNull(T) Throws NullPointerException if null Returns the value. Can be used inline.public Car(Engine engine) {this.engine = Preconditions.checkNotNull(engine);}
  32. 32. checkNotNull(T) Throws NullPointerException if null Returns the value. Can be used inline.. . . with using static import . . .public Car(Engine engine) {this.engine = Preconditions.checkNotNull(engine);}public Car(Engine engine) {this.engine = checkNotNull(engine,“engine cannot be null”);}
  33. 33. checkArgument(boolean) Throws IllegalArgumentException if false Used to validate method argumentspublic void drive(double speed) {Preconditions.checkArgument(speed > 0.0,"Speed (%s) must be positive", speed);}
  34. 34. Why Preconditions? Defensive coding  Useful for validation Each method has three variants: No extra arguments An extra object for error message An extra String & Objects. String.format likebut only allows %s Recommended to be used as static imports
  35. 35. Guava Basic Utilities String Utilities Preconditions Objects Helper Avoiding Nulls StopWatch
  36. 36. Object common methodsObjects.equal(Object, Object)Objects.hashCode(Object...)Objects.toStringHelper(Object)Objects.firstNonNull(T, T)
  37. 37. equal(…) & hashCode(…)public class Person {private final String name, nickname;private final Movie favoriteMovie;@Overridepublic boolean equals(Object object) {if (object instanceof Person) {Person that = (Person) object;return Objects.equal(this.name, that.name)&& Objects.equal(this.nickname, that.nickname)&& Objects.equal(this.favoriteMovie, that.favoriteMovie);}return false;}@Overridepublic int hashCode() {return Objects.hashCode(name, nickname, favoriteMovie);}
  38. 38. toStringHelper(…) & firstNonNull(T, T)@Overridepublic String toString() {// speakers is @Nullable!return Objects.toStringHelper(this).add("conference", name).add(“location", location).add("speakers", speakers).omitNullValues().toString();}>> "Person{name=JeeConf, location=Kiev}“// w/o omitNullValues()>> "Person{name=JeeConf, location=Kiev, speakers=null}“public String preferredLocation() {return Objects.firstNonNull(location, name);}
  39. 39. Guava Basic Utilities String Utilities Preconditions Objects Helper Avoiding Nulls StopWatch
  40. 40. Null is ambiguousif (x != null && x.someM() != null && ..) {// some code…}
  41. 41. Problem with NullNo entry? Or entry exists but the nickname is unlisted?Person person = personService.findByNickname(“Andy");if (person == null) {// what does this mean?}
  42. 42. Problem with NullNo entry? Or entry exists but the nickname is unlisted?The value in the map is null, or the value is not in themap. Null can mean failure, can mean success, canmean almost anything.Person person = personService.findByNickname(“Andy");if (person == null) {// what does this mean?}Map.get(key)
  43. 43. Optional<T> vs. null null is "hidden", Optional is ”explicit” An immutable wrapper that is either: present: contains a non-null reference absent: contains nothing Note that it never "contains null" Possible uses: return type “a T that must be present" "a T that might be absent" distinguish between "unknown" (for example, not present in a map) "known to have no value" (present in the map, with valueOptional.absent()) wrap nullable references for storage in a collection that doesnot support null
  44. 44. Optional<T>// Make optional of given typeOptional<String> possible = Optional.of(“Ido”);Optional<String> value = Optional.fromNullable(str);if (value.isPresent()) {// ...}// returns true if nonNullpossible.isPresent();// returns this possible value or defaultpossible.or(“Nick”);// returns Idopossible.get();
  45. 45. Making an Optional Optional.of(T) - make optional of given non-nullvalue or fail fast on null Optional.absent() - return an absent optional ofsome type Optional.fromNullable(T) - turn value inOptional and treat null as absent
  46. 46. For null-unfriendly collections Many collections, including the JDKs Queue andConcurrentMap implementations, dont allow nullelements. Queue<Optional<Foo>> is a simple and naturalsolution!
  47. 47. Others… Strings Methods are primarily for interfacing withunpleasant APIs that equate null strings and emptystrings:Strings.emptyToNull(String)Strings.isNullOrEmpty(String)Strings.nullToEmpty(String)
  48. 48. https://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained
  49. 49. Guava Basic Utilities String Utilities Preconditions Objects Helper Avoiding Nulls StopWatch
  50. 50. StopWatch Class for measuring elapsed time Prefer StopWatch over System.nanoTime() Dont use System.currentTimeMillis()! Provides methods that automatically calculate timebetween start() and stop() execution
  51. 51. StopWatchpublic void measureElapsedTime(Collection<String> input) {Stopwatch stopwatch = new Stopwatch().start();doSomeOperation(input);long nanos = stopwatch.elapsed(TimeUnit.NANOSECONDS);}
  52. 52. StopWatch Pros StopWatch uses nanoTime() but exposes only relativetimings, a meaningless absolute value Alternate time sources can be substituted using Ticker(read() returns nanoseconds) Can be easily mocked with custom passing time provider Returns counted time using different units toString() gives human readable format
  53. 53. Functional Concepts brought to Java Many things in Guava are inspired by functionalconcepts from other programming languages In Java can only be approximated through awkwardand verbose use of anonymous classes Expected to change in Java 8 Guava is currently aimed at users of Java 5 andabove
  54. 54. Core concepts Key functional concepts Guava uses:
  55. 55. Core concepts Key functional concepts Guava uses: Function<F, T> == F => T=> to transform a collectionpublic interface Function<F, T> {@Nullable T apply(@Nullable F input);}
  56. 56. Core concepts Key functional concepts Guava uses: Function<F, T> == F => T=> to transform a collection Predicate<T> == T => Boolean=> filter out a collectionpublic interface Function<F, T> {@Nullable T apply(@Nullable F input);}public interface Predicate<T> {boolean apply(@Nullable T input);}
  57. 57. Function<F,T> usageIterables.transform()FluentIterable.transform()Iterators.transform()Collections2.transform()Lists.transform()Maps, Multimaps … etc. Main usage with transform() Tools to manipulate collections using Function:
  58. 58. FluentIterable API Chaining methods (return FluentIterable<T>) filter(Predicate) transform(Function) skip(int), limit(int) cycle() Query methods (return boolean) allMatch(Predicate), anyMatch(Predicate) contains(Object) isEmpty() Extraction methods (return Optional<T>) first(), last(), firstMatch(Predicate), get(int) Conversion methods (return a copied Collection<T>) toList(), toSet(), toSortedSet(), toArray()
  59. 59. Function <F,T> Java 7 doesnt have lambda expressions, but Guavahelps us out (a bit) with Functionpublic void demo(Collection<String> input) {Function<String, String> toUpperCase =new Function<String, String>() {@Overridepublic String apply(String string) {return string.toUpperCase();}};Collection<String> transformed =Collections2.transform(input, toUpperCase);}
  60. 60. Predicate<T> usage Predicate checks if condition is met for passed object Tools to manipulate collections using Predicate:FluentIterables.filter()Iterables.filter()Iterators.filter()Collections2.filter()Sets.filter()Maps, MultiMaps, … etc.
  61. 61. Predicate <T> Quite similar to Function but does NOT extend it Predicate<User> onlyAwesome = new Predicate<User>() {@Overridepublic boolean apply(User in) {return Optional.fromNullable(in).or(User.NOT_AWESOME).isAwesome();}};
  62. 62. Predicate <T> Lets use it on a collection:Iterable<User> users = getMixedUsers();// find all awesome usersIterable<User> onlyAwesomeUsers = Iterables.filter(users, onlyAwesome);// find one (first) awesome userUser awesomeUser = Iterables.find(users, onlyAwesome);// or betterOptional<User> awesomeOrAbsent = Iterables.tryFind(users, onlyAwesome);
  63. 63. Putting it togetherprivate Iterable<Integer> puttingItTogether(Iterable<Integer> numbers){FluentIterable<Integer> squaresOfEvens =FluentIterable.from(numbers).filter(new Predicate<Integer>() {@Overridepublic boolean apply(Integer input) {checkNotNull(input, "nulls are not allowed here!");return input % 2 == 0;}}).transform(new Function<Integer, Integer>() {@Overridepublic Integer apply(Integer input) {checkNotNull(input, "nulls are not allowed here!");return input * input;}});return squaresOfEvens;}
  64. 64. … OrList<Integer> squaresOfEvens = Lists.newArrayList();for (Integer number : givenNumbers) {if (number % 2 == 0) {squaresOfEvens.add(number * number);}}>> [ 4, 16, 36, 64, 100 ]
  65. 65. … MoralList<Integer> squaresOfEvens = Lists.newArrayList();for (Integer number : givenNumbers) {if (number % 2 == 0) {squaresOfEvens.add(number * number);}}>> [ 4, 16, 36, 64, 100 ] Just be careful!! Functional style can be great but its notautomatically the better way to go.
  66. 66. Java Caching
  67. 67. Java Caching with Guava Guava has a powerful on-heap key→value cache Thread-safe implementation More or less internally similar to ConcurrentMap +automatic eviction No explicit support for distributed caching
  68. 68. Types of Caches Provides two types of caches: LoadingCache - knows how to load entries whena cache miss occurs LoadingCache.get(key) returns the value associated withkey, loading it first if necessary Cache - does not automatically load entries Were going to focus on the loading case here; itsusually what you want
  69. 69. Caches (example)CacheLoader<String, Graph> loader =new CacheLoader<String, Graph>() {@Overridepublic Graph load(String key) {return createExpensiveGraph(key);}};LoadingCache<String, Graph> cache =CacheBuilder.newBuilder().build(loader);
  70. 70. CacheBuilder The CacheBuilder has next properties: Cache size Time to expire entries after last access Time based expiration of entries after being updated Use of weak or soft references for keys/values Setting RemovalListener that can receive events oncean entry is removed fro the cache. Concurrency level for update operations (defaults to 4) Enable recording caching stats
  71. 71. CacheBuilder (example)LoadingCache<String, String> cache = CacheBuilder.newBuilder().maximumSize(1000).expireAfterAccess(10, TimeUnit.SECONDS).recordStats().build(new CacheLoader<String, String>() {@Overridepublic String load(String key) throws Exception {return key.toUpperCase();}});
  72. 72. Concurrency Cache instances are internally implemented verysimilar to ConcurrentHashMap (thus thread-safe) CacheLoader.load will be invoked a single time foreach key, regardless of the number of requestingthreads The result will be returned to all requestingthreads and inserted into the cache using theequivalent of putIfAbsent
  73. 73. Cache Eviction By size .maximumSize(long) By custom weight: .weigher(Weigher) .maximumWeight(long) By time: .expireAfterAccess(long, TimeUnit) .expireAfterWrite(long, TimeUnit)
  74. 74. Cache Eviction (cont.) Reference-based eviction: .weakKeys() .weakValues() .softValues() Explicit: .invalidate(key) .invalidateAll(keys) .invalidateAll()
  75. 75. Checked Exceptions What if loading causes a checked exception?CacheLoader<String, String> checkedLoader =new CacheLoader<String, String>() {@Overridepublic String load(String key) throws IOException {return loadFromDisk(key);}};
  76. 76. Checked Exceptions (cont.)LoadingCache<String, String> cache =CacheBuilder.newBuilder().build(checkedLoader);try {cache.get(key);} catch (ExecutionException e) {// ensure stack trace is for this threadthrow new IOException(e.getCause());}
  77. 77. Cache Stats hitCount – number of times Cache returned thecached value missCount – number of times Cache returneduncached value loadSuccessCount – number of times Cacheloaded new value successfully
  78. 78. Cache Stats (example)LoadingCache<String, String> cache =CacheBuilder.newBuilder().recordStats().build(checkedLoader);// cumulative stats since cache creationCacheStats stats = cache.stats();CacheStats{hitCount=4, missCount=3, loadSuccessCount=3,loadExceptionCount=0, totalLoadTime=676064, evictionCount=0}
  79. 79. …Collections
  80. 80. MultiSet<E> Implements Collection<E>List: [a, c, b, b, c, a, a, b]Set: [a, c, b]Multiset: [a, a, a, c, c, b, b, b]
  81. 81. MultiSet<E> Implements Collection<E>List: [a, c, b, b, c, a, a, b]Set: [a, c, b]Multiset: [a, a, a, c, c, b, b, b] So a Multiset<E> implementation only needs tostore one occurrence of each element, plus a count![a x 3, c x 2, b x 3]
  82. 82. MultiSet<E> Add multiple instances of a given element Counts how many occurrences exist Similar to a Map<E, Integer>, but... only positive counts size() returns total # of items, not # keys count() for a non-existent key is 0 iterator() goes over each element Usage: i.e. Track frequencies of elements, e.g. "wordcounting"
  83. 83. MultiSet<E> Implementations HashMultiset TreeMultiset LinkedHashMultiset ConcurrentHashMultiset ImmutableMultiset
  84. 84. Tired of this?Map<String, List<String>>
  85. 85. Tired of this?Map<String, List<String>>{a=1, a=2, b=3, c=4, c=5, c=6}
  86. 86. Try …
  87. 87. MultiMap<K, V> Like Map (key-value pairs), but may have duplicates The values related to a single key can be viewed as acollection (set or list) Similar to a Map<K, Collection<V>>, but... get() never returns null (returns an empty collection) containsKey() is true only if 1 or more values exist entries() returns all entries for all keys size() returns total number of entries, not keys asMap() to view it as a Map<K, Collection<V>>
  88. 88. MultiMap<K, V>Multimap<String, String> mm = ArrayListMultimap.create();Collection<String> smiths = mm.get("Smith");>> empty collection (never null)mm.put("Smith", "John");mm.put("Smith", "Alice");mm.put("Smith", "Diane");smiths = mm.get("Smith");>> [ "John", "Alice", "Diane" ]
  89. 89. MultiMap Implementations ArrayListMultimap HashMultimap LinkedListMultima LinkedHashMultimap TreeMultimap ImmutableListMultimap ImmutableSetMultimap
  90. 90. BiMap<K1, K2> Bi-directional Map Both keys and values are unique Can view the inverse map with inverse() Use instead of maintaining two separatemaps: Map<K1, K2> Map<K2, K1>
  91. 91. Static utilities In classes with name ending with an s Lists Maps Multimaps Multisets Sets SortedMaps Tables Iterators Iterables Collections2
  92. 92. Static factories methods Rather than typing you typeMap<String, Class<? extends Handler>> m =new HashMap<String, Class<? extends Handler>>();Map<String, Class<? extends Handler>> m2 = Maps.newHashMap();
  93. 93. Guava Alternatives Should you use Guava or Apache Commons? We may be biased, so consult this question on StackOverflow: http://tinyurl.com/guava-vs-apache The large number of upvotes for the top answersshows a pretty strong community consensus
  94. 94. Need help with a problem? Post to Stack Overflow! Use the "guava" tag Report a defect, request an enhancement? http://code.google.com/p/guava-libraries/issues/list Start an email discussion? Send to guava-discuss@googlegroups.com General discussion takes place on http://groups.google.com/group/guava-discuss The Guava team is generally highly active in all ofthese areas
  95. 95. Time to Play
  96. 96. What to Remember  Functional flavor of collection handling CharMatcher / Splitter / Joiner Avoid null  where possible Ease of Preconditions Caching Multimap / Multiset / Bimap
  97. 97. Q&Ahttp://www.flickr.com/photos/wwworks/4759535950/sizes/o/in/photostream/
  98. 98. References http://code.google.com/p/guava-libraries/ http://code.google.com/p/guava-libraries/downloads/list