Slide 1

Slide 1 text

Google Guava Core libraries for Java & Android @jordi9 11 / oct / 2013

Slide 2

Slide 2 text

...shameless self-promotion bro!

Slide 3

Slide 3 text

Write less code

Slide 4

Slide 4 text

Write cleaner code

Slide 5

Slide 5 text

Write more readable code

Slide 6

Slide 6 text

The “wheel”

Slide 7

Slide 7 text

com.google.guava:guava:15.0

Slide 8

Slide 8 text

Basics

Slide 9

Slide 9 text

Basics Avoid using null

Slide 10

Slide 10 text

Basics: Avoid using null “Null sucks” Doug Lea - JCP, OpenJDK

Slide 11

Slide 11 text

Basics: Avoid using null “I call it my billion-dollar mistake” Sir C.A.R. Hoare - Inventor of null

Slide 12

Slide 12 text

Basics: Avoid using null @Google 95% of collections weren’t supposed to have null values.

Slide 13

Slide 13 text

map = {Foo: bar, null, Baz: qux} Basics: Avoid using null

Slide 14

Slide 14 text

map = {Foo: bar, null, Baz: qux} map.get(“Foo”); Basics: Avoid using null

Slide 15

Slide 15 text

map = {Foo: bar, null, Baz: qux} map.get(“Foo”); // returns Foo Basics: Avoid using null

Slide 16

Slide 16 text

map = {Foo: bar, null, Baz: qux} map.get(“Foo”); map.get(“quux”); Basics: Avoid using null

Slide 17

Slide 17 text

map = {Foo: bar, null, Baz: qux} map.get(“Foo”); map.get(“quux”); // returns null Basics: Avoid using null

Slide 18

Slide 18 text

map = {Foo: bar, null, Baz: qux} map.get(“Foo”); map.get(“quux”); map.get(null); Basics: Avoid using null

Slide 19

Slide 19 text

map = {Foo: bar, null, Baz: qux} map.get(“Foo”); map.get(“quux”); map.get(null); // returns null Basics: Avoid using null

Slide 20

Slide 20 text

map = {Foo: bar, null, Baz: qux} map.get(“Foo”); map.get(“quux”); // returns null map.get(null); // returns null Basics: Avoid using null

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

Optional Basics: Avoid using null

Slide 23

Slide 23 text

Optional Optional foo = Optional.of(“foo”) Basics: Avoid using null

Slide 24

Slide 24 text

Optional Optional foo = Optional.of(“foo”) foo.isPresent(); // returns true Basics: Avoid using null

Slide 25

Slide 25 text

Optional Optional foo = Optional.of(“foo”) foo.isPresent(); foo.get(); // returns “foo” Basics: Avoid using null

Slide 26

Slide 26 text

Optional.of(foo); // not nullable Goodies! RTFM, I mean javadoc

Slide 27

Slide 27 text

Optional.of(foo); Optional.absent(); Goodies! javadoc

Slide 28

Slide 28 text

Optional.of(foo); Optional.absent(); Optional.fromNullable(legacyCode); Goodies! javadoc

Slide 29

Slide 29 text

Optional.of(foo); Optional.absent(); Optional.fromNullable(legacyCode); foo.get(); // may return “foo” Goodies! javadoc

Slide 30

Slide 30 text

Optional.of(foo); Optional.absent(); Optional.fromNullable(legacyCode); foo.get(); foo.or(“bar”); // return “bar” if foo is absent Goodies! javadoc

Slide 31

Slide 31 text

Optional.of(foo); Optional.absent(); Optional.fromNullable(legacyCode); foo.get(); foo.or(“bar”); foo.orNull(); // Deal with code that need nulls, duh Goodies! javadoc

Slide 32

Slide 32 text

Optional is IDIOT-PROOF-NESS Bottom line

Slide 33

Slide 33 text

Basics Preconditions

Slide 34

Slide 34 text

if (seats <= 0) { throw new IllegalArgumentException(“Seats must be positive, but was ” + seats); } Basics: Preconditions

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

