SlideShare una empresa de Scribd logo
1 de 216
Descargar para leer sin conexión
Google Guava
Core libraries for Java & Android
@jordi9
11 / oct / 2013
...shameless self-promotion bro!
Write less code
Write cleaner code
Write more readable code
The “wheel”
com.google.guava:guava:15.0
Basics
Basics
Avoid using null
Basics: Avoid using null
“Null sucks”
Doug Lea - JCP, OpenJDK
Basics: Avoid using null
“I call it my billion-dollar mistake”
Sir C.A.R. Hoare - Inventor of null
Basics: Avoid using null
@Google
95% of collections weren’t supposed
to have null values.
map = {Foo: bar, null, Baz: qux}
Basics: Avoid using null
map = {Foo: bar, null, Baz: qux}
map.get(“Foo”);
Basics: Avoid using null
map = {Foo: bar, null, Baz: qux}
map.get(“Foo”); // returns Foo
Basics: Avoid using null
map = {Foo: bar, null, Baz: qux}
map.get(“Foo”);
map.get(“quux”);
Basics: Avoid using null
map = {Foo: bar, null, Baz: qux}
map.get(“Foo”);
map.get(“quux”); // returns null
Basics: Avoid using null
map = {Foo: bar, null, Baz: qux}
map.get(“Foo”);
map.get(“quux”);
map.get(null);
Basics: Avoid using null
map = {Foo: bar, null, Baz: qux}
map.get(“Foo”);
map.get(“quux”);
map.get(null); // returns null
Basics: Avoid using null
map = {Foo: bar, null, Baz: qux}
map.get(“Foo”);
map.get(“quux”); // returns null
map.get(null); // returns null
Basics: Avoid using null
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
Optional<T>
Basics: Avoid using null
Optional<T>
Optional<String> foo = Optional.of(“foo”)
Basics: Avoid using null
Optional<T>
Optional<String> foo = Optional.of(“foo”)
foo.isPresent(); // returns true
Basics: Avoid using null
Optional<T>
Optional<String> foo = Optional.of(“foo”)
foo.isPresent();
foo.get(); // returns “foo”
Basics: Avoid using null
Optional.of(foo); // not nullable
Goodies!
RTFM, I mean javadoc
Optional.of(foo);
Optional.absent();
Goodies!
javadoc
Optional.of(foo);
Optional.absent();
Optional.fromNullable(legacyCode);
Goodies!
javadoc
Optional.of(foo);
Optional.absent();
Optional.fromNullable(legacyCode);
foo.get(); // may return “foo”
Goodies!
javadoc
Optional.of(foo);
Optional.absent();
Optional.fromNullable(legacyCode);
foo.get();
foo.or(“bar”); // return “bar” if foo is absent
Goodies!
javadoc
Optional.of(foo);
Optional.absent();
Optional.fromNullable(legacyCode);
foo.get();
foo.or(“bar”);
foo.orNull(); // Deal with code that need nulls, duh
Goodies!
javadoc
Optional<T> is IDIOT-PROOF-NESS
Bottom line
Basics
Preconditions
if (seats <= 0) {
throw new IllegalArgumentException(“Seats must be
positive, but was ” + seats);
}
Basics: Preconditions
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
// 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
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
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
void execute(Job job) {
// serious business
}
Basics: Preconditions
void execute(Job job) {
checkNotNull(job, “Job can’t be null”);
// serious business
}
// checkNotNull() throws NullPointerException
Basics: Preconditions
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
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
this.foo = checkNotNull(foo); // inline assig
Goodies!
javadoc
this.foo = checkNotNull(foo);
// list, string or array checks
checkElementIndex(index, size);
checkPositionIndex(index, size);
checkPositionIndexes(start, end, size);
Goodies!
javadoc
Preconditions will save your ass
Bottom line
Basics
Objects
@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
@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
@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
@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
@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
@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
@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
@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
@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
@Override
public int hashCode() {
return Objects.hashCode(firstName, lastName);
}
Basics: Objects
@Override
public int hashCode() {
// sensible, order-sensitive hash
return Objects.hashCode(firstName, lastName);
}
Basics: Objects
@Override
public int hashCode() {
return Objects.hashCode(firstName, lastName);
}
// JDK 1.7 introduced equivalent Objects.hash() method.
Basics: Objects
@Override
public String toString() {
}
Basics: Objects
@Override
public String toString() {
}
Basics: Objects
@Override
public String toString() {
return Objects.toStringHelper(this)
.add("firstName", firstName)
.add("lastName", lastName)
.add("catName", catName)
.toString();
}
Basics: Objects
@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
@Override
public String toString() {
return Objects.toStringHelper(this)
.add("firstName", firstName)
.add("lastName", lastName)
.add("catName", catName)
.omitNullValues()
.toString();
}
Basics: Objects
@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
IntelliJ IDEA support for ToStringHelper()
Generate toString() > Template Objects.ToStringHelper (Guava)
Goodies!
javadoc
So common stuff should ring a bell
Bottom line
Basics
Ordering
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
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
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
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
Comparator<Person> byDescAgeName =
Ordering.natural()
.reverse()
.onResultOf(new Function<Person, Integer>() {
public Integer apply(Person person) {
return person.getAge();
}})
.compound(Ordering.natural());
}
};
Basics: Ordering
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
Ordering is an “enriched” Comparator. It’s fuuuuuuuun!
Goodies!
javadoc
Ordering is an “enriched” Comparator. It’s fluent.
Goodies!
javadoc
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
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
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
There’s a better way than Comparator
Bottom line
Basics
Throwables
void oneLineOfCode() {
DatagramPacket packet = new DatagramPacket(data, length);
}
Basics: Throwables
void oneLineOfCode() {
DatagramPacket packet = new DatagramPacket(data, length);
}
// Compile error, throws IOException
Basics: Throwables
void oneLineOfCode() throws IOException {
DatagramPacket packet = new DatagramPacket(data, length);
}
void someLayer() {
oneLineOfCode();
}
Basics: Throwables
void oneLineOfCode() throws IOException {
DatagramPacket packet = new DatagramPacket(data, length);
}
void someLayer() {
oneLineOfCode();
}
// Compile error, throws IOException
Basics: Throwables
void oneLineOfCode() throws IOException {
DatagramPacket packet = new DatagramPacket(data, length);
}
void someLayer() throws IOException {
oneLineOfCode();
}
void someCoolAbstraction() {
someLayer();
}
Basics: Throwables
void oneLineOfCode() throws IOException {
DatagramPacket packet = new DatagramPacket(data, length);
}
void someLayer() throws IOException {
oneLineOfCode();
}
void someCoolAbstraction() {
someLayer();
}
// Compile error, AGAIN
Basics: Throwables
void oneLineOfCode() throws IOException {
DatagramPacket packet = new DatagramPacket(data, length);
}
void someLayer() throws IOException {
oneLineOfCode();
}
void someCoolAbstraction() throws IOException {
someLayer();
}
Basics: Throwables
void oneLineOfCode() throws IOException {
DatagramPacket packet = new DatagramPacket(data, address);
}
void someLayer() throws IOException {
oneLineOfCode();
}
void someCoolAbstraction() throws IOException {
someLayer();
}
// c’mon...
Basics: Throwables
void oneLineOfCode() {
// Take 2
DatagramPacket packet = new DatagramPacket(data, length);
}
Basics: Throwables
void oneLineOfCode() {
try {
DatagramPacket packet = new DatagramPacket(data, length);
} catch (IOException e) {
}
}
Basics: Throwables
void oneLineOfCode() {
try {
DatagramPacket packet = new DatagramPacket(data, length);
} catch (IOException e) {
// Really? Swallow? Sure? At least explain why!
}
}
Basics: Throwables
void oneLineOfCode() {
try {
DatagramPacket packet = new DatagramPacket(data, length);
} catch (IOException e) {
SendMeAnEmail.error();
}
}
Basics: Throwables
void oneLineOfCode() {
try {
DatagramPacket packet = new DatagramPacket(data, length);
} catch (IOException e) {
SendMeAnEmail.error();
Oh.theLogger().fatal(“WHY Y U FATAL NOW?”);
}
}
Basics: Throwables
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
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
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
void oneLineOfCode() {
// Take 3
DatagramPacket packet = new DatagramPacket(data, length);
}
Basics: Throwables
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
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
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
// more forms
propagateIfInstanceOf(throwable,exceptionClass);
Goodies… or gotcha’s!
javadoc
// more forms
propagateIfInstanceOf(throwable,exceptionClass);
propagateIfPossible(throwable); // Only if RuntimeException or Error
Goodies… or gotcha’s!
javadoc
// more forms
propagateIfInstanceOf(throwable,exceptionClass);
propagateIfPossible(throwable);
propagateIfPossible(throwable, exceptionClass);
Goodies… or gotcha’s!
javadoc
// more forms
propagateIfInstanceOf(throwable,exceptionClass);
propagateIfPossible(throwable);
propagateIfPossible(throwable, exceptionClass);
General practice:
Convert checked exceptions to unchecked exceptions
Goodies… or gotcha’s!
javadoc
// 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
// 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
Think your fraking Exceptions
Bottom line
Strings
Strings
Splitter
We have String.split bro!
Strings: Splitter
We have String.split bro!
“,f,,o, o,”.split(“,”) returns:
Strings: Splitter
We have String.split bro!
“,f,,o, o,”.split(“,”) returns:
a. [“”, “f”, “”, “o”, “ o”,””]
Strings: Splitter
We have String.split bro!
“,f,,o, o,”.split(“,”) returns:
a. [“”, “f”, “”, “o”, “ o”,””]
b. [null, “f”, null, “o” ,”o”, null]
Strings: Splitter
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
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
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
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
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
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
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
“,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”]
Strings: Splitter
“,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”]
Splitter.on(‘,’)
.split(“,f,,o, o,”);
Strings: Splitter
“,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
“,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”]
Splitter.on(‘,’)
.omitEmptyStrings()
.split(“,f,,o, o,”);
Strings: Splitter
“,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
“,f,,o, o,”.split(“,”) we probably want [“f”,”o”,”o”]
Splitter.on(‘,’)
.omitEmptyStrings()
.trimResults()
.split(“,f,,o, o,”);
Strings: Splitter
“,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
“,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
Strings
Joiner
[“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”]
Strings: Joiner
[“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”]
Joiner.on(“, “)
.join(twentyFour);
Strings: Joiner
[“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”]
Joiner.on(“, “)
.join(twentyFour);
// throws NullPointerException!
Strings: Joiner
[“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”]
Joiner.on(“, “)
.join(twentyFour);
// throws NullPointerException!
// null-hostile operations everywhere, good thing ;)
Strings: Joiner
[“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”]
Joiner.on(“, “)
.skipNulls();
.join(twentyFour);
// returns “Jack, Chloe, Tony, Nina, Logan”
Strings: Joiner
[“Jack, “Chloe”, “Tony”, null, “Nina”, “Logan”]
Joiner.on(“, “)
.useForNull(“Bill”);
.join(twentyFour);
// returns “Jack, Chloe, Tony, Bill, Nina, Logan”
Strings: Joiner
javadoc
Always think how to avoid null-idioty
Bottom line
Strings
CharMatcher
Your StringUtils replacement
Strings: CharMatcher
Your StringUtils replacement
CharMatcher.JAVA_ISO_CONTROL.removeFrom(string); // remove control chars
Strings: CharMatcher
Your StringUtils replacement
CharMatcher.JAVA_ISO_CONTROL.removeFrom(string);
CharMatcher.DIGIT.retainFrom(“jordi9”); // returns 9
Strings: CharMatcher
Your StringUtils replacement
CharMatcher.JAVA_ISO_CONTROL.removeFrom(string);
CharMatcher.DIGIT.retainFrom(“jordi9”);
CharMatcher.DIGIT.removeFrom(“jordi9”); // returns jordi
Strings: CharMatcher
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
// 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
// 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
Strings
Escapers
HtmlEscapers.htmlEscaper().escape("Foo > bar");
// returns Foo &gt; bar
Escapers
HtmlEscapers.htmlEscaper().escape("Foo > bar");
XmlEscapers.xmlAttributeEscaper().escape("foo "bar"");
// returns foo &quot;bar&quot;
Escapers
HtmlEscapers.htmlEscaper().escape("Foo > bar");
XmlEscapers.xmlAttributeEscaper().escape("foo "bar"");
XmlEscapers.xmlContentEscaper().escape("foo "bar"");
// returns foo “bar”
Escapers
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
Collections
Collections: Functional Idiom
Collections: Functional Idiom
Collections: Functional Idiom
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
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
Multiset<Integer> lengths = HashMultiset.create();
for (String string : strings) {
if (CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string)) {
lengths.add(string.length());
}
}
Collections: Functional Idiom
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
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
Immutable = Thread-safe
Collections: Immutable types
Immutable = Thread-safe
static final ImmutableSet<String> FOO_NAMES =
ImmutableSet.of(“foo”, “bar”, “baz”);
Collections: Immutable types
Immutable = Thread-safe
static final ImmutableSet<String> FOO_NAMES =
ImmutableSet.of(“foo”, “bar”, “baz”);
// ImmutableList, ImmutableMap...
Collections: Immutable types
Immutable = Thread-safe
static final ImmutableSet<String> FOO_NAMES =
ImmutableSet.of(“foo”, “bar”, “baz”);
ImmutableList<String> defensiveCopy =
ImmutableList.copyOf(someList);
Collections: Immutable types
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
A bag
Collections: Multiset<E>
A bag
Just like a Set<E> with repeated values
Collections: Multiset<E>
A bag
Just like a Set<E> with repeated values
You’ve done this with ArrayList<E> or Map<E, Integer>
Collections: Multiset<E>
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>
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>
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>
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>
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>
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
A Map<K, V> with multiple values
Collections: Multimap<K, V>
A Map<K, V> with multiple values
You’ve done this with Map<K, List<V>>
Collections: Multimap<K, V>
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>
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>
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>
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
// Bi-directional map, keys and values are unique
BiMap<K1, K2>
Goodies!
javadoc
// 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
// 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
// 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
Tons of good abstractions for you to use
Bottom line
Hashing
Freaking PHP: md5($string)
Hashing: JDK
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
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
HashFunction hf = Hashing.md5();
Hashing: Hasher
HashFunction hf = Hashing.md5();
HashCode hc = hf.newHasher()
.putLong(id)
.putString(name, Charsets.UTF_8)
.putObject(person, personFunnel)
.hash();
Hashing: Hasher
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
HashFunction hf = Hashing.md5();
HashCode hc = hf.newHasher()
.putLong(id)
.putString(name, Charsets.UTF_8) // HINT: remember this!
.putObject(person, personFunnel)
.hash();
Hashing: Hasher
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
// More hash functions!
Hashing.md5();
Hashing.murmur3_32();
Hashing.murmur3_128();
Hashing.sha1();
Hashing.sha256();
Hashing.sha512();
Goodies!
javadoc
// 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
I/O
Binary encoding scheme, RFC 4648
I/O: BaseEncoding
Binary encoding scheme, RFC 4648 -- Serious stuff
I/O: BaseEncoding
Binary encoding scheme, RFC 4648
BaseEncoding
.base32()
.encode("foo".getBytes(Charsets.US_ASCII));
I/O: BaseEncoding
Binary encoding scheme, RFC 4648
BaseEncoding
.base32()
.encode("foo".getBytes(Charsets.US_ASCII));
// returns MZXW6===
I/O: BaseEncoding
Binary encoding scheme, RFC 4648
BaseEncoding
.base32()
.encode("foo".getBytes(Charsets.US_ASCII));
// returns MZXW6===
byte[] decoded = BaseEncoding
.base32()
.decode("MZXW6===");
I/O: BaseEncoding
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
// More schemas
BaseEncoding.base16();
BaseEncoding.base32();
BaseEncoding.base64();
BaseEncoding.base64Url(); // Useful all the time
Goodies!
javadoc
KIA
KIA
Caches EventBus
KIA
Caches
Networking
EventBus
Concurrency
KIA
Caches
Networking
Math
EventBus
Concurrency
More I/O
KIA
Caches
Networking
Math
Reflection
EventBus
Concurrency
More I/O
Collect
KIA
Caches
Networking
Math
Reflection
Primitives
EventBus
Concurrency
More I/O
Collect
Grumpy
Your friends
Wiki
Your friends
Wiki
javadoc
Remember
The “wheel”
Remember
Read this code
Remember
No Grumpy Cats were
harmed in the making of
this presentation
Thanks!
jordi@donky.org
@jordi9
Q & A
jordi@donky.org
@jordi9

