Guava - Google Core Libraries for Java 1.5+ - Utility-Klassen, Datenstrukturen und Erweiterungen. Grundlagen, Features und Beispiele. Erstellt von http://www.essential-bytes.de
Preparing Your Data for an Affirmative Action Plan: Promotions
Guava - Google Core Libraries for Java 1.5+
1. Guava
Google Core Libraries for Java 1.5+
Essential Bytes Johannes 1
2. Agenda
Was ist Guava?
Beispiele, Beispiele, Beispiele…
Essential Bytes Johannes 2
3. Was ist Guava?
Häufig benötigte Klassen & Funktionen die Java „fehlen“
Hilfsklassen z.B. für Strings, Vergleiche, …
Neue Datenstrukturen
Nebenläufigkeit, Multi-Threading
…
Ähnlich wie z.B. Apache Commons
Früher bekannt als Google Collections
Apache License 2.0
Sehr aktives Projekt
GWT-kompatibel
Essential Bytes Johannes 3
4. MultiSet
Auch bekannt als „Bag“
Wie normales Set,
aber kann Objekte „mehrfach“ enthalten
Multiset<String> multiset = HashMultiset.create();
multiset.add("Hello World");
multiset.add("Hello World");
System.out.println(multiset.count("Hello World")); //2
multiset.remove("Hello World");
System.out.println(multiset.count("Hello World")); //1
Selten benötigt, aber dann extrem nützlich
Essential Bytes Johannes 4
5. MultiMap
Wie normale Map, aber
kann für jeden Key mehrere Values enthalten
Person alice = new Person();
Person bobJr = new Person();
Person aliceJr = new Person();
Multimap<Person, Person> parentToChildren =
HashMultimap.create();
parentToChildren.put(alice, bobJr);
parentToChildren.put(alice, aliceJr);
Collection<Person> aliceChildren =
parentToChildren.get(alice);
Ähnlich wie: Map<Person, Collection<Person>>
Essential Bytes Johannes 5
6. BiMap
Eine Map bei der nicht nur Keys sondern auch Values
einmalig sind
Lässt sich deswegen per invert() umdrehen:
Keys werden zu Values und umgekehrt
Essential Bytes Johannes 6
7. Table
Eine Map mit zwei Keys (mehr oder weniger)
Row-Key
Column-Key
Ersatz für Map<T, Map<U, V>>
Per .row() erhält man eine Map einer Reihe
Per .column() eine Map einer Spalte
Essential Bytes Johannes 7
8. Collection Utiltities
Statische Konstruktoren um Collections einfacher
erzeugen zu können
Methoden die java.util.Collections fehlen
.getFirst()
.frequency()
…
Für Listen
.partition() Teil Liste in kleinere Listen auf
.reverse()
…
Essential Bytes Johannes 8
9. Collection Utilties
„Mengenlehre“
.union()
.intersection()
…
Versionen der java.util.Collections-Methoden für Guava‘s
neue Datenstrukturen
Essential Bytes Johannes 9
10. Immutable Collections
Eine Collection die nicht verändert werden kann
Collection<String> colors = ImmutableSet.of("red",
"orange", "yellow", "green", "blue");
Java kann etwas ähnliches: Unmodifiable Collections
Collection<String> colors =
Collections.unmodifiableList(Arrays.asList(
"red", "orange", "yellow", "green", "blue"));
Aber
Original geändert Unmodifiable Collection geändert
Keine optimierte Datenstruktur: Speicherverbrauch
und Performance schlechter als Guava
Essential Bytes Johannes 10
11. Immutable Collections
Wozu das Ganze?
Manipulationssicher: Fremder Code kann nicht
absichtlich oder ausversehen Inhalt ändern
Methoden sollten wann immer möglich Immutable
Collections zurückgeben
Thread-Safe: Keine Änderungen Keine parallelen
Änderungen
Etwas bessere Performance
Viel besserer Speicherverbrauch (1/3 von HashSet)
Kann als Konstante verwendet werden
Essential Bytes Johannes 11
12. equals() und hashCode()
Von Eclipse generiert:
public class Person { return false;
if (getClass() != obj.getClass())
private String firstName; return false;
Person other = (Person) obj;
private String lastName; if (birthDay == null) {
if (other.birthDay != null)
private Date birthDay; return false;
} else if (!birthDay.equals(other.birthDay))
@Override return false;
public int hashCode() { if (firstName == null) {
final int prime = 31; if (other.firstName != null)
int result = 1; return false;
result = prime * result + ((birthDay == } else if
null) ? 0 : birthDay.hashCode()); (!firstName.equals(other.firstName))
result = prime * result + ((firstName == return false;
null) ? 0 : firstName.hashCode()); if (lastName == null) {
result = prime * result + ((lastName == if (other.lastName != null)
null) ? 0 : lastName.hashCode()); return false;
return result; } else if (!lastName.equals(other.lastName))
} return false;
return true;
@Override }
public boolean equals(Object obj) {
if (this == obj) }
return true;
if (obj == null)
Essential Bytes Johannes 12
13. equals() und hashCode()
Guava:
public class Person {
Ähnliche
Methode gibt
private String firstName;
es auch für
private String lastName; toString()
private Date birthDay;
@Override
public int hashCode() {
return Objects.hashCode(firstName, lastName, birthDay);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Person) {
Person other = (Person) obj;
return Objects.equal(firstName, other.firstName)
&& Objects.equal(lastName, other.lastName)
&& Objects.equal(birthDay, other.birthDay);
}
return false;
}
}
Essential Bytes Johannes 13
14. ComparisonChain
Java-Standard
public int compareTo(Person o) {
if(lastName == null && o.lastName != null)
return -1;
int lastNameCompared = lastName.compareTo(o.lastName);
if(lastNameCompared != 0)
return lastNameCompared;
if(firstName == null && o.firstName != null)
return -1;
else
return firstName.compareTo(o.firstName);
}
Guava
public int compareTo(Person o) {
return ComparisonChain.start().compare(lastName, o.lastName)
.compare(firstName, o.firstName).result();
}
Essential Bytes Johannes 14
15. Preconditions
Java-Standard
public void setBirthDay(Date birthDay) {
Date today = new Date();
if (today.before(birthDay)) {
throw new IllegalArgumentException("Birthday must not be in the future");
}
this.birthDay = birthDay; Ähnliche
} Methoden für:
• NullPointer
Exception
• IllegalState
Guava Exception
• …
public void setBirthDay(Date birthDay) {
Date today = new Date();
checkArgument(today.before(birthDay), "Birthday must not be in the future");
this.birthDay = birthDay;
}
Essential Bytes Johannes 15
18. Splitter
Das Gegenstück zum Joiner
Iterable<String> animals =
Splitter.on(',').split("cat, dog, velociraptor");
Java kann das zwar auch
String[] animals =
"cat, dog, velociraptor".split(",");
aber
Verwendet reguläre Ausdrücke (split(".") geht also schief)
Gibt Arrays zurück
Seltsamer Umgang mit null-Werten und Leerzeichen
Essential Bytes Johannes 18
20. Primitives
Min / Max
Longs.min(7823, 23487, 198, 213, 2340);
Saturated Cast
int number = (int) 12345678910; //-539222978
int number = Ints.saturatedCast(12345678910);
//2147483647
uvm.
Essential Bytes Johannes 20
21. Unsigned
Wrapper- und Utility-Klassen für unsigned int und long
UnsignedInteger number =
UnsignedInteger.valueOf(Integer.MAX_VALUE);
number = number.add(UnsignedInteger.valueOf(1L));
System.out.println(number); //2147483648
Essential Bytes Johannes 21
22. common.io
Bessere Ein- und Ausgabestreams für Dateien
Methoden wie
Kopieren
Verschieben
…
Aber:
durch Java 7 hinfällig
evtl. für Java 5 & 6 noch interessant
Essential Bytes Johannes 22
23. Optional
Gefährlich: null als „optional“ oder „nicht gefunden“
Person findPersonBy(Collection<Person> persons,
String firstName, String lastName) {
for (Person person : persons) {
if (firstName.equals(person.getFirstName())
&& lastName.equals(person.getLastName())) {
return person;
}
}
// No matching entry found, return null
return null;
}
Essential Bytes Johannes 23
24. Optional
Was wenn
Eine Person nicht gefunden wird und der Aufrufer mit
dem Null-Wert arbeitet?
Nach einer Person ohne Vornamen gesucht wird?
NullPointerException
Essential Bytes Johannes 24
25. Optional
Optional<Person> findPerson(Collection<Person> persons,
Optional<String> firstName, String lastName) {
for (Person person : persons) {
if ((!firstName.isPresent()
|| firstName.equals(person.getFirstName()))
&& lastName.equals(person.getLastName())) {
return Optional.of(person);
}
}
// No matching entry found, return absent
return Optional.absent();
}
Essential Bytes Johannes 25
26. Optional
Erzeugen
Optional.of(reference); //Fehler bei null
Optional.fromNullable(reference);
Optional.absent();
Verwenden
.isPresent()
.get()
.or(defaultValue)
.orNull()
Essential Bytes Johannes 26
27. Cache
Einfacher Cache
Nur lokal und nur im RAM
Unterstützt Nebenläufigkeit
„Self populating“
Aufräumen nach Zeit oder Größe
Statistiken
Viel besser als zweckentfremdete Maps
Kein Ersatz für große Server-Caches (Memcached,
EHCache, …)
Essential Bytes Johannes 27
28. Cache
LoadingCache<String, Person> cache =
CacheBuilder.newBuilder().maximumSize(500)
.expireAfterAccess(5, TimeUnit.MINUTES).build(
new CacheLoader<String, Person>(){
public Person load(String key) throws Exception{
return fetchPersonFromDatabase(key);
}
}
);
Person someone = cache.get("Wulff");
Essential Bytes Johannes 28
29. EventBus
Publish-Subscribe-Kommunikation
Kommunikation zwischen Komponenten
Komponenten müssen sich nicht kennen
Vergleichbar mit Observer-Pattern oder Messaging, aber:
Nur lokal
Keine Extras wie Persistenz, Vetos, etc.
Extrem hilfreich, aber Kapitel für sich
Essential Bytes Johannes 29
30. Und sonst so
Jede Menge weitere Hilfsmethoden
Nebenläufigkeit
Thread-Ersatz für Hintergrunddienste
Ersatz für ReentrantLock
Erweiterte Future mit Callback-Unterstützung
Wert-Bereiche
„Funktionales Programmieren“ (mit anonymen Klassen)
Ersatz für hashCode() für Fälle mit zu vielen Kollisionen
Bloom-Filter
…
Essential Bytes Johannes 30