// 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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

void execute(Job job) { // serious business } Basics: Preconditions

Slide 40

Slide 40 text

void execute(Job job) { checkNotNull(job, “Job can’t be null”); // serious business } // checkNotNull() throws NullPointerException Basics: Preconditions

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

this.foo = checkNotNull(foo); // inline assig Goodies! javadoc

Slide 44

Slide 44 text

this.foo = checkNotNull(foo); // list, string or array checks checkElementIndex(index, size); checkPositionIndex(index, size); checkPositionIndexes(start, end, size); Goodies! javadoc

Slide 45

Slide 45 text

Preconditions will save your ass Bottom line

Slide 46

Slide 46 text

Basics Objects

Slide 47

Slide 47 text

@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

Slide 48

Slide 48 text

@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

Slide 49

Slide 49 text

@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

Slide 50

Slide 50 text

@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

Slide 51

Slide 51 text

@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

Slide 52

Slide 52 text

@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

Slide 53

Slide 53 text

@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

Slide 54

Slide 54 text

@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

Slide 55

Slide 55 text

@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

Slide 56

Slide 56 text

@Override public int hashCode() { return Objects.hashCode(firstName, lastName); } Basics: Objects

Slide 57

Slide 57 text

@Override public int hashCode() { // sensible, order-sensitive hash return Objects.hashCode(firstName, lastName); } Basics: Objects

Slide 58

Slide 58 text

@Override public int hashCode() { return Objects.hashCode(firstName, lastName); } // JDK 1.7 introduced equivalent Objects.hash() method. Basics: Objects

Slide 59

Slide 59 text

@Override public String toString() { } Basics: Objects

Slide 60

Slide 60 text

@Override public String toString() { } Basics: Objects

Slide 61

Slide 61 text

@Override public String toString() { return Objects.toStringHelper(this) .add("firstName", firstName) .add("lastName", lastName) .add("catName", catName) .toString(); } Basics: Objects

Slide 62

Slide 62 text

@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

Slide 63

Slide 63 text

@Override public String toString() { return Objects.toStringHelper(this) .add("firstName", firstName) .add("lastName", lastName) .add("catName", catName) .omitNullValues() .toString(); } Basics: Objects

Slide 64

Slide 64 text

@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

Slide 65

Slide 65 text

IntelliJ IDEA support for ToStringHelper() Generate toString() > Template Objects.ToStringHelper (Guava) Goodies! javadoc

Slide 66

Slide 66 text

So common stuff should ring a bell Bottom line

Slide 67

Slide 67 text

Basics Ordering

Slide 68

Slide 68 text

Comparator byDescAgeName = new Comparator() { 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

Slide 69

Slide 69 text

Comparator byDescAgeName = new Comparator() { 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

Slide 70

Slide 70 text

Comparator byDescAgeName = new Comparator() { public int compare(Person p1, Person p2) { return ComparisonChain.start() .compare(p2.getAge(), p1.getAge()) .compare(p1, p2) .result(); } }; Basics: Ordering

Slide 71

Slide 71 text

Comparator byDescAgeName = new Comparator() { 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

Slide 72

Slide 72 text

Comparator byDescAgeName = Ordering.natural() .reverse() .onResultOf(new Function() { public Integer apply(Person person) { return person.getAge(); }}) .compound(Ordering.natural()); } }; Basics: Ordering

Slide 73

Slide 73 text

Comparator byDescAgeName = Ordering.natural() .reverse() .onResultOf(new Function() { public Integer apply(Person person) { return person.getAge(); }}) .compound(Ordering.natural()); } }; // Read backwards Basics: Ordering

Slide 74

Slide 74 text

Ordering is an “enriched” Comparator. It’s fuuuuuuuun! Goodies! javadoc

Slide 75

Slide 75 text

Ordering is an “enriched” Comparator. It’s fluent. Goodies! javadoc

Slide 76

Slide 76 text

Ordering is an “enriched” Comparator. It’s fluent. // Subclass Ordering and implement compare(T,T) Ordering ORDER_BY_CLASS_NAME = (left, right) -> { return Ordering.usingToString() .compare(left.getClass(), right.getClass()); }; Goodies! javadoc

Slide 77

Slide 77 text

Ordering is an “enriched” Comparator. It’s fluent. // Subclass Ordering and implement compare(T,T) Ordering ORDER_BY_CLASS_NAME = (left, right) -> { return Ordering.usingToString() .compare(left.getClass(), right.getClass()); }; // Or create one Ordering.from(comparator); Ordering.natural(); Goodies! javadoc

Slide 78

Slide 78 text

Ordering is an “enriched” Comparator. It’s fluent. // Subclass Ordering and implement compare(T,T) Ordering 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

Slide 79

Slide 79 text

There’s a better way than Comparator Bottom line

Slide 80

Slide 80 text

Basics Throwables

Slide 81

Slide 81 text

void oneLineOfCode() { DatagramPacket packet = new DatagramPacket(data, length); } Basics: Throwables

Slide 82

Slide 82 text

void oneLineOfCode() { DatagramPacket packet = new DatagramPacket(data, length); } // Compile error, throws IOException Basics: Throwables

Slide 83

Slide 83 text

void oneLineOfCode() throws IOException { DatagramPacket packet = new DatagramPacket(data, length); } void someLayer() { oneLineOfCode(); } Basics: Throwables

Slide 84

Slide 84 text

void oneLineOfCode() throws IOException { DatagramPacket packet = new DatagramPacket(data, length); } void someLayer() { oneLineOfCode(); } // Compile error, throws IOException Basics: Throwables

Slide 85

Slide 85 text

void oneLineOfCode() throws IOException { DatagramPacket packet = new DatagramPacket(data, length); } void someLayer() throws IOException { oneLineOfCode(); } void someCoolAbstraction() { someLayer(); } Basics: Throwables

Slide 86

Slide 86 text

void oneLineOfCode() throws IOException { DatagramPacket packet = new DatagramPacket(data, length); } void someLayer() throws IOException { oneLineOfCode(); } void someCoolAbstraction() { someLayer(); } // Compile error, AGAIN Basics: Throwables

Slide 87

Slide 87 text

void oneLineOfCode() throws IOException { DatagramPacket packet = new DatagramPacket(data, length); } void someLayer() throws IOException { oneLineOfCode(); } void someCoolAbstraction() throws IOException { someLayer(); } Basics: Throwables

Slide 88

Slide 88 text

void oneLineOfCode() throws IOException { DatagramPacket packet = new DatagramPacket(data, address); } void someLayer() throws IOException { oneLineOfCode(); } void someCoolAbstraction() throws IOException { someLayer(); } // c’mon... Basics: Throwables

Slide 89

Slide 89 text

void oneLineOfCode() { // Take 2 DatagramPacket packet = new DatagramPacket(data, length); } Basics: Throwables

Slide 90

Slide 90 text

void oneLineOfCode() { try { DatagramPacket packet = new DatagramPacket(data, length); } catch (IOException e) { } } Basics: Throwables

Slide 91

Slide 91 text

void oneLineOfCode() { try { DatagramPacket packet = new DatagramPacket(data, length); } catch (IOException e) { // Really? Swallow? Sure? At least explain why! } } Basics: Throwables

Slide 92

Slide 92 text

void oneLineOfCode() { try { DatagramPacket packet = new DatagramPacket(data, length); } catch (IOException e) { SendMeAnEmail.error(); } } Basics: Throwables

Slide 93

Slide 93 text

void oneLineOfCode() { try { DatagramPacket packet = new DatagramPacket(data, length); } catch (IOException e) { SendMeAnEmail.error(); Oh.theLogger().fatal(“WHY Y U FATAL NOW?”); } } Basics: Throwables

Slide 94

Slide 94 text

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

Slide 95

Slide 95 text

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

Slide 96

Slide 96 text

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

Slide 97

Slide 97 text

void oneLineOfCode() { // Take 3 DatagramPacket packet = new DatagramPacket(data, length); } Basics: Throwables

Slide 98

Slide 98 text

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

Slide 99

Slide 99 text

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

Slide 100

Slide 100 text

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

Slide 101

Slide 101 text

// more forms propagateIfInstanceOf(throwable,exceptionClass); Goodies… or gotcha’s! javadoc

Slide 102

Slide 102 text

// more forms propagateIfInstanceOf(throwable,exceptionClass); propagateIfPossible(throwable); // Only if RuntimeException or Error Goodies… or gotcha’s! javadoc

Slide 103

Slide 103 text

// more forms propagateIfInstanceOf(throwable,exceptionClass); propagateIfPossible(throwable); propagateIfPossible(throwable, exceptionClass); Goodies… or gotcha’s! javadoc

Slide 104

Slide 104 text

// more forms propagateIfInstanceOf(throwable,exceptionClass); propagateIfPossible(throwable); propagateIfPossible(throwable, exceptionClass); General practice: Convert checked exceptions to unchecked exceptions Goodies… or gotcha’s! javadoc

Slide 105

Slide 105 text

// 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

Slide 106

Slide 106 text

// 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

Slide 107

Slide 107 text

Think your fraking Exceptions Bottom line

Slide 108

Slide 108 text

Strings

Slide 109

Slide 109 text

Strings Splitter

Slide 110

Slide 110 text

We have String.split bro! Strings: Splitter

Slide 111

Slide 111 text

We have String.split bro! “,f,,o, o,”.split(“,”) returns: Strings: Splitter

Slide 112

Slide 112 text

We have String.split bro! “,f,,o, o,”.split(“,”) returns: a. [“”, “f”, “”, “o”, “ o”,””] Strings: Splitter

Slide 113

Slide 113 text

We have String.split bro! “,f,,o, o,”.split(“,”) returns: a. [“”, “f”, “”, “o”, “ o”,””] b. [null, “f”, null, “o” ,”o”, null] Strings: Splitter

Slide 114

Slide 114 text

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

Slide 115

Slide 115 text

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

Slide 116

Slide 116 text

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

Slide 117

Slide 117 text

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

Slide 118

Slide 118 text

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

Slide 119

Slide 119 text

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

Slide 120

Slide 120 text

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

Slide 121

Slide 121 text

“,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”] Strings: Splitter

Slide 122

Slide 122 text

“,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”] Splitter.on(‘,’) .split(“,f,,o, o,”); Strings: Splitter

Slide 123

Slide 123 text

“,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

Slide 124

Slide 124 text

“,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”] Splitter.on(‘,’) .omitEmptyStrings() .split(“,f,,o, o,”); Strings: Splitter

Slide 125

Slide 125 text

“,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

Slide 126

Slide 126 text

“,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”] Splitter.on(‘,’) .omitEmptyStrings() .trimResults() .split(“,f,,o, o,”); Strings: Splitter

Slide 127

Slide 127 text

“,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

Slide 128

Slide 128 text

“,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

Slide 129

Slide 129 text

Strings Joiner

Slide 130

Slide 130 text

[“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”] Strings: Joiner

Slide 131

Slide 131 text

[“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”] Joiner.on(“, “) .join(twentyFour); Strings: Joiner

Slide 132

Slide 132 text

[“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”] Joiner.on(“, “) .join(twentyFour); // throws NullPointerException! Strings: Joiner

Slide 133

Slide 133 text

[“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”] Joiner.on(“, “) .join(twentyFour); // throws NullPointerException! // null-hostile operations everywhere, good thing ;) Strings: Joiner

Slide 134

Slide 134 text

[“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”] Joiner.on(“, “) .skipNulls(); .join(twentyFour); // returns “Jack, Chloe, Tony, Nina, Logan” Strings: Joiner

Slide 135

Slide 135 text

[“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”] Joiner.on(“, “) .useForNull(“Bill”); .join(twentyFour); // returns “Jack, Chloe, Tony, Bill, Nina, Logan” Strings: Joiner javadoc

Slide 136

Slide 136 text

Always think how to avoid null-idioty Bottom line

Slide 137

Slide 137 text

Strings CharMatcher

Slide 138

Slide 138 text

Your StringUtils replacement Strings: CharMatcher

Slide 139

Slide 139 text

Your StringUtils replacement CharMatcher.JAVA_ISO_CONTROL.removeFrom(string); // remove control chars Strings: CharMatcher

Slide 140

Slide 140 text

Your StringUtils replacement CharMatcher.JAVA_ISO_CONTROL.removeFrom(string); CharMatcher.DIGIT.retainFrom(“jordi9”); // returns 9 Strings: CharMatcher

Slide 141

Slide 141 text

Your StringUtils replacement CharMatcher.JAVA_ISO_CONTROL.removeFrom(string); CharMatcher.DIGIT.retainFrom(“jordi9”); CharMatcher.DIGIT.removeFrom(“jordi9”); // returns jordi Strings: CharMatcher

Slide 142

Slide 142 text

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

Slide 143

Slide 143 text

// 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

Slide 144

Slide 144 text

// 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

Slide 145

Slide 145 text

Strings Escapers

Slide 146

Slide 146 text

HtmlEscapers.htmlEscaper().escape("Foo > bar"); // returns Foo > bar Escapers

Slide 147

Slide 147 text

HtmlEscapers.htmlEscaper().escape("Foo > bar"); XmlEscapers.xmlAttributeEscaper().escape("foo \"bar\""); // returns foo "bar" Escapers

Slide 148

Slide 148 text

HtmlEscapers.htmlEscaper().escape("Foo > bar"); XmlEscapers.xmlAttributeEscaper().escape("foo \"bar\""); XmlEscapers.xmlContentEscaper().escape("foo \"bar\""); // returns foo “bar” Escapers

Slide 149

Slide 149 text

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

Slide 150

Slide 150 text

Collections

Slide 151

Slide 151 text

Collections: Functional Idiom

Slide 152

Slide 152 text

Collections: Functional Idiom

Slide 153

Slide 153 text

Collections: Functional Idiom

Slide 154

Slide 154 text

Function lengthFunction = new Function() { public Integer apply(String string) { return string.length(); } }; Predicate allCaps = new Predicate() { public boolean apply(String string) { return CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string); } }; Multiset lengths = HashMultiset.create( Iterables.transform(Iterables.filter(strings, allCaps), lengthFunction)); Collections: Functional Idiom

Slide 155

Slide 155 text

Function lengthFunction = new Function() { public Integer apply(String string) { return string.length(); } }; Predicate allCaps = new Predicate() { public boolean apply(String string) { return CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string); } }; Multiset lengths = HashMultiset.create( Iterables.transform(Iterables.filter(strings, allCaps), lengthFunction)); Collections: Functional Idiom