Más contenido relacionado

La actualidad más candente

Google Guava & EMF @ GTUG Nantes
Google Guava & EMF @ GTUG NantesGoogle Guava & EMF @ GTUG Nantes
Google Guava & EMF @ GTUG Nantesmikaelbarbero
 
The Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 SeasonsThe Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 SeasonsBaruch Sadogursky
 
Java 8 Puzzlers [as presented at OSCON 2016]
Java 8 Puzzlers [as presented at  OSCON 2016]Java 8 Puzzlers [as presented at  OSCON 2016]
Java 8 Puzzlers [as presented at OSCON 2016]Baruch Sadogursky
 
Scala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 WorldScala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 WorldBTI360
 
JEEConf 2017 - Having fun with Javassist
JEEConf 2017 - Having fun with JavassistJEEConf 2017 - Having fun with Javassist
JEEConf 2017 - Having fun with JavassistAnton Arhipov
 
Stuff you didn't know about action script
Stuff you didn't know about action scriptStuff you didn't know about action script
Stuff you didn't know about action scriptChristophe Herreman
 
Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Programming Java - Lection 07 - Puzzlers - Lavrentyev FedorProgramming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Programming Java - Lection 07 - Puzzlers - Lavrentyev FedorFedor Lavrentyev
 
Programmation fonctionnelle en JavaScript
Programmation fonctionnelle en JavaScriptProgrammation fonctionnelle en JavaScript
Programmation fonctionnelle en JavaScriptLoïc Knuchel
 
