Google Guava - Core libraries for Java & Android
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Google Guava - Core libraries for Java & Android

on

  • 6,140 views

Talk at GDG DevFest Barcelona 2013. ...

Talk at GDG DevFest Barcelona 2013.

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.

Statistics

Views

Total Views
6,140
Views on SlideShare
5,778
Embed Views
362

Actions

Likes
25
Downloads
131
Comments
0

8 Embeds 362

https://twitter.com 156
http://www.scoop.it 120
https://postre.am 80
https://www.linkedin.com 2
http://webcache.googleusercontent.com 1
http://www.linkedin.com 1
http://wada811.tumblr.com 1
http://radi0ant.hatenablog.com 1
More...

Accessibility

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Google Guava - Core libraries for Java & Android Presentation Transcript

  • 1. Google Guava Core libraries for Java & Android @jordi9 11 / oct / 2013
  • 2. ...shameless self-promotion bro!
  • 3. Write less code
  • 4. Write cleaner code
  • 5. Write more readable code
  • 6. The “wheel”
  • 7. com.google.guava:guava:15.0
  • 8. Basics
  • 9. Basics Avoid using null
  • 10. Basics: Avoid using null “Null sucks” Doug Lea - JCP, OpenJDK
  • 11. Basics: Avoid using null “I call it my billion-dollar mistake” Sir C.A.R. Hoare - Inventor of null
  • 12. Basics: Avoid using null @Google 95% of collections weren’t supposed to have null values.
  • 13. map = {Foo: bar, null, Baz: qux} Basics: Avoid using null
  • 14. map = {Foo: bar, null, Baz: qux} map.get(“Foo”); Basics: Avoid using null
  • 15. map = {Foo: bar, null, Baz: qux} map.get(“Foo”); // returns Foo Basics: Avoid using null
  • 16. map = {Foo: bar, null, Baz: qux} map.get(“Foo”); map.get(“quux”); Basics: Avoid using null
  • 17. map = {Foo: bar, null, Baz: qux} map.get(“Foo”); map.get(“quux”); // returns null Basics: Avoid using null
  • 18. map = {Foo: bar, null, Baz: qux} map.get(“Foo”); map.get(“quux”); map.get(null); Basics: Avoid using null
  • 19. map = {Foo: bar, null, Baz: qux} map.get(“Foo”); map.get(“quux”); map.get(null); // returns null Basics: Avoid using null
  • 20. map = {Foo: bar, null, Baz: qux} map.get(“Foo”); map.get(“quux”); // returns null map.get(null); // returns null Basics: Avoid using null
  • 21. map = {Foo: bar, null, Baz: qux} map.get(“Foo”); map.get(“quux”); // returns null map.get(null); // returns null // Null to indicate absence // vs null value Basics: Avoid using null
  • 22. Optional<T> Basics: Avoid using null
  • 23. Optional<T> Optional<String> foo = Optional.of(“foo”) Basics: Avoid using null
  • 24. Optional<T> Optional<String> foo = Optional.of(“foo”) foo.isPresent(); // returns true Basics: Avoid using null
  • 25. Optional<T> Optional<String> foo = Optional.of(“foo”) foo.isPresent(); foo.get(); // returns “foo” Basics: Avoid using null
  • 26. Optional.of(foo); // not nullable Goodies! RTFM, I mean javadoc
  • 27. Optional.of(foo); Optional.absent(); Goodies! javadoc
  • 28. Optional.of(foo); Optional.absent(); Optional.fromNullable(legacyCode); Goodies! javadoc
  • 29. Optional.of(foo); Optional.absent(); Optional.fromNullable(legacyCode); foo.get(); // may return “foo” Goodies! javadoc
  • 30. Optional.of(foo); Optional.absent(); Optional.fromNullable(legacyCode); foo.get(); foo.or(“bar”); // return “bar” if foo is absent Goodies! javadoc
  • 31. Optional.of(foo); Optional.absent(); Optional.fromNullable(legacyCode); foo.get(); foo.or(“bar”); foo.orNull(); // Deal with code that need nulls, duh Goodies! javadoc
  • 32. Optional<T> is IDIOT-PROOF-NESS Bottom line
  • 33. Basics Preconditions
  • 34. if (seats <= 0) { throw new IllegalArgumentException(“Seats must be positive, but was ” + seats); } Basics: Preconditions
  • 35. if (seats <= 0) { throw new IllegalArgumentException(“Seats must be positive, but was ” + seats); } checkArgument(seats > 0, “Seats must be positive, but was %s”, seats); Basics: Preconditions
  • 36. // Always use static import import static com.google.common.base.Preconditions.checkArgument; checkArgument(seats > 0, “Seats must be positive, but was %s”, seats); Basics: Preconditions
  • 37. import static com.google.common.base.Preconditions.checkArgument; // Check what you expect to be true checkArgument(seats > 0, “Seats must be positive, but was %s”, seats); Basics: Preconditions
  • 38. import static com.google.common.base.Preconditions.checkArgument; // “%s” specifier is recognized as a placeholder in // these messages (the only one) checkArgument(seats > 0, “Seats must be positive, but was %s”, seats); Basics: Preconditions
  • 39. void execute(Job job) { // serious business } Basics: Preconditions
  • 40. void execute(Job job) { checkNotNull(job, “Job can’t be null”); // serious business } // checkNotNull() throws NullPointerException Basics: Preconditions
  • 41. void execute(Job job) { checkNotNull(job, “Job can’t be null”); checkArgument(!job.started(), “Job already started”); // serious business } // checkArgument() throws IllegalArgumentException // checkNotNull() throws NullPointerException Basics: Preconditions
  • 42. void execute(Job job) { checkNotNull(job, “Job can’t be null”); checkArgument(!job.started(), “Job already started”); // serious business checkState(seatsAvailabe <= totalSeats, “You’ve sold more seats than available! This should never happen. %s/%s”, seatsAvailable, totalSeats); } // checkState() throws IllegalStateException // checkArgument() throws IllegalArgumentException // checkNotNull() throws NullPointerException Basics: Preconditions
  • 43. this.foo = checkNotNull(foo); // inline assig Goodies! javadoc
  • 44. this.foo = checkNotNull(foo); // list, string or array checks checkElementIndex(index, size); checkPositionIndex(index, size); checkPositionIndexes(start, end, size); Goodies! javadoc
  • 45. Preconditions will save your ass Bottom line
  • 46. Basics Objects
  • 47. @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj == null || obj.getClass() != this.getClass()) { return false; } Person guest = (Person) obj; return id == guest.id && (firstName == guest.firstName || (firstName != null && firstName.equals(guest.getFirstName()))) && (lastName == guest.lastName || (lastName != null && lastName.equals(guest.getLastName()))); } Basics: Objects
  • 48. @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj == null || obj.getClass() != this.getClass()) { return false; } Person guest = (Person) obj; return id == guest.id && (firstName == guest.firstName || (firstName != null && firstName.equals(guest.getFirstName()))) && (lastName == guest.lastName || (lastName != null && lastName.equals(guest.getLastName()))); } Basics: Objects F
  • 49. @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj == null || obj.getClass() != this.getClass()) { return false; } Person guest = (Person) obj; return id == guest.id && (firstName == guest.firstName || (firstName != null && firstName.equals(guest.getFirstName()))) && (lastName == guest.lastName || (lastName != null && lastName.equals(guest.getLastName()))); } Basics: Objects FM
  • 50. @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj == null || obj.getClass() != this.getClass()) { return false; } Person guest = (Person) obj; return id == guest.id && (firstName == guest.firstName || (firstName != null && firstName.equals(guest.getFirstName()))) && (lastName == guest.lastName || (lastName != null && lastName.equals(guest.getLastName()))); } Basics: Objects FML
  • 51. @Override public boolean equals(Object obj) { if (obj instanceof Person) { Person that = (Person) obj; return Objects.equal(firstName, that.firstName) && Objects.equal(lastName, that.lastName); } else { return false; } } Basics: Objects
  • 52. @Override public boolean equals(Object obj) { if (obj instanceof Person) { Person that = (Person) obj; return Objects.equal(firstName, that.firstName) // null safe! && Objects.equal(lastName, that.lastName); // null safe x2! } else { return false; } } Basics: Objects
  • 53. @Override public boolean equals(Object obj) { if (obj instanceof Person) { Person that = (Person) obj; return Objects.equal(firstName, that.firstName) && Objects.equal(lastName, that.lastName); } else { return false; } } // JDK 1.7 introduced equivalent Objects.equals() method. Basics: Objects
  • 54. @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((firstName == null) ? 0 : firstName.hashCode()); result = prime * result + id; result = prime * result + ((lastName == null) ? 0 : lastName.hashCode()); return result; } Basics: Objects
  • 55. @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((firstName == null) ? 0 : firstName.hashCode()); result = prime * result + id; result = prime * result + ((lastName == null) ? 0 : lastName.hashCode()); return result; } // oh, grumpy cat! Basics: Objects
  • 56. @Override public int hashCode() { return Objects.hashCode(firstName, lastName); } Basics: Objects
  • 57. @Override public int hashCode() { // sensible, order-sensitive hash return Objects.hashCode(firstName, lastName); } Basics: Objects
  • 58. @Override public int hashCode() { return Objects.hashCode(firstName, lastName); } // JDK 1.7 introduced equivalent Objects.hash() method. Basics: Objects
  • 59. @Override public String toString() { } Basics: Objects
  • 60. @Override public String toString() { } Basics: Objects
  • 61. @Override public String toString() { return Objects.toStringHelper(this) .add("firstName", firstName) .add("lastName", lastName) .add("catName", catName) .toString(); } Basics: Objects
  • 62. @Override public String toString() { return Objects.toStringHelper(this) .add("firstName", firstName) .add("lastName", lastName) .add("catName", catName) .toString(); } // returns Person{firstName=Solid, lastName=Snake, catName=null} Basics: Objects
  • 63. @Override public String toString() { return Objects.toStringHelper(this) .add("firstName", firstName) .add("lastName", lastName) .add("catName", catName) .omitNullValues() .toString(); } Basics: Objects
  • 64. @Override public String toString() { return Objects.toStringHelper(this) .add("firstName", firstName) .add("lastName", lastName) .add("catName", catName) .omitNullValues() .toString(); } // returns Person{firstName=Solid, lastName=Snake} Basics: Objects
  • 65. IntelliJ IDEA support for ToStringHelper() Generate toString() > Template Objects.ToStringHelper (Guava) Goodies! javadoc
  • 66. So common stuff should ring a bell Bottom line
  • 67. Basics Ordering
  • 68. Comparator<Person> byDescAgeName = new Comparator<Person>() { public int compare(Person p1, Person p2) { int result = p2.getAge() - p1.getAge(); // ugh! return (result == 0) ? p1.compareTo(p2) : result; } }; // Ok, it’s not that bad -- But it’s pretty hard to get Basics: Ordering
  • 69. Comparator<Person> byDescAgeName = new Comparator<Person>() { public int compare(Person p1, Person p2) { int result = p2.getAge() - p1.getAge(); // ugh! return (result == 0) ? p1.compareTo(p2) : result; } }; // Ok, it’s not that bad -- But it’s pretty hard to get // We’re lucky ints and Person are Comparable, otherwise you’ll // have to implement it Basics: Ordering
  • 70. Comparator<Person> byDescAgeName = new Comparator<Person>() { public int compare(Person p1, Person p2) { return ComparisonChain.start() .compare(p2.getAge(), p1.getAge()) .compare(p1, p2) .result(); } }; Basics: Ordering
  • 71. Comparator<Person> byDescAgeName = new Comparator<Person>() { public int compare(Person p1, Person p2) { return ComparisonChain.start() .compare(p2.getAge(), p1.getAge()) .compare(p1, p2) .result(); } }; // Short-circuits: If one comparison is not equals, stop and return Basics: Ordering
  • 72. Comparator<Person> byDescAgeName = Ordering.natural() .reverse() .onResultOf(new Function<Person, Integer>() { public Integer apply(Person person) { return person.getAge(); }}) .compound(Ordering.natural()); } }; Basics: Ordering
  • 73. Comparator<Person> byDescAgeName = Ordering.natural() .reverse() .onResultOf(new Function<Person, Integer>() { public Integer apply(Person person) { return person.getAge(); }}) .compound(Ordering.natural()); } }; // Read backwards Basics: Ordering
  • 74. Ordering is an “enriched” Comparator. It’s fuuuuuuuun! Goodies! javadoc
  • 75. Ordering is an “enriched” Comparator. It’s fluent. Goodies! javadoc
  • 76. Ordering is an “enriched” Comparator. It’s fluent. // Subclass Ordering and implement compare(T,T) Ordering<Throwable> ORDER_BY_CLASS_NAME = (left, right) -> { return Ordering.usingToString() .compare(left.getClass(), right.getClass()); }; Goodies! javadoc
  • 77. Ordering is an “enriched” Comparator. It’s fluent. // Subclass Ordering and implement compare(T,T) Ordering<Throwable> ORDER_BY_CLASS_NAME = (left, right) -> { return Ordering.usingToString() .compare(left.getClass(), right.getClass()); }; // Or create one Ordering.from(comparator); Ordering.natural(); Goodies! javadoc
  • 78. Ordering is an “enriched” Comparator. It’s fluent. // Subclass Ordering and implement compare(T,T) Ordering<Throwable> ORDER_BY_CLASS_NAME = (left, right) -> { return Ordering.usingToString() .compare(left.getClass(), right.getClass()); }; // Or create one Ordering.from(comparator); Ordering.natural(); // And chain! ORDER_BY_CLASS_NAME.nullsFirst().reverse().compound(comparator); Goodies! javadoc
  • 79. There’s a better way than Comparator Bottom line
  • 80. Basics Throwables
  • 81. void oneLineOfCode() { DatagramPacket packet = new DatagramPacket(data, length); } Basics: Throwables
  • 82. void oneLineOfCode() { DatagramPacket packet = new DatagramPacket(data, length); } // Compile error, throws IOException Basics: Throwables
  • 83. void oneLineOfCode() throws IOException { DatagramPacket packet = new DatagramPacket(data, length); } void someLayer() { oneLineOfCode(); } Basics: Throwables
  • 84. void oneLineOfCode() throws IOException { DatagramPacket packet = new DatagramPacket(data, length); } void someLayer() { oneLineOfCode(); } // Compile error, throws IOException Basics: Throwables
  • 85. void oneLineOfCode() throws IOException { DatagramPacket packet = new DatagramPacket(data, length); } void someLayer() throws IOException { oneLineOfCode(); } void someCoolAbstraction() { someLayer(); } Basics: Throwables
  • 86. void oneLineOfCode() throws IOException { DatagramPacket packet = new DatagramPacket(data, length); } void someLayer() throws IOException { oneLineOfCode(); } void someCoolAbstraction() { someLayer(); } // Compile error, AGAIN Basics: Throwables
  • 87. void oneLineOfCode() throws IOException { DatagramPacket packet = new DatagramPacket(data, length); } void someLayer() throws IOException { oneLineOfCode(); } void someCoolAbstraction() throws IOException { someLayer(); } Basics: Throwables
  • 88. void oneLineOfCode() throws IOException { DatagramPacket packet = new DatagramPacket(data, address); } void someLayer() throws IOException { oneLineOfCode(); } void someCoolAbstraction() throws IOException { someLayer(); } // c’mon... Basics: Throwables
  • 89. void oneLineOfCode() { // Take 2 DatagramPacket packet = new DatagramPacket(data, length); } Basics: Throwables
  • 90. void oneLineOfCode() { try { DatagramPacket packet = new DatagramPacket(data, length); } catch (IOException e) { } } Basics: Throwables
  • 91. void oneLineOfCode() { try { DatagramPacket packet = new DatagramPacket(data, length); } catch (IOException e) { // Really? Swallow? Sure? At least explain why! } } Basics: Throwables
  • 92. void oneLineOfCode() { try { DatagramPacket packet = new DatagramPacket(data, length); } catch (IOException e) { SendMeAnEmail.error(); } } Basics: Throwables
  • 93. void oneLineOfCode() { try { DatagramPacket packet = new DatagramPacket(data, length); } catch (IOException e) { SendMeAnEmail.error(); Oh.theLogger().fatal(“WHY Y U FATAL NOW?”); } } Basics: Throwables
  • 94. void oneLineOfCode() { try { DatagramPacket packet = new DatagramPacket(data, length); } catch (IOException e) { SendMeAnEmail.error(); Oh.theLogger().fatal(“WHY Y U FATAL NOW?”); // repeat for every catch block } } Basics: Throwables
  • 95. void oneLineOfCode() { try { DatagramPacket packet = new DatagramPacket(data, length); } catch (IOException e) { SendMeAnEmail.error(); Oh.theLogger().fatal(“WHY Y U FATAL NOW?”); // repeat for every catch block // AGAIN AND AGAIN } } Basics: Throwables
  • 96. void oneLineOfCode() { try { DatagramPacket packet = new DatagramPacket(data, address); } catch (IOException e) { SendMeAnEmail.error(); Oh.theLogger().fatal(“WHY Y U FATAL NOW?”); // repeat for every catch block // AGAIN AND AGAIN } } Basics: Throwables
  • 97. void oneLineOfCode() { // Take 3 DatagramPacket packet = new DatagramPacket(data, length); } Basics: Throwables
  • 98. void oneLineOfCode() { try { DatagramPacket packet = new DatagramPacket(data, length); } catch (IOException e) { handle(e); } } // We know what to do with this Exception, like recover Basics: Throwables
  • 99. void oneLineOfCode() { try { DatagramPacket packet = new DatagramPacket(data, length); } catch (IOException e) { throw new MyException(e); } } // Translate the Exception to another one more suitable Basics: Throwables
  • 100. void oneLineOfCode() { try { DatagramPacket packet = new DatagramPacket(data, length); } catch (IOException e) { throw Throwables.propagate(e); } } // Propagates the throwable as-is if it is a RuntimeException or // an Error, or wraps it in a RuntimeException and throws it // otherwise. Basics: Throwables
  • 101. // more forms propagateIfInstanceOf(throwable,exceptionClass); Goodies… or gotcha’s! javadoc
  • 102. // more forms propagateIfInstanceOf(throwable,exceptionClass); propagateIfPossible(throwable); // Only if RuntimeException or Error Goodies… or gotcha’s! javadoc
  • 103. // more forms propagateIfInstanceOf(throwable,exceptionClass); propagateIfPossible(throwable); propagateIfPossible(throwable, exceptionClass); Goodies… or gotcha’s! javadoc
  • 104. // more forms propagateIfInstanceOf(throwable,exceptionClass); propagateIfPossible(throwable); propagateIfPossible(throwable, exceptionClass); General practice: Convert checked exceptions to unchecked exceptions Goodies… or gotcha’s! javadoc
  • 105. // more forms propagateIfInstanceOf(throwable,exceptionClass); propagateIfPossible(throwable); propagateIfPossible(throwable, exceptionClass); General practice: Convert checked exceptions to unchecked exceptions Checked exceptions... are a bad idea? Goodies… or gotcha’s! javadoc
  • 106. // more forms propagateIfInstanceOf(throwable,exceptionClass); propagateIfPossible(throwable); propagateIfPossible(throwable, exceptionClass); General practice: Convert checked exceptions to unchecked exceptions Checked exceptions... are a bad idea? Don’t use propagate() to ignore IOExceptions and so on Goodies… or gotcha’s! javadoc
  • 107. Think your fraking Exceptions Bottom line
  • 108. Strings
  • 109. Strings Splitter
  • 110. We have String.split bro! Strings: Splitter
  • 111. We have String.split bro! “,f,,o, o,”.split(“,”) returns: Strings: Splitter
  • 112. We have String.split bro! “,f,,o, o,”.split(“,”) returns: a. [“”, “f”, “”, “o”, “ o”,””] Strings: Splitter
  • 113. We have String.split bro! “,f,,o, o,”.split(“,”) returns: a. [“”, “f”, “”, “o”, “ o”,””] b. [null, “f”, null, “o” ,”o”, null] Strings: Splitter
  • 114. We have String.split bro! “,f,,o, o,”.split(“,”) returns: a. [“”, “f”, “”, “o”, “ o”,””] b. [null, “f”, null, “o” ,”o”, null] c. [“f”, null, “o”, “o”] Strings: Splitter
  • 115. We have String.split bro! “,f,,o, o,”.split(“,”) returns: a. [“”, “f”, “”, “o”, “ o”,””] b. [null, “f”, null, “o” ,”o”, null] c. [“f”, null, “o”, “o”] d. [“f”, ”o”, ”o”] Strings: Splitter
  • 116. We have String.split bro! “,f,,o, o,”.split(“,”) returns: a. [“”, “f”, “”, “o”, “ o”,””] b. [null, “f”, null, “o” ,”o”, null] c. [“f”, null, “o”, “o”] d. [“f”, ”o”, ”o”] e. None of above Strings: Splitter
  • 117. We have String.split bro! “,f,,o, o,”.split(“,”) returns: a. [“”, “f”, “”, “o”, “ o”,””] b. [null, “f”, null, “o” ,”o”, null] c. [“f”, null, “o”, “o”] d. [“f”, ”o”, ”o”] e. None of above Strings: Splitter
  • 118. We have String.split bro! “,f,,o, o,”.split(“,”) returns: a. [“”, “f”, “”, “o”, “ o”,””] b. [null, “f”, null, “o” ,”o”, null] c. [“f”, null, “o”, “o”] d. [“f”, ”o”, ”o”] e. None of above Strings: Splitter
  • 119. We have String.split bro! “,f,,o, o,”.split(“,”) returns: a. [“”, “f”, “”, “o”, “ o”,””] b. [null, “f”, null, “o” ,”o”, null] c. [“f”, null, “o”, “o”] d. [“f”, ”o”, ”o”] e. None of above Returns: [“”, “f”, “”, “o”, “ o”] Strings: Splitter
  • 120. We have String.split bro! “,f,,o, o,”.split(“,”) returns: a. [“”, “f”, “”, “o”, “ o”,””] b. [null, “f”, null, “o” ,”o”, null] c. [“f”, null, “o”, “o”] d. [“f”, ”o”, ”o”] e. None of above Returns: [“”, “f”, “”, “o”, “ o”] Only trailing empty strings are skipped. Strings: Splitter
  • 121. “,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”] Strings: Splitter
  • 122. “,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”] Splitter.on(‘,’) .split(“,f,,o, o,”); Strings: Splitter
  • 123. “,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”] Splitter.on(‘,’) .split(“,f,,o, o,”); // returns [“”,”f”,””,”o”,” o”,””] // Doesn’t discard trailing separators! Strings: Splitter
  • 124. “,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”] Splitter.on(‘,’) .omitEmptyStrings() .split(“,f,,o, o,”); Strings: Splitter
  • 125. “,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”] Splitter.on(‘,’) .omitEmptyStrings() .split(“,f,,o, o,”); // returns [”f”,”o”,” o”] // Empty space is respected Strings: Splitter
  • 126. “,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”] Splitter.on(‘,’) .omitEmptyStrings() .trimResults() .split(“,f,,o, o,”); Strings: Splitter
  • 127. “,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”] Splitter.on(‘,’) .omitEmptyStrings() .trimResults() .split(“,f,,o, o,”); // returns [”f”,”o”,”o”] -- yay! Strings: Splitter
  • 128. “,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”] static final Splitter COMMA = Splitter.on(‘,’) .omitEmptyStrings() .trimResults() .split(“,f,,o, o,”); // Best practice: declare Splitters as static final Strings: Splitter javadoc
  • 129. Strings Joiner
  • 130. [“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”] Strings: Joiner
  • 131. [“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”] Joiner.on(“, “) .join(twentyFour); Strings: Joiner
  • 132. [“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”] Joiner.on(“, “) .join(twentyFour); // throws NullPointerException! Strings: Joiner
  • 133. [“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”] Joiner.on(“, “) .join(twentyFour); // throws NullPointerException! // null-hostile operations everywhere, good thing ;) Strings: Joiner
  • 134. [“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”] Joiner.on(“, “) .skipNulls(); .join(twentyFour); // returns “Jack, Chloe, Tony, Nina, Logan” Strings: Joiner
  • 135. [“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”] Joiner.on(“, “) .useForNull(“Bill”); .join(twentyFour); // returns “Jack, Chloe, Tony, Bill, Nina, Logan” Strings: Joiner javadoc
  • 136. Always think how to avoid null-idioty Bottom line
  • 137. Strings CharMatcher
  • 138. Your StringUtils replacement Strings: CharMatcher
  • 139. Your StringUtils replacement CharMatcher.JAVA_ISO_CONTROL.removeFrom(string); // remove control chars Strings: CharMatcher
  • 140. Your StringUtils replacement CharMatcher.JAVA_ISO_CONTROL.removeFrom(string); CharMatcher.DIGIT.retainFrom(“jordi9”); // returns 9 Strings: CharMatcher
  • 141. Your StringUtils replacement CharMatcher.JAVA_ISO_CONTROL.removeFrom(string); CharMatcher.DIGIT.retainFrom(“jordi9”); CharMatcher.DIGIT.removeFrom(“jordi9”); // returns jordi Strings: CharMatcher
  • 142. Your StringUtils replacement CharMatcher.JAVA_ISO_CONTROL.removeFrom(string); CharMatcher.DIGIT.retainFrom(“jordi9”); CharMatcher.DIGIT.removeFrom(“jordi9”); CharMatcher.DIGIT.or(CharMatcher.JAVA_UPPER_CASE).retainFrom(“Jordi9”); // returns J9 Strings: CharMatcher
  • 143. // More matchers CharMatcher.ANY; CharMatcher.BREAKING_WHITESPACE; CharMatcher.WHITESPACE; CharMatcher.INVISIBLE; CharMatcher.DIGIT; // Unicode CharMatcher.JAVA_DIGIT; // Java’s definition CharMatcher.is(char); CharMatcher.isNot(char); Goodies! javadoc
  • 144. // More matchers CharMatcher.ANY; CharMatcher.BREAKING_WHITESPACE; CharMatcher.WHITESPACE; CharMatcher.INVISIBLE; CharMatcher.DIGIT; // Unicode CharMatcher.JAVA_DIGIT; // Java’s definition CharMatcher.is(char); CharMatcher.isNot(char); // And operations .replaceFrom(charSequence, replacement); .collapseFrom(charSequence, replacement); .trimFrom(charSequence, replacement); Goodies! javadoc
  • 145. Strings Escapers
  • 146. HtmlEscapers.htmlEscaper().escape("Foo > bar"); // returns Foo &gt; bar Escapers
  • 147. HtmlEscapers.htmlEscaper().escape("Foo > bar"); XmlEscapers.xmlAttributeEscaper().escape("foo "bar""); // returns foo &quot;bar&quot; Escapers
  • 148. HtmlEscapers.htmlEscaper().escape("Foo > bar"); XmlEscapers.xmlAttributeEscaper().escape("foo "bar""); XmlEscapers.xmlContentEscaper().escape("foo "bar""); // returns foo “bar” Escapers
  • 149. HtmlEscapers.htmlEscaper().escape("Foo > bar"); XmlEscapers.xmlAttributeEscaper().escape("foo "bar""); XmlEscapers.xmlContentEscaper().escape("foo "bar""); Escaper myEscaper = Escapers.builder() // custom Escaper .addEscape(‘’’, “‘’”) .addEscape(‘&’, “&”) .build(); Escapers javadoc
  • 150. Collections
  • 151. Collections: Functional Idiom
  • 152. Collections: Functional Idiom
  • 153. Collections: Functional Idiom
  • 154. 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); } }; Multiset<Integer> lengths = HashMultiset.create( Iterables.transform(Iterables.filter(strings, allCaps), lengthFunction)); Collections: Functional Idiom
  • 155. 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); } }; Multiset<Integer> lengths = HashMultiset.create( Iterables.transform(Iterables.filter(strings, allCaps), lengthFunction)); Collections: Functional Idiom
  • 156. Multiset<Integer> lengths = HashMultiset.create(); for (String string : strings) { if (CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string)) { lengths.add(string.length()); } } Collections: Functional Idiom
  • 157. Multiset<Integer> lengths = HashMultiset.create(); for (String string : strings) { if (CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string)) { lengths.add(string.length()); } } // Use Imperative, you’ve already survived! Collections: Functional Idiom
  • 158. Multiset<Integer> lengths = HashMultiset.create(); for (String string : strings) { if (CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string)) { lengths.add(string.length()); } } // Use Imperative, you’ve already survived! // Wait for Java 8! Collections: Functional Idiom explain
  • 159. Immutable = Thread-safe Collections: Immutable types
  • 160. Immutable = Thread-safe static final ImmutableSet<String> FOO_NAMES = ImmutableSet.of(“foo”, “bar”, “baz”); Collections: Immutable types
  • 161. Immutable = Thread-safe static final ImmutableSet<String> FOO_NAMES = ImmutableSet.of(“foo”, “bar”, “baz”); // ImmutableList, ImmutableMap... Collections: Immutable types
  • 162. Immutable = Thread-safe static final ImmutableSet<String> FOO_NAMES = ImmutableSet.of(“foo”, “bar”, “baz”); ImmutableList<String> defensiveCopy = ImmutableList.copyOf(someList); Collections: Immutable types
  • 163. Immutable = Thread-safe static final ImmutableSet<String> FOO_NAMES = ImmutableSet.of(“foo”, “bar”, “baz”); ImmutableList<String> defensiveCopy = ImmutableList.copyOf(someList); // Prefer Immutable collections over JDK Collections.unmodifiableXX // for efficiency and consistency Collections: Immutable types explain
  • 164. A bag Collections: Multiset<E>
  • 165. A bag Just like a Set<E> with repeated values Collections: Multiset<E>
  • 166. A bag Just like a Set<E> with repeated values You’ve done this with ArrayList<E> or Map<E, Integer> Collections: Multiset<E>
  • 167. A bag Just like a Set<E> with repeated values You’ve done this with ArrayList<E> or Map<E, Integer> Multiset<Person> ppl = HashMultiset.create(); Collections: Multiset<E>
  • 168. A bag Just like a Set<E> with repeated values You’ve done this with ArrayList<E> or Map<E, Integer> Multiset<Person> ppl = HashMultiset.create(); ppl.add(jack); ppl.add(charles); ppl.add(jack); Collections: Multiset<E>
  • 169. A bag Just like a Set<E> with repeated values You’ve done this with ArrayList<E> or Map<E, Integer> Multiset<Person> ppl = HashMultiset.create(); ppl.add(jack); ppl.add(charles); ppl.add(jack); // prints [jack x 2, charles x 1] Collections: Multiset<E>
  • 170. A bag Just like a Set<E> with repeated values You’ve done this with ArrayList<E> or Map<E, Integer> Multiset<Person> ppl = HashMultiset.create(); ppl.add(jack); ppl.add(charles); ppl.add(jack); ppl.count(jack); Collections: Multiset<E>
  • 171. A bag Just like a Set<E> with repeated values You’ve done this with ArrayList<E> or Map<E, Integer> Multiset<Person> ppl = HashMultiset.create(); ppl.add(jack); ppl.add(charles); ppl.add(jack); ppl.count(jack); // returns 2 Collections: Multiset<E>
  • 172. A bag Just like a Set<E> with repeated values You’ve done this with ArrayList<E> or Map<E, Integer> Multiset<Person> ppl = HashMultiset.create(); ppl.add(jack); ppl.add(charles); ppl.add(jack); ppl.count(jack); // Goodies: elementSet(), entrySet(), setCount(E, int)... Collections: Multiset<E> explain
  • 173. A Map<K, V> with multiple values Collections: Multimap<K, V>
  • 174. A Map<K, V> with multiple values You’ve done this with Map<K, List<V>> Collections: Multimap<K, V>
  • 175. A Map<K, V> with multiple values You’ve done this with Map<K, List<V>> Multimap<Person, Ticket> ticketsByPerson = ArrayListMultimap.create(); Collections: Multimap<K, V>
  • 176. A Map<K, V> with multiple values You’ve done this with Map<K, List<V>> Multimap<Person, Ticket> ticketsByPerson = ArrayListMultimap.create(); ticketsByPerson.put(jack, ctu); ticketsByPerson.put(jack, division); Collections: Multimap<K, V>
  • 177. A Map<K, V> with multiple values You’ve done this with Map<K, List<V>> Multimap<Person, Ticket> ticketsByPerson = ArrayListMultimap.create(); ticketsByPerson.put(jack, ctu); ticketsByPerson.put(jack, division); ticketsByPerson.get(jack); // returns a view of the associated values, a List. // With SetMultimap returns a Set. Collections: Multimap<K, V>
  • 178. A Map<K, V> with multiple values You’ve done this with Map<K, List<V>> Multimap<Person, Ticket> ticketsByPerson = ArrayListMultimap.create(); ticketsByPerson.put(jack, ctu); ticketsByPerson.put(jack, division); ticketsByPerson.get(jack); // asMap(), entries(), values()... Collections: Multimap<K, V> explain
  • 179. // Bi-directional map, keys and values are unique BiMap<K1, K2> Goodies! javadoc
  • 180. // Bi-directional map, keys and values are unique BiMap<K1, K2> // Two-tier map, or a map with two keys Table<R, C, V> Goodies! javadoc
  • 181. // Bi-directional map, keys and values are unique BiMap<K1, K2> // Two-tier map, or a map with two keys Table<R, C, V> // < JDK 7, no diamond support List<String> list = Lists.newArrayList(); // Sets, Maps... Goodies! javadoc
  • 182. // Bi-directional map, keys and values are unique BiMap<K1, K2> // Two-tier map, or a map with two keys Table<R, C, V> // < JDK 7, no diamond support List<String> list = Lists.newArrayList(); // Sets, Maps... // Ranges RangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Range.closed(1, 10)); // {[1, 10]} Goodies! javadoc
  • 183. Tons of good abstractions for you to use Bottom line
  • 184. Hashing
  • 185. Freaking PHP: md5($string) Hashing: JDK
  • 186. Freaking PHP: md5($string) public static String md5Java(String message) { String digest = null; try { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] hash = md.digest(message.getBytes("UTF-8")); String StringBuilder sb = new StringBuilder(2*hash.length); for(byte b : hash){ sb.append(String.format("%02x", b&0xff)); } digest = sb.toString(); } catch (UnsupportedEncodingException ex) { throw Throwables.propagate(ex); } catch (NoSuchAlgorithmException ex) { throw Throwables.propagate(ex); } return digest; } Hashing: JDK
  • 187. Freaking PHP: md5($string) public static String md5Java(String message) { String digest = null; try { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] hash = md.digest(message.getBytes("UTF-8")); String StringBuilder sb = new StringBuilder(2*hash.length); for(byte b : hash){ sb.append(String.format("%02x", b&0xff)); } digest = sb.toString(); } catch (UnsupportedEncodingException ex) { throw Throwables.propagate(ex); } catch (NoSuchAlgorithmException ex) { throw Throwables.propagate(ex); } return digest; } Hashing: JDK
  • 188. HashFunction hf = Hashing.md5(); Hashing: Hasher
  • 189. HashFunction hf = Hashing.md5(); HashCode hc = hf.newHasher() .putLong(id) .putString(name, Charsets.UTF_8) .putObject(person, personFunnel) .hash(); Hashing: Hasher
  • 190. HashFunction hf = Hashing.md5(); HashCode hc = hf.newHasher() .putLong(id) .putString(name, Charsets.UTF_8) .putObject(person, personFunnel) // Defines how to hash .hash(); Hashing: Hasher
  • 191. HashFunction hf = Hashing.md5(); HashCode hc = hf.newHasher() .putLong(id) .putString(name, Charsets.UTF_8) // HINT: remember this! .putObject(person, personFunnel) .hash(); Hashing: Hasher
  • 192. HashFunction hf = Hashing.md5(); HashCode hc = hf.newHasher() .putLong(id) .putString(name, Charsets.UTF_8) .putObject(person, personFunnel) .hash(); hc.asBytes(); // byte[] hc.asInt(); // value in little-endian order hc.toString(); // hexadecimal in lower case Hashing: Hasher
  • 193. // More hash functions! Hashing.md5(); Hashing.murmur3_32(); Hashing.murmur3_128(); Hashing.sha1(); Hashing.sha256(); Hashing.sha512(); Goodies! javadoc
  • 194. // More hash functions! Hashing.md5(); Hashing.murmur3_32(); Hashing.murmur3_128(); Hashing.sha1(); Hashing.sha256(); Hashing.sha512(); // Bloom Filter public boolean mightContain(T); if true, T is probably there if false, T for sure is not there Goodies! javadoc
  • 195. I/O
  • 196. Binary encoding scheme, RFC 4648 I/O: BaseEncoding
  • 197. Binary encoding scheme, RFC 4648 -- Serious stuff I/O: BaseEncoding
  • 198. Binary encoding scheme, RFC 4648 BaseEncoding .base32() .encode("foo".getBytes(Charsets.US_ASCII)); I/O: BaseEncoding
  • 199. Binary encoding scheme, RFC 4648 BaseEncoding .base32() .encode("foo".getBytes(Charsets.US_ASCII)); // returns MZXW6=== I/O: BaseEncoding
  • 200. Binary encoding scheme, RFC 4648 BaseEncoding .base32() .encode("foo".getBytes(Charsets.US_ASCII)); // returns MZXW6=== byte[] decoded = BaseEncoding .base32() .decode("MZXW6==="); I/O: BaseEncoding
  • 201. Binary encoding scheme, RFC 4648 BaseEncoding .base32() .encode("foo".getBytes(Charsets.US_ASCII)); // returns MZXW6=== byte[] decoded = BaseEncoding .base32() .decode("MZXW6==="); // returns the ASCII bytes of String “foo” I/O: BaseEncoding
  • 202. // More schemas BaseEncoding.base16(); BaseEncoding.base32(); BaseEncoding.base64(); BaseEncoding.base64Url(); // Useful all the time Goodies! javadoc
  • 203. KIA
  • 204. KIA Caches EventBus
  • 205. KIA Caches Networking EventBus Concurrency
  • 206. KIA Caches Networking Math EventBus Concurrency More I/O
  • 207. KIA Caches Networking Math Reflection EventBus Concurrency More I/O Collect
  • 208. KIA Caches Networking Math Reflection Primitives EventBus Concurrency More I/O Collect Grumpy
  • 209. Your friends Wiki
  • 210. Your friends Wiki javadoc
  • 211. Remember The “wheel”
  • 212. Remember Read this code
  • 213. Remember No Grumpy Cats were harmed in the making of this presentation
  • 214. Thanks! jordi@donky.org @jordi9
  • 215. Q & A jordi@donky.org @jordi9