Slide 156

Slide 156 text

Multiset lengths = HashMultiset.create(); for (String string : strings) { if (CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string)) { lengths.add(string.length()); } } Collections: Functional Idiom

Slide 157

Slide 157 text

Multiset 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

Slide 158

Slide 158 text

Multiset 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

Slide 159

Slide 159 text

Immutable = Thread-safe Collections: Immutable types

Slide 160

Slide 160 text

Immutable = Thread-safe static final ImmutableSet FOO_NAMES = ImmutableSet.of(“foo”, “bar”, “baz”); Collections: Immutable types

Slide 161

Slide 161 text

Immutable = Thread-safe static final ImmutableSet FOO_NAMES = ImmutableSet.of(“foo”, “bar”, “baz”); // ImmutableList, ImmutableMap... Collections: Immutable types

Slide 162

Slide 162 text

Immutable = Thread-safe static final ImmutableSet FOO_NAMES = ImmutableSet.of(“foo”, “bar”, “baz”); ImmutableList defensiveCopy = ImmutableList.copyOf(someList); Collections: Immutable types

Slide 163

Slide 163 text

Immutable = Thread-safe static final ImmutableSet FOO_NAMES = ImmutableSet.of(“foo”, “bar”, “baz”); ImmutableList defensiveCopy = ImmutableList.copyOf(someList); // Prefer Immutable collections over JDK Collections.unmodifiableXX // for efficiency and consistency Collections: Immutable types explain