Jquery 1.3 cheatsheet_v1
Jquery 1.3 cheatsheet_v1Jquery 1.3 cheatsheet_v1
Jquery 1.3 cheatsheet_v1Sultan Khan
 
Jquery 13 cheatsheet_v1
Jquery 13 cheatsheet_v1Jquery 13 cheatsheet_v1
Jquery 13 cheatsheet_v1ilesh raval
 
Let the type system be your friend
Let the type system be your friendLet the type system be your friend
Let the type system be your friendThe Software House
 
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev FedorProgramming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev FedorFedor Lavrentyev
 
Kotlin collections
Kotlin collectionsKotlin collections
Kotlin collectionsMyeongin Woo
 
Ian 20150116 java script oop
Ian 20150116 java script oopIan 20150116 java script oop
Ian 20150116 java script oopLearningTech
 
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloading
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloadingRiga DevDays 2017 - The hitchhiker’s guide to Java class reloading
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloadingAnton Arhipov
 
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵Wanbok Choi
 
Functional Programming In Java
Functional Programming In JavaFunctional Programming In Java
Functional Programming In JavaAndrei Solntsev
 
Collections Framework
Collections FrameworkCollections Framework
Collections FrameworkSunil OS
 

La actualidad más candente (20)

Google Guava & EMF @ GTUG Nantes
Google Guava & EMF @ GTUG NantesGoogle Guava & EMF @ GTUG Nantes
Google Guava & EMF @ GTUG Nantes
 
The Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 SeasonsThe Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 Seasons
 
Java 8 Puzzlers [as presented at OSCON 2016]
Java 8 Puzzlers [as presented at  OSCON 2016]Java 8 Puzzlers [as presented at  OSCON 2016]
Java 8 Puzzlers [as presented at OSCON 2016]
 
Scala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 WorldScala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 World
 
JEEConf 2017 - Having fun with Javassist
JEEConf 2017 - Having fun with JavassistJEEConf 2017 - Having fun with Javassist
JEEConf 2017 - Having fun with Javassist
 
Java Generics
Java GenericsJava Generics
Java Generics
 
Stuff you didn't know about action script
Stuff you didn't know about action scriptStuff you didn't know about action script
Stuff you didn't know about action script
 
Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Programming Java - Lection 07 - Puzzlers - Lavrentyev FedorProgramming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
 
Programmation fonctionnelle en JavaScript
Programmation fonctionnelle en JavaScriptProgrammation fonctionnelle en JavaScript
Programmation fonctionnelle en JavaScript
 
Jquery 1.3 cheatsheet_v1
Jquery 1.3 cheatsheet_v1Jquery 1.3 cheatsheet_v1
Jquery 1.3 cheatsheet_v1
 
Jquery 13 cheatsheet_v1
Jquery 13 cheatsheet_v1Jquery 13 cheatsheet_v1
Jquery 13 cheatsheet_v1
 