Slide 164

Slide 164 text

A bag Collections: Multiset

Slide 165

Slide 165 text

A bag Just like a Set with repeated values Collections: Multiset

Slide 166

Slide 166 text

A bag Just like a Set with repeated values You’ve done this with ArrayList or Map Collections: Multiset

Slide 167

Slide 167 text

A bag Just like a Set with repeated values You’ve done this with ArrayList or Map Multiset ppl = HashMultiset.create(); Collections: Multiset

Slide 168

Slide 168 text

A bag Just like a Set with repeated values You’ve done this with ArrayList or Map Multiset ppl = HashMultiset.create(); ppl.add(jack); ppl.add(charles); ppl.add(jack); Collections: Multiset

Slide 169

Slide 169 text

A bag Just like a Set with repeated values You’ve done this with ArrayList or Map Multiset ppl = HashMultiset.create(); ppl.add(jack); ppl.add(charles); ppl.add(jack); // prints [jack x 2, charles x 1] Collections: Multiset

Slide 170

Slide 170 text

A bag Just like a Set with repeated values You’ve done this with ArrayList or Map Multiset ppl = HashMultiset.create(); ppl.add(jack); ppl.add(charles); ppl.add(jack); ppl.count(jack); Collections: Multiset

Slide 171

Slide 171 text

A bag Just like a Set with repeated values You’ve done this with ArrayList or Map Multiset ppl = HashMultiset.create(); ppl.add(jack); ppl.add(charles); ppl.add(jack); ppl.count(jack); // returns 2 Collections: Multiset

Slide 172

Slide 172 text

A bag Just like a Set with repeated values You’ve done this with ArrayList or Map Multiset ppl = HashMultiset.create(); ppl.add(jack); ppl.add(charles); ppl.add(jack); ppl.count(jack); // Goodies: elementSet(), entrySet(), setCount(E, int)... Collections: Multiset explain

Slide 173

Slide 173 text

A Map with multiple values Collections: Multimap

Slide 174

Slide 174 text

A Map with multiple values You’ve done this with Map> Collections: Multimap

Slide 175

Slide 175 text

A Map with multiple values You’ve done this with Map> Multimap ticketsByPerson = ArrayListMultimap.create(); Collections: Multimap

Slide 176

Slide 176 text

A Map with multiple values You’ve done this with Map> Multimap ticketsByPerson = ArrayListMultimap.create(); ticketsByPerson.put(jack, ctu); ticketsByPerson.put(jack, division); Collections: Multimap

Slide 177

Slide 177 text

A Map with multiple values You’ve done this with Map> Multimap 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