Scala in practice
Scala in practiceScala in practice
Scala in practice
 
Let the type system be your friend
Let the type system be your friendLet the type system be your friend
Let the type system be your friend
 
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev FedorProgramming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
 
Kotlin collections
Kotlin collectionsKotlin collections
Kotlin collections
 
Ian 20150116 java script oop
Ian 20150116 java script oopIan 20150116 java script oop
Ian 20150116 java script oop
 
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloading
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloadingRiga DevDays 2017 - The hitchhiker’s guide to Java class reloading
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloading
 
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
 
Functional Programming In Java
Functional Programming In JavaFunctional Programming In Java
Functional Programming In Java
 
Collections Framework
Collections FrameworkCollections Framework
Collections Framework
 

Similar a Google Guava - Core libraries for Java & Android

Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Seri Moth
 
JavaScript for PHP developers
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developersStoyan Stefanov
 
Object-oriented Javascript
Object-oriented JavascriptObject-oriented Javascript
Object-oriented JavascriptDaniel Ku
 
Javascript Primer
Javascript PrimerJavascript Primer
Javascript PrimerAdam Hepton
 
Data Types and Processing in ES6
Data Types and Processing in ES6Data Types and Processing in ES6
Data Types and Processing in ES6m0bz
 
ぐだ生 Java入門第一回(equals hash code_tostring)
ぐだ生 Java入門第一回(equals hash code_tostring)ぐだ生 Java入門第一回(equals hash code_tostring)
ぐだ生 Java入門第一回(equals hash code_tostring)Makoto Yamazaki
 
PHP Language Trivia
PHP Language TriviaPHP Language Trivia
PHP Language TriviaNikita Popov
 
bullismo e scuola primaria
bullismo e scuola primariabullismo e scuola primaria
bullismo e scuola primariaimartini
 
The Future of JVM Languages
The Future of JVM Languages The Future of JVM Languages
The Future of JVM Languages VictorSzoltysek
 
Grails Launchpad - From Ground Zero to Orbit
Grails Launchpad - From Ground Zero to OrbitGrails Launchpad - From Ground Zero to Orbit
Grails Launchpad - From Ground Zero to OrbitZachary Klein
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on AndroidSven Haiges
 
JavaScript - i och utanför webbläsaren (2010-03-03)
JavaScript - i och utanför webbläsaren (2010-03-03)JavaScript - i och utanför webbläsaren (2010-03-03)
JavaScript - i och utanför webbläsaren (2010-03-03)Anders Jönsson
 
Realm: Building a mobile database
Realm: Building a mobile databaseRealm: Building a mobile database
Realm: Building a mobile databaseChristian Melchior
 
Get started with YUI
Get started with YUIGet started with YUI
Get started with YUIAdam Lu
 
jQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyjQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyHuiyi Yan
 
Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018
Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018
Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018Codemotion
 

Similar a Google Guava - Core libraries for Java & Android (20)

Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02
 
JavaScript for PHP developers
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developers
 
Object-oriented Javascript
Object-oriented JavascriptObject-oriented Javascript
Object-oriented Javascript
 
Javascript Primer
Javascript PrimerJavascript Primer
Javascript Primer
 