Slide 178

Slide 178 text

A Map with multiple values You’ve done this with Map> Multimap ticketsByPerson = ArrayListMultimap.create(); ticketsByPerson.put(jack, ctu); ticketsByPerson.put(jack, division); ticketsByPerson.get(jack); // asMap(), entries(), values()... Collections: Multimap explain

Slide 179

Slide 179 text

// Bi-directional map, keys and values are unique BiMap Goodies! javadoc

Slide 180

Slide 180 text

// Bi-directional map, keys and values are unique BiMap // Two-tier map, or a map with two keys Table Goodies! javadoc

Slide 181

Slide 181 text

// Bi-directional map, keys and values are unique BiMap // Two-tier map, or a map with two keys Table // < JDK 7, no diamond support List list = Lists.newArrayList(); // Sets, Maps... Goodies! javadoc

Slide 182

Slide 182 text

// Bi-directional map, keys and values are unique BiMap // Two-tier map, or a map with two keys Table // < JDK 7, no diamond support List list = Lists.newArrayList(); // Sets, Maps... // Ranges RangeSet rangeSet = TreeRangeSet.create(); rangeSet.add(Range.closed(1, 10)); // {[1, 10]} Goodies! javadoc

Slide 183

Slide 183 text

Tons of good abstractions for you to use Bottom line