Data Types and Processing in ES6
Data Types and Processing in ES6Data Types and Processing in ES6
Data Types and Processing in ES6
 
ぐだ生 Java入門第一回(equals hash code_tostring)
ぐだ生 Java入門第一回(equals hash code_tostring)ぐだ生 Java入門第一回(equals hash code_tostring)
ぐだ生 Java入門第一回(equals hash code_tostring)
 
PHP Language Trivia
PHP Language TriviaPHP Language Trivia
PHP Language Trivia
 
Say It With Javascript
Say It With JavascriptSay It With Javascript
Say It With Javascript
 
bullismo e scuola primaria
bullismo e scuola primariabullismo e scuola primaria
bullismo e scuola primaria
 
The Future of JVM Languages
The Future of JVM Languages The Future of JVM Languages
The Future of JVM Languages
 
F[4]
F[4]F[4]
F[4]
 
Grails Launchpad - From Ground Zero to Orbit
Grails Launchpad - From Ground Zero to OrbitGrails Launchpad - From Ground Zero to Orbit
Grails Launchpad - From Ground Zero to Orbit
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 
Presentatie - Introductie in Groovy
Presentatie - Introductie in GroovyPresentatie - Introductie in Groovy
Presentatie - Introductie in Groovy
 
JavaScript - i och utanför webbläsaren (2010-03-03)
JavaScript - i och utanför webbläsaren (2010-03-03)JavaScript - i och utanför webbläsaren (2010-03-03)
JavaScript - i och utanför webbläsaren (2010-03-03)
 
Realm: Building a mobile database
Realm: Building a mobile databaseRealm: Building a mobile database
Realm: Building a mobile database
 
Get started with YUI
Get started with YUIGet started with YUI
Get started with YUI
 
jQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyjQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journey
 
Wakanday JS201 Best Practices
Wakanday JS201 Best PracticesWakanday JS201 Best Practices
Wakanday JS201 Best Practices
 
Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018
Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018
Kotlin for Android Developers - Victor Kropp - Codemotion Rome 2018
 

Más de Jordi Gerona

Netty from the trenches
Netty from the trenchesNetty from the trenches
Netty from the trenchesJordi Gerona
 
Clean code via dependency injection + guice
Clean code via dependency injection + guiceClean code via dependency injection + guice
Clean code via dependency injection + guiceJordi Gerona
 
Unit Testing - Trovit
Unit Testing - TrovitUnit Testing - Trovit
Unit Testing - TrovitJordi Gerona
 
Mitos y otras criaturas startuperas (webbar)
Mitos y otras criaturas startuperas (webbar)Mitos y otras criaturas startuperas (webbar)
Mitos y otras criaturas startuperas (webbar)Jordi Gerona
 
Unit Testing - GTUG
Unit Testing - GTUGUnit Testing - GTUG
Unit Testing - GTUGJordi Gerona
 
Dependency Injection con Guice - GTUG
Dependency Injection con Guice - GTUGDependency Injection con Guice - GTUG
Dependency Injection con Guice - GTUGJordi Gerona
 

Más de Jordi Gerona (7)

Netty from the trenches
Netty from the trenchesNetty from the trenches
Netty from the trenches
 
Clean code via dependency injection + guice
Clean code via dependency injection + guiceClean code via dependency injection + guice
Clean code via dependency injection + guice
 
Unit Testing - Trovit
Unit Testing - TrovitUnit Testing - Trovit
Unit Testing - Trovit
 
Mitos y otras criaturas startuperas (webbar)
Mitos y otras criaturas startuperas (webbar)Mitos y otras criaturas startuperas (webbar)
Mitos y otras criaturas startuperas (webbar)
 
Mercurial
MercurialMercurial
Mercurial
 
Unit Testing - GTUG
Unit Testing - GTUGUnit Testing - GTUG
Unit Testing - GTUG
 
Dependency Injection con Guice - GTUG
Dependency Injection con Guice - GTUGDependency Injection con Guice - GTUG
Dependency Injection con Guice - GTUG
 

Último

Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 

Último (20)

Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 

Google Guava - Core libraries for Java & Android