Slide 184

Slide 184 text

Hashing

Slide 185

Slide 185 text

Freaking PHP: md5($string) Hashing: JDK

Slide 186

Slide 186 text

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

Slide 187

Slide 187 text

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

Slide 188

Slide 188 text

HashFunction hf = Hashing.md5(); Hashing: Hasher

Slide 189

Slide 189 text

HashFunction hf = Hashing.md5(); HashCode hc = hf.newHasher() .putLong(id) .putString(name, Charsets.UTF_8) .putObject(person, personFunnel) .hash(); Hashing: Hasher

Slide 190

Slide 190 text

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

Slide 191

Slide 191 text

HashFunction hf = Hashing.md5(); HashCode hc = hf.newHasher() .putLong(id) .putString(name, Charsets.UTF_8) // HINT: remember this! .putObject(person, personFunnel) .hash(); Hashing: Hasher

Slide 192

Slide 192 text

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

Slide 193

Slide 193 text

// More hash functions! Hashing.md5(); Hashing.murmur3_32(); Hashing.murmur3_128(); Hashing.sha1(); Hashing.sha256(); Hashing.sha512(); Goodies! javadoc

Slide 194

Slide 194 text

// 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

Slide 195

Slide 195 text

I/O

Slide 196

Slide 196 text

Binary encoding scheme, RFC 4648 I/O: BaseEncoding

Slide 197

Slide 197 text

Binary encoding scheme, RFC 4648 -- Serious stuff I/O: BaseEncoding

Slide 198

Slide 198 text

Binary encoding scheme, RFC 4648 BaseEncoding .base32() .encode("foo".getBytes(Charsets.US_ASCII)); I/O: BaseEncoding

Slide 199

Slide 199 text

Binary encoding scheme, RFC 4648 BaseEncoding .base32() .encode("foo".getBytes(Charsets.US_ASCII)); // returns MZXW6=== I/O: BaseEncoding

Slide 200

Slide 200 text

Binary encoding scheme, RFC 4648 BaseEncoding .base32() .encode("foo".getBytes(Charsets.US_ASCII)); // returns MZXW6=== byte[] decoded = BaseEncoding .base32() .decode("MZXW6==="); I/O: BaseEncoding

Slide 201

Slide 201 text

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

Slide 202

Slide 202 text

// More schemas BaseEncoding.base16(); BaseEncoding.base32(); BaseEncoding.base64(); BaseEncoding.base64Url(); // Useful all the time Goodies! javadoc

Slide 203

Slide 203 text

KIA

Slide 204

Slide 204 text

KIA Caches EventBus

Slide 205

Slide 205 text

KIA Caches Networking EventBus Concurrency

Slide 206

Slide 206 text

KIA Caches Networking Math EventBus Concurrency More I/O

Slide 207

Slide 207 text

KIA Caches Networking Math Reflection EventBus Concurrency More I/O Collect

Slide 208

Slide 208 text

KIA Caches Networking Math Reflection Primitives EventBus Concurrency More I/O Collect Grumpy

Slide 209

Slide 209 text

Your friends Wiki

Slide 210

Slide 210 text

Your friends Wiki javadoc

Slide 211

Slide 211 text

Remember The “wheel”

Slide 212

Slide 212 text

Remember Read this code

Slide 213

Slide 213 text

Remember No Grumpy Cats were harmed in the making of this presentation

Slide 214

Slide 214 text

No content

Slide 215

Slide 215 text

Thanks! [email protected] @jordi9

Slide 216

Slide 216 text

Q & A [email protected] @jordi9