SlideShare ist ein Scribd-Unternehmen logo
1 von 119
08/11/2011

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique
08/11/2011

Guava by Google
Thierry Leriche
Consultant freelance
ICAUDA

Etienne Neveu
Consultant
SFEIR
Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique
« Pourquoi aimons-nous
tant Google Guava ? »

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

3
Factory Methods

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

4
Factory Methods
Avec Java 5
List<Integer> primeNumbers = new ArrayList<Integer>();
Set<String> colors = new TreeSet<String>();
Map<String, Integer> ages = new HashMap<String, Integer>();

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

5
Factory Methods
Avec Java 5
List<Integer> primeNumbers = new ArrayList<Integer>();
Set<String> colors = new TreeSet<String>();
Map<String, Integer> ages = new HashMap<String, Integer>();

ou même...
Map<String, List<String>> favoriteColors
= new HashMap<String, List<String>>();
Map<? extends Person, Map<String, List<String>>> favoriteColors
= new TreeMap<? Extends Person, Map<String, List<String>>>();

on peut facilement trouver pire...

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

6
Factory Methods
Avec Java 5
List<Integer> primeNumbers = new ArrayList<Integer>();
Set<String> colors = new TreeSet<String>();
Map<String, Integer> ages = new HashMap<String, Integer>();

Avec Java 7
List<Integer> primeNumbers = new ArrayList<>();
Set<String> colors = new TreeSet<>();
Map<String, Integer> ages = new HashMap<>();

mais quand ?

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

7
Factory Methods
Avec Java 5
List<Integer> primeNumbers = new ArrayList<Integer>();
Set<String> colors = new TreeSet<String>();
Map<String, Integer> ages = new HashMap<String, Integer>();

Avec Java 7
List<Integer> primeNumbers = new ArrayList<>();
Set<String> colors = new TreeSet<>();
Map<String, Integer> ages = new HashMap<>();

Avec Guava
List<Integer> primeNumbers = newArrayList();
Set<String> colors = newTreeSet();
Map<String, Integer> ages = newHashMap();

tout de suite
08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

8
Factory Methods
Par exemple, avec des chiens
public class Dog {
private String name;
private Double weight;
private Sex sex;
public Dog(String name, Sex sex) {
this.name = name ;
this.sex = sex;
}
// getters & setters
}

public enum Sex {
MALE, FEMALE
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

9
Factory Methods
Par exemple, avec des chiens
List<Dog> dogs = newArrayList();
dogs.add(new Dog("Milou", MALE));
dogs.add(new Dog("Idefix", MALE));
dogs.add(new Dog("Lassie", FEMALE));
dogs.add(new Dog("Rintintin", MALE));
dogs.add(new Dog("Lady", FEMALE));
dogs.add(new Dog("Medor", MALE));

08/11/2011

Guava by Google

Milou
Idefix
Lassie
Rintintin
Lady
Medor

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

10
Factory Methods
Ou plutôt
List<Dog> dogs = newArrayList(
new Dog("Milou", MALE),
new Dog("Idefix", MALE),
new Dog("Lassie", FEMALE),
new Dog("Rintintin", MALE),
new Dog("Lady", FEMALE),
new Dog("Medor", MALE)
);

08/11/2011

Guava by Google

Milou
Idefix
Lassie
Rintintin
Lady
Medor

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

11
Functional Programming

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

12
Functional Programming
Filtre avec Predicate
Iterable<Dog> maleDogs = Iterables.filter(dogs,
new Predicate<Dog>() {
public boolean apply(Dog dog) {
return dog.getSex() == MALE;
}
});

Milou
Idefix
prog fonc ? Rintintin
Medor

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

13
Functional Programming
And, or, in, not, ...
List<Dog> superDogs = newArrayList(
new Dog("Milou", MALE),
new Dog("Lassie", FEMALE),
new Dog("Volt", MALE));

08/11/2011

Guava by Google

Milou
Lassie
Volt

Milou
Idefix
Lassie
Rintintin
Lady
Medor

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

14
Functional Programming
And, or, in, not, ...
List<Dog> superDogs = newArrayList(
new Dog("Milou", MALE),
new Dog("Lassie", FEMALE),
new Dog("Volt", MALE));

boolean isMilouInBoth
= and(in(dogs), in(superDogs))
.apply(new Dog("Milou"));

boolean isTintinInOne
= or(in(dogs), in(superDogs))
.apply(new Dog("Tintin"));

08/11/2011

Guava by Google

Milou
Lassie
Volt

Milou
Idefix
Lassie
Rintintin
Lady
Medor

true

false

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

15
Functional Programming
Un chien en français
public class Chien {
private String prenom;
public Chien(String prenom) {
this.prenom = prenom;
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

16
Functional Programming
Transformation
List<Chien> chiens =
Lists.transform(dogs, new Function<Dog, Chien>() {
public Chien apply(Dog dog) {
return new Chien(dog.getName());
}
});

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

17
Functional Programming
Attention : vue
List<Chien> chiens =
Lists.transform(dogs, new Function<Dog, Chien>() {
public Chien apply(Dog dog) {
return new Chien(dog.getName());
}
});

–

Vue (lazy)

–

size / isEmpty dispo

–

Pas fait pour des traitements multiples

List<Chien> chiens = newArrayList(Lists.transform(...

ImmutableList<Chien> chiens
= ImmutableList.copyOf(Lists.transform(...

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

18
Functional Programming
Converter Spring
import org.springframework...Converter;

@Component("dogToChienConverter")
public class DogToChienConverter
implements Converter<List<Dog>, List<Chien>> {
public List<Chien> convert(List<Dog> dogs) {
List<Chien> chiens = newArrayList(Lists.transform(dogs,
new Function<Dog, Chien>() {
public Chien apply(Dog dog) {
return new Chien(dog.getName());
}
}));
}

return chiens;

Lazy or not lazy ?

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

19
Functional Programming
Find
Predicate<Dog> malePredicate = new Predicate<Dog>() {
public boolean apply(Dog dog) {
return dog.getSex() == MALE;
}};

Dog firstMale = Iterables.find(dogs, malePredicate);

Milou

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

20
Functional Programming
Find
Predicate<Dog> malePredicate = new Predicate<Dog>() {
public boolean apply(Dog dog) {
return dog.getSex() == MALE;
}};

Dog firstMale = Iterables.find(dogs, malePredicate);

Milou

Dog firstMale = Iterables.find(femaleDogs, malePredicate, DEFAULT_DOG );

Chien par défaut

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

21
Immutable Collections

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

22
Immutable Collections
Set (en Java)
Set<Integer> temp = new LinkedHashSet<Integer>(
Arrays.asList(1, 2, 3, 5, 7));
Set<Integer> primeNumbers = Collections.unmodifiableSet(temp);

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

23
Immutable Collections
Set (en Java) Vs ImmutableSet (Guava)
Set<Integer> temp = new LinkedHashSet<Integer>(
Arrays.asList(1, 2, 3, 5, 7));
Set<Integer> primeNumbers = Collections.unmodifiableSet(temp);

Guava
Set<Integer> primeNumbers = ImmutableSet.of(1, 2, 3, 5, 7);

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

24
Immutable Collections
Multi « of »
ImmutableSet.of(E
ImmutableSet.of(E
ImmutableSet.of(E
ImmutableSet.of(E
ImmutableSet.of(E
ImmutableSet.of(E

e1)
e1,
e1,
e1,
e1,
e1,

E
E
E
E
E

e2)
e2,
e2,
e2,
e2,

E
E
E
E

e3)
e3, E e4)
e3, E e4, E e5)
e3, E e4, E e5, E e6, E...)

n'accepte pas les éléments null

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

25
Immutable Collections
Multi « of »
ImmutableSet.of(E
ImmutableSet.of(E
ImmutableSet.of(E
ImmutableSet.of(E
ImmutableSet.of(E
ImmutableSet.of(E

e1)
e1,
e1,
e1,
e1,
e1,

E
E
E
E
E

e2)
e2,
e2,
e2,
e2,

E
E
E
E

e3)
e3, E e4)
e3, E e4, E e5)
e3, E e4, E e5, E e6, E...)

n'accepte pas les éléments null
ImmutableSet.of()

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

26
Immutable Collections
Copie de défense (en java)
public class Person {
private final Set<String> favoriteColors;
private final String firstName;
public Person(Set<String> favoriteColors, String firstName) {
this.favoriteColors = Collections.unmodifiableSet(
new LinkedHashSet<String>(favoriteColors));
this.firstName = firstName;
}
public Set<String> getFavoriteColors() {
return favoriteColors;
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

27
Immutable Collections
Copie de défense (Guava)
public class Person {
private final ImmutableSet<String> favoriteColors;
private final String firstName;
public Person(Set<String> favoriteColors, String firstName) {
this.favoriteColors = ImmutableSet.copyOf(favoriteColors));
}

this.firstName = firstName;

public ImmutableSet<String> getFavoriteColors() {
return favoriteColors;
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

28
Base – Objects

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

29
Base – Objects
Le retour du chien
public class Dog {
private String name;
private Double weight;
private Sex sex;
public Dog(String name, Sex sex) {
this.name = name ;
this.sex = sex;
}
// getters & setters
}

public enum Sex {
MALE, FEMALE
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

30
Base – Objects
Objects.equal()
public boolean equals(Object other) {
if (!(other instanceof Dog)) return false;
Dog that = (Dog) other;

}

return
(name == that.name
|| (name != null && name.equals(that.name)))
&& (weight == that.weight
|| (weight != null && weight.equals(that.weight)))
&& sex == that.sex;

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

31
Base – Objects
Objects.equal()
public boolean equals(Object other) {
if (!(other instanceof Dog)) return false;
Dog that = (Dog) other;

}

return
Objects.equal(name, that.name)
&& Objects.equal(weight, that.weight)
&& sex == that.sex;

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

32
Base – Objects
Objects.hashCode()
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + (weight != null ? weight.hashCode():0);
result = 31 * result + (sex != null ? sex.hashCode():0);
}

return result;

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

33
Base – Objects
Objects.hashCode()
public int hashCode() {
}

return Objects.hashCode(name, weight, sex);

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

34
Base – Objects
Objects.toStringHelper()
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(Dog.class.getSimpleName());
sb.append("{name=").append(name);
sb.append(", weight=").append(weight);
sb.append(", sex=").append(sex);
sb.append('}');
return sb.toString();
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

35
Base – Objects
Objects.toStringHelper()
public String toString() {

}

return Objects.toStringHelper(this)
.add("name", name)
.add("weight", weight)
.add("sex", sex)
.toString();

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

36
Base – Objects
ComparisonChain
public int compareTo(Dog other) {
int result = name.compareTo(other.name);
if (result != 0) {
return result;
}
result = weight.compareTo(other.weight);
if (result != 0) {
return result;
}
}

return sex.compareTo(other.sex);

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

37
Base – Objects
ComparisonChain
public int compareTo(Dog other) {

}

return ComparisonChain.start()
.compare(name, other.name)
.compare(weight, other.weight)
.compare(sex, other.sex)
.result();

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

38
Base – Objects
ComparisonChain
public int compareTo(Dog other) {

}

return ComparisonChain.start()
.compare(name, other.name, NULL_LAST_COMPARATOR)
.compare(weight, other.weight, NULL_LAST_COMPARATOR)
.compare(sex, other.sex, NULL_LAST_COMPARATOR)
.result();

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

39
Base – Preconditions

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

40
Base – Preconditions
Money money money

@Immutable
public class Money {
@Nonnull
private final BigDecimal amount;
@Nonnull
private final Currency currency;
public Money(BigDecimal amount, Currency currency) {
// ???
}
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

41
Base – Preconditions
Validation classique des arguments

public Money(BigDecimal amount, Currency currency) {
if (amount == null) {
throw new NullPointerException("amount cannot be null");
}
if (currency == null) {
throw new NullPointerException("currency cannot be null");
}
if (amount.signum() < 0) {
throw new IllegalArgumentException("must be positive: " + amount);
}

}

this.amount = amount;
this.currency = currency;

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

42
Base – Preconditions
Validation avec Preconditions
import static com.google.common.base.Preconditions.*;
public Money(BigDecimal amount, Currency currency) {
checkNotNull(amount, "amount cannot be null");
checkNotNull(currency, "currency cannot be null");
checkArgument(amount.signum() >= 0, "must be positive: %s", amount);

}

this.amount = amount;
this.currency = currency;

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

43
Base – Preconditions
Validation et assignement inline
import static com.google.common.base.Preconditions.*;
public Money(BigDecimal amount, Currency currency) {
this.amount = checkNotNull(amount, "amount cannot be null");
this.currency = checkNotNull(currency, "currency cannot be null");
checkArgument(amount.signum() >= 0, "must be positive: %s", amount);
}

public static <T> T checkNotNull(T reference) {
if (reference == null) {
throw new NullPointerException();
}
return reference;
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

44
Base – CharMatcher

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

45
Base – CharMatcher
StringUtils ?
String collapse(String source, String charsToCollapse)
String collapseWhitespace(String source)
String collapseControlChars(String source)
int
int

lastIndexOf(String source, String chars)
lastIndexNotOf(String source, String chars)

String
String
String
String

remove(String source, String charsToRemove)
removeDigits(String source)
removeWhitespace(String source)
removeControlChars(String source)

String trim(String source, String charsToStrip)
String trimWhiteSpace(String source)
String trimControlChars(String source)

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

46
Base – CharMatcher
StringUtils → CharMatcher
String collapse(String source, String charsToCollapse)
String collapseWhitespace(String source)
String collapseControlChars(String source)
int
int

lastIndexOf(String source, String chars)
lastIndexNotOf(String source, String chars)

String
String
String
String

remove(String source, String charsToRemove)
removeDigits(String source)
removeWhitespace(String source)
removeControlChars(String source)

String trim(String source, String charsToStrip)
String trimWhiteSpace(String source)
String trimControlChars(String source)
public abstract class CharMatcher {
public boolean matches(char c);
}

// ...
08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

47
Base – CharMatcher
Obtention d'un CharMatcher
CharMatcher.ANY
CharMatcher.NONE
CharMatcher.ASCII
CharMatcher.DIGIT
CharMatcher.WHITESPACE
CharMatcher.JAVA_ISO_CONTROL

CharMatcher.is('x')
CharMatcher.isNot('_')
CharMatcher.anyOf('aeiou').negate()
CharMatcher.inRange('a', 'z').or(CharMatcher.inRange('A', 'Z'))

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

48
Base – CharMatcher
Utilisation d'un CharMatcher
boolean matchesAllOf(CharSequence)
boolean matchesAnyOf(CharSequence)
boolean matchesNoneOf(CharSequence)
int
indexIn(CharSequence, int)
int
lastIndexIn(CharSequence, int)
int
countIn(CharSequence)
String removeFrom(CharSequence)
String retainFrom(CharSequence)
String trimFrom(CharSequence)
String trimLeadingFrom(CharSequence)
String trimTrailingFrom(CharSequence)
String collapseFrom(CharSequence, char)
String trimAndCollapseFrom(CharSequence, char)
String replaceFrom(CharSequence, char)

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

49
Base – CharMatcher
Utilisation d'un CharMatcher
boolean matchesAllOf(CharSequence)
boolean matchesAnyOf(CharSequence)
boolean matchesNoneOf(CharSequence)
int
indexIn(CharSequence, int)
int
lastIndexIn(CharSequence, int)
int
countIn(CharSequence)
String removeFrom(CharSequence)
String retainFrom(CharSequence)
String trimFrom(CharSequence)
String trimLeadingFrom(CharSequence)
String trimTrailingFrom(CharSequence)
String collapseFrom(CharSequence, char)
String trimAndCollapseFrom(CharSequence, char)
String replaceFrom(CharSequence, char)
CharMatcher VALID_CHARS = CharMatcher.DIGIT.or(CharMatcher.anyOf(“-_”);
String VALID_CHARS.retainFrom(input);
checkArgument(!CharMatcher.WHITESPACE.matchesAllOf(input));
08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

50
Collection Utilities

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

51
Collection Utilities
Multimap (avec Java)
Map<String, List<String>> favoriteColors
= new HashMap<String, List<String>>();
List<String> julienColors = favoriteColors.get("Julien");
if(julienColors == null) {
julienColors = new ArrayList<String>();
favoriteColors.put("Julien",julienColors);
}
julienColors.add("Vert");

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

52
Collection Utilities
Multimap (avec Guava)
Map<String, List<String>> favoriteColors
= new HashMap<String, List<String>>();

Multimap<String, String> favoriteColors = HashMultimap.create();
favoriteColors2.put("Julien", "Jaune");
favoriteColors2.put("Julien", "Rouge");

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

53
Collection Utilities
Bimap (Clé-Valeur-Clé)
BiMap<String, String> cars = HashBiMap.create();
cars.put("Thierry", "1234 AB 91");
cars.put("Marie", "4369 ERD 75");
cars.put("Julien", "549 DF 87");

{Thierry=1234 AB 91,
Julien=549 DF 87,
Marie=4369 ERD 75}

println(cars);
println(cars.inverse());

Une map bijective

{1234 AB 91=Thierry,
549 DF 87=Julien,
4369 ERD 75=Marie}

Il est possible de changer la valeur associée à une clé mais pas d'avoir deux clés
avec la même valeur (IllegalArgumentException).
08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

54
Collection Utilities
Multiset
Multiset<Integer> primeNumbers = HashMultiset.create();
primeNumbers.add(2);
primeNumbers.add(3);
primeNumbers.add(7);
primeNumbers.add(11);
primeNumbers.add(3);
primeNumbers.add(5);
println(primeNumbers);

08/11/2011

[2, 3 x 2, 5, 7, 11]

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

55
Collection Utilities
Multiset
Multiset<Integer> primeNumbers = HashMultiset.create();
primeNumbers.add(2);
primeNumbers.add(3);
primeNumbers.add(7);
primeNumbers.add(11);
primeNumbers.add(3);
primeNumbers.add(5);
println(primeNumbers);

println(premiers.count(3))

08/11/2011

[2, 3 x 2, 5, 7, 11]

2

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

56
Joiner / Splitter

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

57
Joiner / Splitter
Joiner
List<String> dogs = newArrayList("Milou", "Idefix", "Rintintin");
String names = Joiner.on(", ").join(dogs);

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

58
Joiner / Splitter
Joiner
List<String> dogs = newArrayList("Milou", "Idefix", "Rintintin");
String names = Joiner.on(", ").join(dogs);

List<String> dogs = newArrayList("Milou", "Idefix", null, "Rintintin");
String names = Joiner.on(", ").join(dogs);
NullPointerException

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

59
Joiner / Splitter
Joiner
List<String> dogs = newArrayList("Milou", "Idefix", "Rintintin");
String names = Joiner.on(", ").join(dogs);

List<String> dogs = newArrayList("Milou", "Idefix", null, "Rintintin");
String names = Joiner.on(", ").join(dogs);
NullPointerException
List<String> dogs = newArrayList("Milou", "Idefix", null, "Rintintin");
String names = Joiner.on(", ").skipNulls().join(dogs);
Milou, Idefix, Rintintin

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

60
Joiner / Splitter
Joiner
List<String> dogs = newArrayList("Milou", "Idefix", "Rintintin");
String names = Joiner.on(", ").join(dogs);

List<String> dogs = newArrayList("Milou", "Idefix", null, "Rintintin");
String names = Joiner.on(", ").join(dogs);
NullPointerException
List<String> dogs = newArrayList("Milou", "Idefix", null, "Rintintin");
String names = Joiner.on(", ").skipNulls().join(dogs);
Milou, Idefix, Rintintin
List<String> dogs = newArrayList("Milou", "Idefix", null, "Rintintin");
String names = Joiner.on(", ").useForNull("Doggie").join(dogs);
Milou, Idefix, Doggie, Rintintin

7

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

61
Joiner / Splitter
Splitter
Iterable<String> superDogs = Splitter.on(",")
.split("Lassie, Volt, Milou");

"Lassie"
" Volt"
" Milou"

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

62
Joiner / Splitter
Splitter
Iterable<String> superDogs = Splitter.on(",")
.split("Lassie, Volt, Milou");
Iterable<String> superDogs = Splitter.on(",")
.split("Lassie, , Volt, Milou");

"Lassie"
" "
" Volt"
" Milou"

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

63
Joiner / Splitter
Splitter
Iterable<String> superDogs = Splitter.on(",")
.split("Lassie, Volt, Milou");
Iterable<String> superDogs = Splitter.on(",")
.split("Lassie, , Volt, Milou");
Iterable<String> superDogs = Splitter.on(",")
.trimResults()
.split("Lassie, , Volt, Milou");

"Lassie"
""
"Volt"
"Milou"

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

64
Joiner / Splitter
Splitter
Iterable<String> superDogs = Splitter.on(",")
.split("Lassie, Volt, Milou");
Iterable<String> superDogs = Splitter.on(",")
.split("Lassie, , Volt, Milou");
Iterable<String> superDogs = Splitter.on(",")
.trimResults()
.split("Lassie, , Volt, Milou");
Iterable<String> superDogs = Splitter.on(",")
.trimResults()
.omitEmptyStrings()
.split("Lassie, , Volt, Milou");

"Lassie"
"Volt"
"Milou"

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

65
Cache – Memoization

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

66
Cache – Memoization
Exemple : service renvoyant la dernière version du JDK
public class JdkService {
@Inject
private JdkWebService jdkWebService;
public JdkVersion getLatestVersion() {
return jdkWebService.checkLatestVersion();
}
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

67
Cache – Memoization
Cache manuel
public class JdkService {
@Inject
private JdkWebService jdkWebService;
public synchronized JdkVersion getLatestVersion() {
if (versionCache == null) {
versionCache = jdkWebService.checkLatestVersion();
}
return versionCache;
}
private JdkVersion versionCache = null;
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

68
Cache – Memoization
Supplier
public class JdkService {
@Inject
private JdkWebService jdkWebService;
public synchronized JdkVersion getLatestVersion() {
if (versionCache == null) {
versionCache = jdkWebService.checkLatestVersion();
public interface Supplier<T> {
}
return versionCache;
T get();
}
}
private JdkVersion versionCache = null;
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

69
Cache – Memoization
Supplier
public class JdkService {
@Inject
private JdkWebService jdkWebService;
public JdkVersion getLatestVersion() {
return versionCache.get();
}
private Supplier<JdkVersion> versionCache =
Suppliers.memoize(
new Supplier<JdkVersion>() {
public JdkVersion get() {
return jdkWebService.checkLatestVersion();
}
}
);
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

70
Cache – Memoization
Suppliers.memoize()
public class JdkService {
@Inject
private JdkWebService jdkWebService;
public JdkVersion getLatestVersion() {
return versionCache.get();
}
private Supplier<JdkVersion> versionCache =
Suppliers.memoize(
new Supplier<JdkVersion>() {
public JdkVersion get() {
return jdkWebService.checkLatestVersion();
}
}
);
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

71
Cache – Memoization
Suppliers.memoizeWithExpiration()
public class JdkService {
@Inject
private JdkWebService jdkWebService;
public JdkVersion getLatestVersion() {
return versionCache.get();
}
private Supplier<JdkVersion> versionCache =
Suppliers.memoizeWithExpiration(
new Supplier<JdkVersion>() {
public JdkVersion get() {
return jdkWebService.checkLatestVersion();
}
},
365, TimeUnit.DAYS
);
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

72
Cache – Key-Value

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

73
Cache – Key-Value
Exemple
public class FilmService {
@Inject
private ImdbWebService imdbWebService;
public Film getFilm(Long filmId) {
return imdbWebService.loadFilmInfos(filmId);
}
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

74
Cache – Key-Value
Cache – Interface
public interface Cache<K, V> extends Function<K, V> {
V get(K key) throws ExecutionException;
V getUnchecked(K key);
void invalidate(Object key);
void invalidateAll();
long size();
CacheStats stats();
ConcurrentMap<K, V> asMap();
}

void cleanUp();

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

75
Cache – Key-Value
CacheBuilder & CacheLoader
public class FilmService {
@Inject
private FilmWebService imdbWebService;
public Film getFilm(Long filmId) {
return filmCache.getUnchecked(filmId);
}
private Cache<Long, Film> filmCache = CacheBuilder.newBuilder()
.build(new CacheLoader<Long, Film>() {
public Film load(Film filmId) {
return imdbWebService.loadFilmInfos(filmId);
}
});
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

76
Cache – Key-Value
Customisation du CacheBuilder
public class FilmService {
@Inject
private FilmWebService imdbWebService;
public Film getFilm(Long filmId) {
return filmCache.getUnchecked(filmId);
}
private Cache<Long, Film> filmCache = CacheBuilder.newBuilder()
.maximumSize(2000)
.expireAfterWrite(30, TimeUnit.MINUTES)
.build(new CacheLoader<Long, Film>() {
public Film load(Long filmId) {
return imdbWebService.loadFilmInfos(filmId);
}
});
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

77
I/O

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

78
I/O
Java 5
public static byte[] toByteArray(File file) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
boolean threw = true;
InputStream in = new FileInputStream(file);
try {
byte[] buf = new byte[BUF_SIZE];
while (true) {
int r = in.read(buf);
if (r == -1) break;
out.write(buf, 0, r);
}
threw = false;
} finally {
try {
in.close();
} catch (IOException e) {
if (threw) {
logger.warn("IOException thrown while closing", e);
} else {
throw e;
}
}
}
return out.toByteArray();
}
08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

79
I/O
Java 7 – Automatic Resource Management (ARM)
public static byte[] toByteArray(File file) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try (InputStream in = new FileInputStream(file);) {
byte[] buf = new byte[BUF_SIZE];
while (true) {
int r = in.read(buf);
if (r == -1) break;
out.write(buf, 0, r);
}
}
}

return out.toByteArray();

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

80
I/O
Guava
public static byte[] toByteArray(File file) throws IOException {
return Files.toByteArray(file) ;
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

81
I/O
InputSupplier & OutputSupplier
interface InputSupplier<T> {

interface OutputSupplier<T> {

T getInput() throws IOException;
}

T getOutput() throws IOException;
}

InputSupplier<InputStream>

OutputSupplier<OutputStream>

InputSupplier<Reader>

OutputSupplier<Writer>

try {
InputStream stream = new FileInputStream(file) ;
} catch (IOException ioex) {
throw Throwables.propagate(ioex);
}
InputSupplier<InputStream> stream = Files.newInputStreamSupplier(file);

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

82
I/O
ByteStreams
byte[] toByteArray(InputStream)
byte[] toByteArray(InputSupplier<InputStream>)
T readBytes(InputSupplier<InputStream>, ByteProcessor<T>)
void write(byte[], OutputSupplier<OutputStream>)
long copy(InputStream, OutputStream)
long copy(InputSupplier<InputStream>,
OutputSupplier<OutputStream>)
InputSupplier<InputStream> join(InputSupplier<InputStream>...)

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

83
I/O
CharStreams
String toString(Readable)
String toString(InputSupplier<Readable & Closeable>)
T readLines(InputSupplier<Readable & Closeable>, LineProcessor<T>)
void write(CharSequence, OutputSupplier<Appendable & Closeable>)
long copy(Readable, Appendable)
long copy(InputSupplier<Readable & Closeable>,
OutputSupplier<Appendable & Closeable>)
InputSupplier<Reader> join(InputSupplier<Reader>...)

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

84
I/O
Files
byte[] toByteArray(File)
String toString(File, Charset)
List<String> readLines(File, Charset)
void write(byte[], File)
void write(CharSequence, File to, Charset)
void copy(File from, File to)
void copy(InputSupplier<...>, File)
void copy(File, OutputSupplier<...>)
void move(File, File)

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

85
Concurrent

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

86
Concurrent
Future
List<Note> getNotes(Film film) {
Note noteImdb = imdbService.getNote(film);
Note noteAllo = allocineService.getNote(film);
return ImmutableList.of(noteImdb, noteAllo);
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

87
Concurrent
Future
List<Note> getNotes(Film film) {
Note noteImdb = imdbService.getNote(film);
Note noteAllo = allocineService.getNote(film);
return ImmutableList.of(noteImdb, noteAllo);
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

88
Concurrent
Future
List<Note> getNotes(Film film) {
Note noteImdb = imdbService.getNote(film);
Note noteAllo = allocineService.getNote(film);
return ImmutableList.of(noteImdb, noteAllo);
}

List<Note> getNotes(Film film) {
Future<Note> noteImdb = imdbService.getNote(film);
Future<Note> noteAllo = allocineService.getNote(film);
return ImmutableList.of(noteImdb.get(), noteAllo.get());
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

89
Concurrent
Future – Obtention
public class ImdbService {
private ImdbWebService imdbWebService;
@Inject
ImdbService(ImdbWebService imdbWs) {
this.imdbWebService = imdbWs;
}
public Note getNote(Film film) {
return imdbWebService.getNote(film);
}
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

90
Concurrent
Future – Obtention
public class ImdbService {
private ImdbWebService imdbWebService;
private ExecutorService executor;
@Inject
ImdbService(ImdbWebService imdbWs, ExecutorService executor) {
this.imdbWebService = imdbWs;
this.executor = executor;
}
public Future<Note> getNote(final Film film) {
return executor.submit(new Callable<Note>() {
public Note call() {
return imdbWebService.getNote(film);
}
});
}
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

91
Concurrent
ListenableFuture
public interface ListenableFuture<V> extends Future<V> {
void addListener(Runnable listener, Executor executor);
}

ListenableFuture<Result> future = ...
future.addListener(new Runnable() {
public void run() {
logger.debug("Future is done");
}
}, executor);

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

92
Concurrent
ListenableFuture – Callbacks
future.addListener(new Runnable() {
public void run() {
try {
Result result = Uninterruptibles.getUninterruptibly(future);
storeInCache(result);
} catch (ExecutionException e) {
reportError(e.getCause());
} catch (RuntimeException e) {
// just in case
}
}
}, executor);

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

93
Concurrent
ListenableFuture – Callbacks
future.addListener(new Runnable() {
public void run() {
try {
Result result = Uninterruptibles.getUninterruptibly(future);
storeInCache(result);
} catch (ExecutionException e) {
reportError(e.getCause());
} catch (RuntimeException e) {
// just in case
}
}
}, executor);
Futures.addCallback(future, new FutureCallback<Result>() {
public void onSuccess(Result result) {
storeInCache(result);
}
public void onFailure(Throwable t) {
reportError(t);
}
});
08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

94
Concurrent
ListenableFuture – Brique élémentaire
public final class Futures {
ListenableFuture<O> transform(ListenableFuture<I>,
Function<I, O>)
ListenableFuture<O> chain(ListenableFuture<I>,
Function<I, ListenableFuture<O>>)
ListenableFuture<List<V>> allAsList(List<ListenableFuture<V>>)
ListenableFuture<List<V>> successfullAsList(List<ListenableFuture<V>>)
// ...
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

95
Concurrent
ListenableFuture – Obtention
ListenableFuture<V> future = JdkFutureAdapters.listenInPoolThread(f);

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

96
Concurrent
ListenableFuture – Obtention
ListenableFuture<V> future = JdkFutureAdapters.listenInPoolThread(f);

Peu performant, car bloque un Thread qui va « attendre » que le Future se
termine pour appeler les listeners.
Mieux vaut créer des ListenableFuture directement, au lieu de simples Future.

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

97
Concurrent
ListenableFuture – Obtention
ListenableFuture<V> future = JdkFutureAdapters.listenInPoolThread(f);
public class ImdbService {
private ImdbWebService imdbWebService;
private ListeningExecutorService executor;
@Inject
ImdbService(ImdbWebService imdbWs, ExecutorService executor) {
this.imdbWebService = imdbWs;
this.executor = MoreExecutors.listeningDecorator(executor);
}
public ListenableFuture<Note> getNote(final Film film) {
return executor.submit(new Callable<Note>() {
public Note call() {
return imdbWebService.getNote(film);
}
});
}
}
08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

98
Concurrent
ListenableFuture – Quand ?

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

99
Concurrent
ListenableFuture – Quand ?

Toujours.
●

Nécessaire pour la plupart des méthodes utilitaires de Futures

●

Évite de devoir changer l'API plus tard

●

Permet aux clients de vos services de faire de la programmation asynchrone

●

Coût en performance négligeable

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

100
Concurrent
ListenableFuture – Exemple
ListenableFuture<List<Note>> getNotes(Film film) {
ListenableFuture<Note> noteImdb = imdbService.getNote(film);
ListenableFuture<Note> noteAllo = allocineService.getNote(film);
return Futures.allAsList(noteImdb, noteAllo);
}

On retourne un Future au lieu de bloquer pour renvoyer une List<Note>.
Permet au client de getNotes() d'exécuter d'autres actions en parallèle.

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

101
Conclusion
Effective Guava

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

102
Bibliographie / liens
Guava
–

http://code.google.com/p/guava-libraries/

Tuto Google-Collections (dvp)
–

http://thierry-lerichedessirier.developpez.com/tutoriels/java/tutogoogle-collections/

Comparaison d’API Java de programmation
fonctionnelle (Xebia)
–

http://blog.xebia.fr/2011/06/29/comparaison-dapijava-de-programmation-fonctionnelle/

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

103
Bibliographie / liens
Guava: faire du fonctionnel (Touilleur)
–

http://www.touilleur-express.fr/2010/11/03/googleguava-faire-du-fonctionnel/

Chez Thierry
–

http://www.thierryler.com/

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

104
Questions /
Réponses

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique
Sponsors

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

106
Merci de
votre
attention!

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique
Licence

http://creativecommons.org/licenses/by-nc-sa/2.0/fr/

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

108
Functional Programming
Filtre en chaine avec FluentIterable ?
Predicate malePredicate = new Predicate<Dog>() {
public boolean apply(Dog dog) {
return dog.getSex() == MALE;
}};

Milou
Idefix
Rintintin
Medor

Predicate eLetterPredicate = new Predicate<Dog>() {
public boolean apply(Dog dog) {
return dog.getName().contains("e");
}};

Idefix
Lassie
Medor

FluentIterable.with(dogs)
.filter(malePredicate)
.filter(eLetterPredicate)

Guava 11-12 ?

08/11/2011

Guava by Google

Idefix
Medor

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

109
Functional Programming
Ensembles...
Set<Dog> dogSet = newHashSet(dogs);

Milou
Idefix
Lassie
Rintintin
Lady
Medor

Set<Dog> superDogSet = newTreeSet(superDogs);

Milou
Lassie
Volt

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

110
Functional Programming
Ensembles...

Milou
Idefix
Lassie
Rintintin
Lady
Medor

Milou
Lassie
Volt

Sets.SetView<Dog> difference
= Sets.difference(dogSet, superDogSet);

Idefix
Medor
Rintintin
Lady

Sets.SetView<Dog> intersection
= Sets.intersection(dogSet, superDogSet);

Lassie
Milou

Sets.SetView<Dog> union
= Sets.union(dogSet, superDogSet);

Milou
Lady
Lassie
Idefix

08/11/2011

Guava by Google

Rintintin
Medor
Volt

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

111
Partition / limit
Avec 4 chiens
import static com.google.common.collect.Lists.partition;

List<List<Dog>> partitions = partition(dogs, 4);

Milou
Idefix
Lassie
Rintintin

Laidy
Medor

import static com.google.common.collect.Iterables.limit;

List<Dog> subList = newArrayList(limit(dogs, 4));

Milou
Idefix
Lassie
Rintintin
08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

112
Ordering
Classement des chiens
dogs = newArrayList(
new Dog("Milou",
new Dog("Idefix",
new Dog("Lassie",
new Dog("Rintintin",
new Dog("Lady",
new Dog("Medor",

08/11/2011

MALE,
MALE,
FEMALE,
MALE,
FEMALE,
MALE,

6.0),
4.8),
23.5),
12.4),
7.8),
26.2));

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

113
Ordering
Classement des chiens
dogs = newArrayList(
new Dog("Milou",
new Dog("Idefix",
new Dog("Lassie",
new Dog("Rintintin",
new Dog("Lady",
new Dog("Medor",

MALE,
MALE,
FEMALE,
MALE,
FEMALE,
MALE,

6.0),
4.8),
23.5),
12.4),
7.8),
26.2));

Ordering<Dog> weightOrdering = new Ordering<Dog>() {
public int compare(Dog left, Dog right) {
return left.getWeight().compareTo(right.getWeight());
}};

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

114
Ordering
Classement des chiens
dogs = newArrayList(
new Dog("Milou",
new Dog("Idefix",
new Dog("Lassie",
new Dog("Rintintin",
new Dog("Lady",
new Dog("Medor",

MALE,
MALE,
FEMALE,
MALE,
FEMALE,
MALE,

6.0),
4.8),
23.5),
12.4),
7.8),
26.2));

Ordering<Dog> weightOrdering = new Ordering<Dog>() {
public int compare(Dog left, Dog right) {
return left.getWeight().compareTo(right.getWeight());
}};
List<Dog> orderedDogs = weightOrdering
.nullsLast()
.sortedCopy(dogs);

08/11/2011

Guava by Google

Idefix
Milou
Lady
Rintintin
Lassie
Medor

(4.8)
(6.0)
(7.8)
(12.4)
(23.5)
(26.2)

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

115
Ordering
Classement des chiens
Ordering<Dog> weightOrdering = new Ordering<Dog>() {
public int compare(Dog left, Dog right) {
return left.getWeight().compareTo(right.getWeight());
}
}

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

116
Ordering
Classement des chiens
Ordering<Dog> weightOrdering = new Ordering<Dog>() {
public int compare(Dog left, Dog right) {
return left.getWeight().compareTo(right.getWeight());
}
}

Dog biggestDog = weightOrdering.max(dogs);

Medor

Dog smallestDog = weightOrdering.min(dogs);

Idefix

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

117
Immutables
Map
public static final ImmutableMap<String, Integer> AGES
= ImmutableMap.of("Jean", 32,
"Paul", 12,
"Lucie", 37,
"Marie", 17);

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

118
Immutables
Map
public static final ImmutableMap<String, Integer> AGES
= ImmutableMap.of("Jean", 32,
"Paul", 12,
"Lucie", 37,
"Marie", 17);

public static final ImmutableMap<String, Integer> AGES
= new ImmutableMap.Builder<String, Integer>()
.put("Jean", 32)
.put("Paul", 12)
.put("Lucie", 37)
.put("Marie", 17)
.put("Bernard", 17)
.put("Toto", 17)
.put("Loulou", 17)
.build();

08/11/2011

Guava by Google

www.parisjug.org

Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique

119

Weitere ähnliche Inhalte

Ähnlich wie Guava au Paris JUG

Adding 1.21 Gigawatts to Applications with RabbitMQ (DPC 2015)
Adding 1.21 Gigawatts to Applications with RabbitMQ (DPC 2015)Adding 1.21 Gigawatts to Applications with RabbitMQ (DPC 2015)
Adding 1.21 Gigawatts to Applications with RabbitMQ (DPC 2015)James Titcumb
 
Keeping Up with Java: Look at All These New Features!
Keeping Up with Java: Look at All These New Features!Keeping Up with Java: Look at All These New Features!
Keeping Up with Java: Look at All These New Features!VMware Tanzu
 
Massively Parallel Processing with Procedural Python by Ronert Obst PyData Be...
Massively Parallel Processing with Procedural Python by Ronert Obst PyData Be...Massively Parallel Processing with Procedural Python by Ronert Obst PyData Be...
Massively Parallel Processing with Procedural Python by Ronert Obst PyData Be...PyData
 
ONLINE IMAGE PROCESSING WITH ORFEOTOOLBOX WPS
ONLINE IMAGE PROCESSING WITH ORFEOTOOLBOX WPSONLINE IMAGE PROCESSING WITH ORFEOTOOLBOX WPS
ONLINE IMAGE PROCESSING WITH ORFEOTOOLBOX WPSotb
 
Java 8 ​and ​Best Practices
 Java 8 ​and ​Best Practices Java 8 ​and ​Best Practices
Java 8 ​and ​Best PracticesWSO2
 
Java9 Beyond Modularity - Java 9 más allá de la modularidad
Java9 Beyond Modularity - Java 9 más allá de la modularidadJava9 Beyond Modularity - Java 9 más allá de la modularidad
Java9 Beyond Modularity - Java 9 más allá de la modularidadDavid Gómez García
 
OpenIO: Objet Storage and Grid for Apps
OpenIO: Objet Storage and Grid for AppsOpenIO: Objet Storage and Grid for Apps
OpenIO: Objet Storage and Grid for AppsOW2
 
What is new in Python 3.9
What is new in Python 3.9What is new in Python 3.9
What is new in Python 3.9Haim Michael
 
Perl 6 For Mere Mortals
Perl 6 For Mere MortalsPerl 6 For Mere Mortals
Perl 6 For Mere MortalsCurtis Poe
 
Whats New For Developers In JDK 9
Whats New For Developers In JDK 9Whats New For Developers In JDK 9
Whats New For Developers In JDK 9Simon Ritter
 
DIY in 5 Minutes: Testing Django App with Pytest
DIY in 5 Minutes: Testing Django App with Pytest DIY in 5 Minutes: Testing Django App with Pytest
DIY in 5 Minutes: Testing Django App with Pytest Inexture Solutions
 
What is new in PHP
What is new in PHPWhat is new in PHP
What is new in PHPHaim Michael
 
Mastering the Sling Rewriter by Justin Edelson
Mastering the Sling Rewriter by Justin EdelsonMastering the Sling Rewriter by Justin Edelson
Mastering the Sling Rewriter by Justin EdelsonAEM HUB
 
Mastering the Sling Rewriter
Mastering the Sling RewriterMastering the Sling Rewriter
Mastering the Sling RewriterJustin Edelson
 
Who's afraid of ML -V2- Hello MLKit
Who's afraid of ML -V2- Hello MLKitWho's afraid of ML -V2- Hello MLKit
Who's afraid of ML -V2- Hello MLKitBritt Barak (HIRING)
 

Ähnlich wie Guava au Paris JUG (20)

Adding 1.21 Gigawatts to Applications with RabbitMQ (DPC 2015)
Adding 1.21 Gigawatts to Applications with RabbitMQ (DPC 2015)Adding 1.21 Gigawatts to Applications with RabbitMQ (DPC 2015)
Adding 1.21 Gigawatts to Applications with RabbitMQ (DPC 2015)
 
Java after 8
Java after 8Java after 8
Java after 8
 
Keeping Up with Java: Look at All These New Features!
Keeping Up with Java: Look at All These New Features!Keeping Up with Java: Look at All These New Features!
Keeping Up with Java: Look at All These New Features!
 
Massively Parallel Processing with Procedural Python by Ronert Obst PyData Be...
Massively Parallel Processing with Procedural Python by Ronert Obst PyData Be...Massively Parallel Processing with Procedural Python by Ronert Obst PyData Be...
Massively Parallel Processing with Procedural Python by Ronert Obst PyData Be...
 
ONLINE IMAGE PROCESSING WITH ORFEOTOOLBOX WPS
ONLINE IMAGE PROCESSING WITH ORFEOTOOLBOX WPSONLINE IMAGE PROCESSING WITH ORFEOTOOLBOX WPS
ONLINE IMAGE PROCESSING WITH ORFEOTOOLBOX WPS
 
Java 8 ​and ​Best Practices
Java 8 ​and ​Best PracticesJava 8 ​and ​Best Practices
Java 8 ​and ​Best Practices
 
Java 8 ​and ​Best Practices
 Java 8 ​and ​Best Practices Java 8 ​and ​Best Practices
Java 8 ​and ​Best Practices
 
Java 8 ​and ​Best Practices
Java 8 ​and ​Best PracticesJava 8 ​and ​Best Practices
Java 8 ​and ​Best Practices
 
Java9 Beyond Modularity - Java 9 más allá de la modularidad
Java9 Beyond Modularity - Java 9 más allá de la modularidadJava9 Beyond Modularity - Java 9 más allá de la modularidad
Java9 Beyond Modularity - Java 9 más allá de la modularidad
 
OpenIO: Objet Storage and Grid for Apps
OpenIO: Objet Storage and Grid for AppsOpenIO: Objet Storage and Grid for Apps
OpenIO: Objet Storage and Grid for Apps
 
What is new in Python 3.9
What is new in Python 3.9What is new in Python 3.9
What is new in Python 3.9
 
Perl 6 For Mere Mortals
Perl 6 For Mere MortalsPerl 6 For Mere Mortals
Perl 6 For Mere Mortals
 
Whats New For Developers In JDK 9
Whats New For Developers In JDK 9Whats New For Developers In JDK 9
Whats New For Developers In JDK 9
 
Python and Sage
Python and SagePython and Sage
Python and Sage
 
What is new in JUnit5
What is new in JUnit5What is new in JUnit5
What is new in JUnit5
 
DIY in 5 Minutes: Testing Django App with Pytest
DIY in 5 Minutes: Testing Django App with Pytest DIY in 5 Minutes: Testing Django App with Pytest
DIY in 5 Minutes: Testing Django App with Pytest
 
What is new in PHP
What is new in PHPWhat is new in PHP
What is new in PHP
 
Mastering the Sling Rewriter by Justin Edelson
Mastering the Sling Rewriter by Justin EdelsonMastering the Sling Rewriter by Justin Edelson
Mastering the Sling Rewriter by Justin Edelson
 
Mastering the Sling Rewriter
Mastering the Sling RewriterMastering the Sling Rewriter
Mastering the Sling Rewriter
 
Who's afraid of ML -V2- Hello MLKit
Who's afraid of ML -V2- Hello MLKitWho's afraid of ML -V2- Hello MLKit
Who's afraid of ML -V2- Hello MLKit
 

Mehr von Thierry Leriche-Dessirier

Rapport de test DISC de Groupe (Laurent Duval)
Rapport de test DISC de Groupe (Laurent Duval)Rapport de test DISC de Groupe (Laurent Duval)
Rapport de test DISC de Groupe (Laurent Duval)Thierry Leriche-Dessirier
 
Management en couleur avec DISC à Agile Tour Paris 2015
Management en couleur avec DISC à Agile Tour Paris 2015Management en couleur avec DISC à Agile Tour Paris 2015
Management en couleur avec DISC à Agile Tour Paris 2015Thierry Leriche-Dessirier
 

Mehr von Thierry Leriche-Dessirier (20)

Disc l'essentiel
Disc l'essentielDisc l'essentiel
Disc l'essentiel
 
Rapport DISC Pro de Lucie Durand
Rapport DISC Pro de Lucie DurandRapport DISC Pro de Lucie Durand
Rapport DISC Pro de Lucie Durand
 
Rapport de test DISC de Groupe (Laurent Duval)
Rapport de test DISC de Groupe (Laurent Duval)Rapport de test DISC de Groupe (Laurent Duval)
Rapport de test DISC de Groupe (Laurent Duval)
 
Memento DISC Influent (English)
Memento DISC Influent (English)Memento DISC Influent (English)
Memento DISC Influent (English)
 
Le management en couleurs avec le DISC
Le management en couleurs avec le DISCLe management en couleurs avec le DISC
Le management en couleurs avec le DISC
 
Memento DISC Stable
Memento DISC StableMemento DISC Stable
Memento DISC Stable
 
Memento DISC Influent
Memento DISC InfluentMemento DISC Influent
Memento DISC Influent
 
Memento DISC Dominant
Memento DISC DominantMemento DISC Dominant
Memento DISC Dominant
 
Memento Disc Consciencieux
Memento Disc ConsciencieuxMemento Disc Consciencieux
Memento Disc Consciencieux
 
Management en couleur avec DISC à Agile Tour Paris 2015
Management en couleur avec DISC à Agile Tour Paris 2015Management en couleur avec DISC à Agile Tour Paris 2015
Management en couleur avec DISC à Agile Tour Paris 2015
 
Management en couleur avec DISC
Management en couleur avec DISCManagement en couleur avec DISC
Management en couleur avec DISC
 
Les algorithmes de tri
Les algorithmes de triLes algorithmes de tri
Les algorithmes de tri
 
Cours de Génie Logiciel / ESIEA 2016-17
Cours de Génie Logiciel / ESIEA 2016-17Cours de Génie Logiciel / ESIEA 2016-17
Cours de Génie Logiciel / ESIEA 2016-17
 
Puzzle 2 (4x4)
Puzzle 2 (4x4)Puzzle 2 (4x4)
Puzzle 2 (4x4)
 
Guava et Lombok au Normandy JUG
Guava et Lombok au Normandy JUGGuava et Lombok au Normandy JUG
Guava et Lombok au Normandy JUG
 
Guava et Lombok au Lyon JUG
Guava et Lombok au Lyon JUGGuava et Lombok au Lyon JUG
Guava et Lombok au Lyon JUG
 
Guava et Lombok au Lorraine JUG
Guava et Lombok au Lorraine JUGGuava et Lombok au Lorraine JUG
Guava et Lombok au Lorraine JUG
 
Guava et Lombok au Brezth JUG
Guava et Lombok au Brezth JUGGuava et Lombok au Brezth JUG
Guava et Lombok au Brezth JUG
 
Memento scrum-equipe
Memento scrum-equipeMemento scrum-equipe
Memento scrum-equipe
 
Memento java
Memento javaMemento java
Memento java
 

Kürzlich hochgeladen

"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
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
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
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
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
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
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfSeasiaInfotech2
 
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
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 

Kürzlich hochgeladen (20)

"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
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
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
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
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
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
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdf
 
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
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 

Guava au Paris JUG

  • 1. 08/11/2011 Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique
  • 2. 08/11/2011 Guava by Google Thierry Leriche Consultant freelance ICAUDA Etienne Neveu Consultant SFEIR Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique
  • 3. « Pourquoi aimons-nous tant Google Guava ? » 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 3
  • 4. Factory Methods 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 4
  • 5. Factory Methods Avec Java 5 List<Integer> primeNumbers = new ArrayList<Integer>(); Set<String> colors = new TreeSet<String>(); Map<String, Integer> ages = new HashMap<String, Integer>(); 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 5
  • 6. Factory Methods Avec Java 5 List<Integer> primeNumbers = new ArrayList<Integer>(); Set<String> colors = new TreeSet<String>(); Map<String, Integer> ages = new HashMap<String, Integer>(); ou même... Map<String, List<String>> favoriteColors = new HashMap<String, List<String>>(); Map<? extends Person, Map<String, List<String>>> favoriteColors = new TreeMap<? Extends Person, Map<String, List<String>>>(); on peut facilement trouver pire... 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 6
  • 7. Factory Methods Avec Java 5 List<Integer> primeNumbers = new ArrayList<Integer>(); Set<String> colors = new TreeSet<String>(); Map<String, Integer> ages = new HashMap<String, Integer>(); Avec Java 7 List<Integer> primeNumbers = new ArrayList<>(); Set<String> colors = new TreeSet<>(); Map<String, Integer> ages = new HashMap<>(); mais quand ? 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 7
  • 8. Factory Methods Avec Java 5 List<Integer> primeNumbers = new ArrayList<Integer>(); Set<String> colors = new TreeSet<String>(); Map<String, Integer> ages = new HashMap<String, Integer>(); Avec Java 7 List<Integer> primeNumbers = new ArrayList<>(); Set<String> colors = new TreeSet<>(); Map<String, Integer> ages = new HashMap<>(); Avec Guava List<Integer> primeNumbers = newArrayList(); Set<String> colors = newTreeSet(); Map<String, Integer> ages = newHashMap(); tout de suite 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 8
  • 9. Factory Methods Par exemple, avec des chiens public class Dog { private String name; private Double weight; private Sex sex; public Dog(String name, Sex sex) { this.name = name ; this.sex = sex; } // getters & setters } public enum Sex { MALE, FEMALE } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 9
  • 10. Factory Methods Par exemple, avec des chiens List<Dog> dogs = newArrayList(); dogs.add(new Dog("Milou", MALE)); dogs.add(new Dog("Idefix", MALE)); dogs.add(new Dog("Lassie", FEMALE)); dogs.add(new Dog("Rintintin", MALE)); dogs.add(new Dog("Lady", FEMALE)); dogs.add(new Dog("Medor", MALE)); 08/11/2011 Guava by Google Milou Idefix Lassie Rintintin Lady Medor www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 10
  • 11. Factory Methods Ou plutôt List<Dog> dogs = newArrayList( new Dog("Milou", MALE), new Dog("Idefix", MALE), new Dog("Lassie", FEMALE), new Dog("Rintintin", MALE), new Dog("Lady", FEMALE), new Dog("Medor", MALE) ); 08/11/2011 Guava by Google Milou Idefix Lassie Rintintin Lady Medor www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 11
  • 12. Functional Programming 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 12
  • 13. Functional Programming Filtre avec Predicate Iterable<Dog> maleDogs = Iterables.filter(dogs, new Predicate<Dog>() { public boolean apply(Dog dog) { return dog.getSex() == MALE; } }); Milou Idefix prog fonc ? Rintintin Medor 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 13
  • 14. Functional Programming And, or, in, not, ... List<Dog> superDogs = newArrayList( new Dog("Milou", MALE), new Dog("Lassie", FEMALE), new Dog("Volt", MALE)); 08/11/2011 Guava by Google Milou Lassie Volt Milou Idefix Lassie Rintintin Lady Medor www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 14
  • 15. Functional Programming And, or, in, not, ... List<Dog> superDogs = newArrayList( new Dog("Milou", MALE), new Dog("Lassie", FEMALE), new Dog("Volt", MALE)); boolean isMilouInBoth = and(in(dogs), in(superDogs)) .apply(new Dog("Milou")); boolean isTintinInOne = or(in(dogs), in(superDogs)) .apply(new Dog("Tintin")); 08/11/2011 Guava by Google Milou Lassie Volt Milou Idefix Lassie Rintintin Lady Medor true false www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 15
  • 16. Functional Programming Un chien en français public class Chien { private String prenom; public Chien(String prenom) { this.prenom = prenom; } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 16
  • 17. Functional Programming Transformation List<Chien> chiens = Lists.transform(dogs, new Function<Dog, Chien>() { public Chien apply(Dog dog) { return new Chien(dog.getName()); } }); 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 17
  • 18. Functional Programming Attention : vue List<Chien> chiens = Lists.transform(dogs, new Function<Dog, Chien>() { public Chien apply(Dog dog) { return new Chien(dog.getName()); } }); – Vue (lazy) – size / isEmpty dispo – Pas fait pour des traitements multiples List<Chien> chiens = newArrayList(Lists.transform(... ImmutableList<Chien> chiens = ImmutableList.copyOf(Lists.transform(... 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 18
  • 19. Functional Programming Converter Spring import org.springframework...Converter; @Component("dogToChienConverter") public class DogToChienConverter implements Converter<List<Dog>, List<Chien>> { public List<Chien> convert(List<Dog> dogs) { List<Chien> chiens = newArrayList(Lists.transform(dogs, new Function<Dog, Chien>() { public Chien apply(Dog dog) { return new Chien(dog.getName()); } })); } return chiens; Lazy or not lazy ? 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 19
  • 20. Functional Programming Find Predicate<Dog> malePredicate = new Predicate<Dog>() { public boolean apply(Dog dog) { return dog.getSex() == MALE; }}; Dog firstMale = Iterables.find(dogs, malePredicate); Milou 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 20
  • 21. Functional Programming Find Predicate<Dog> malePredicate = new Predicate<Dog>() { public boolean apply(Dog dog) { return dog.getSex() == MALE; }}; Dog firstMale = Iterables.find(dogs, malePredicate); Milou Dog firstMale = Iterables.find(femaleDogs, malePredicate, DEFAULT_DOG ); Chien par défaut 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 21
  • 22. Immutable Collections 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 22
  • 23. Immutable Collections Set (en Java) Set<Integer> temp = new LinkedHashSet<Integer>( Arrays.asList(1, 2, 3, 5, 7)); Set<Integer> primeNumbers = Collections.unmodifiableSet(temp); 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 23
  • 24. Immutable Collections Set (en Java) Vs ImmutableSet (Guava) Set<Integer> temp = new LinkedHashSet<Integer>( Arrays.asList(1, 2, 3, 5, 7)); Set<Integer> primeNumbers = Collections.unmodifiableSet(temp); Guava Set<Integer> primeNumbers = ImmutableSet.of(1, 2, 3, 5, 7); 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 24
  • 25. Immutable Collections Multi « of » ImmutableSet.of(E ImmutableSet.of(E ImmutableSet.of(E ImmutableSet.of(E ImmutableSet.of(E ImmutableSet.of(E e1) e1, e1, e1, e1, e1, E E E E E e2) e2, e2, e2, e2, E E E E e3) e3, E e4) e3, E e4, E e5) e3, E e4, E e5, E e6, E...) n'accepte pas les éléments null 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 25
  • 26. Immutable Collections Multi « of » ImmutableSet.of(E ImmutableSet.of(E ImmutableSet.of(E ImmutableSet.of(E ImmutableSet.of(E ImmutableSet.of(E e1) e1, e1, e1, e1, e1, E E E E E e2) e2, e2, e2, e2, E E E E e3) e3, E e4) e3, E e4, E e5) e3, E e4, E e5, E e6, E...) n'accepte pas les éléments null ImmutableSet.of() 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 26
  • 27. Immutable Collections Copie de défense (en java) public class Person { private final Set<String> favoriteColors; private final String firstName; public Person(Set<String> favoriteColors, String firstName) { this.favoriteColors = Collections.unmodifiableSet( new LinkedHashSet<String>(favoriteColors)); this.firstName = firstName; } public Set<String> getFavoriteColors() { return favoriteColors; } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 27
  • 28. Immutable Collections Copie de défense (Guava) public class Person { private final ImmutableSet<String> favoriteColors; private final String firstName; public Person(Set<String> favoriteColors, String firstName) { this.favoriteColors = ImmutableSet.copyOf(favoriteColors)); } this.firstName = firstName; public ImmutableSet<String> getFavoriteColors() { return favoriteColors; } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 28
  • 29. Base – Objects 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 29
  • 30. Base – Objects Le retour du chien public class Dog { private String name; private Double weight; private Sex sex; public Dog(String name, Sex sex) { this.name = name ; this.sex = sex; } // getters & setters } public enum Sex { MALE, FEMALE } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 30
  • 31. Base – Objects Objects.equal() public boolean equals(Object other) { if (!(other instanceof Dog)) return false; Dog that = (Dog) other; } return (name == that.name || (name != null && name.equals(that.name))) && (weight == that.weight || (weight != null && weight.equals(that.weight))) && sex == that.sex; 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 31
  • 32. Base – Objects Objects.equal() public boolean equals(Object other) { if (!(other instanceof Dog)) return false; Dog that = (Dog) other; } return Objects.equal(name, that.name) && Objects.equal(weight, that.weight) && sex == that.sex; 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 32
  • 33. Base – Objects Objects.hashCode() public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + (weight != null ? weight.hashCode():0); result = 31 * result + (sex != null ? sex.hashCode():0); } return result; 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 33
  • 34. Base – Objects Objects.hashCode() public int hashCode() { } return Objects.hashCode(name, weight, sex); 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 34
  • 35. Base – Objects Objects.toStringHelper() public String toString() { StringBuilder sb = new StringBuilder(); sb.append(Dog.class.getSimpleName()); sb.append("{name=").append(name); sb.append(", weight=").append(weight); sb.append(", sex=").append(sex); sb.append('}'); return sb.toString(); } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 35
  • 36. Base – Objects Objects.toStringHelper() public String toString() { } return Objects.toStringHelper(this) .add("name", name) .add("weight", weight) .add("sex", sex) .toString(); 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 36
  • 37. Base – Objects ComparisonChain public int compareTo(Dog other) { int result = name.compareTo(other.name); if (result != 0) { return result; } result = weight.compareTo(other.weight); if (result != 0) { return result; } } return sex.compareTo(other.sex); 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 37
  • 38. Base – Objects ComparisonChain public int compareTo(Dog other) { } return ComparisonChain.start() .compare(name, other.name) .compare(weight, other.weight) .compare(sex, other.sex) .result(); 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 38
  • 39. Base – Objects ComparisonChain public int compareTo(Dog other) { } return ComparisonChain.start() .compare(name, other.name, NULL_LAST_COMPARATOR) .compare(weight, other.weight, NULL_LAST_COMPARATOR) .compare(sex, other.sex, NULL_LAST_COMPARATOR) .result(); 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 39
  • 40. Base – Preconditions 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 40
  • 41. Base – Preconditions Money money money @Immutable public class Money { @Nonnull private final BigDecimal amount; @Nonnull private final Currency currency; public Money(BigDecimal amount, Currency currency) { // ??? } } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 41
  • 42. Base – Preconditions Validation classique des arguments public Money(BigDecimal amount, Currency currency) { if (amount == null) { throw new NullPointerException("amount cannot be null"); } if (currency == null) { throw new NullPointerException("currency cannot be null"); } if (amount.signum() < 0) { throw new IllegalArgumentException("must be positive: " + amount); } } this.amount = amount; this.currency = currency; 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 42
  • 43. Base – Preconditions Validation avec Preconditions import static com.google.common.base.Preconditions.*; public Money(BigDecimal amount, Currency currency) { checkNotNull(amount, "amount cannot be null"); checkNotNull(currency, "currency cannot be null"); checkArgument(amount.signum() >= 0, "must be positive: %s", amount); } this.amount = amount; this.currency = currency; 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 43
  • 44. Base – Preconditions Validation et assignement inline import static com.google.common.base.Preconditions.*; public Money(BigDecimal amount, Currency currency) { this.amount = checkNotNull(amount, "amount cannot be null"); this.currency = checkNotNull(currency, "currency cannot be null"); checkArgument(amount.signum() >= 0, "must be positive: %s", amount); } public static <T> T checkNotNull(T reference) { if (reference == null) { throw new NullPointerException(); } return reference; } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 44
  • 45. Base – CharMatcher 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 45
  • 46. Base – CharMatcher StringUtils ? String collapse(String source, String charsToCollapse) String collapseWhitespace(String source) String collapseControlChars(String source) int int lastIndexOf(String source, String chars) lastIndexNotOf(String source, String chars) String String String String remove(String source, String charsToRemove) removeDigits(String source) removeWhitespace(String source) removeControlChars(String source) String trim(String source, String charsToStrip) String trimWhiteSpace(String source) String trimControlChars(String source) 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 46
  • 47. Base – CharMatcher StringUtils → CharMatcher String collapse(String source, String charsToCollapse) String collapseWhitespace(String source) String collapseControlChars(String source) int int lastIndexOf(String source, String chars) lastIndexNotOf(String source, String chars) String String String String remove(String source, String charsToRemove) removeDigits(String source) removeWhitespace(String source) removeControlChars(String source) String trim(String source, String charsToStrip) String trimWhiteSpace(String source) String trimControlChars(String source) public abstract class CharMatcher { public boolean matches(char c); } // ... 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 47
  • 48. Base – CharMatcher Obtention d'un CharMatcher CharMatcher.ANY CharMatcher.NONE CharMatcher.ASCII CharMatcher.DIGIT CharMatcher.WHITESPACE CharMatcher.JAVA_ISO_CONTROL CharMatcher.is('x') CharMatcher.isNot('_') CharMatcher.anyOf('aeiou').negate() CharMatcher.inRange('a', 'z').or(CharMatcher.inRange('A', 'Z')) 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 48
  • 49. Base – CharMatcher Utilisation d'un CharMatcher boolean matchesAllOf(CharSequence) boolean matchesAnyOf(CharSequence) boolean matchesNoneOf(CharSequence) int indexIn(CharSequence, int) int lastIndexIn(CharSequence, int) int countIn(CharSequence) String removeFrom(CharSequence) String retainFrom(CharSequence) String trimFrom(CharSequence) String trimLeadingFrom(CharSequence) String trimTrailingFrom(CharSequence) String collapseFrom(CharSequence, char) String trimAndCollapseFrom(CharSequence, char) String replaceFrom(CharSequence, char) 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 49
  • 50. Base – CharMatcher Utilisation d'un CharMatcher boolean matchesAllOf(CharSequence) boolean matchesAnyOf(CharSequence) boolean matchesNoneOf(CharSequence) int indexIn(CharSequence, int) int lastIndexIn(CharSequence, int) int countIn(CharSequence) String removeFrom(CharSequence) String retainFrom(CharSequence) String trimFrom(CharSequence) String trimLeadingFrom(CharSequence) String trimTrailingFrom(CharSequence) String collapseFrom(CharSequence, char) String trimAndCollapseFrom(CharSequence, char) String replaceFrom(CharSequence, char) CharMatcher VALID_CHARS = CharMatcher.DIGIT.or(CharMatcher.anyOf(“-_”); String VALID_CHARS.retainFrom(input); checkArgument(!CharMatcher.WHITESPACE.matchesAllOf(input)); 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 50
  • 51. Collection Utilities 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 51
  • 52. Collection Utilities Multimap (avec Java) Map<String, List<String>> favoriteColors = new HashMap<String, List<String>>(); List<String> julienColors = favoriteColors.get("Julien"); if(julienColors == null) { julienColors = new ArrayList<String>(); favoriteColors.put("Julien",julienColors); } julienColors.add("Vert"); 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 52
  • 53. Collection Utilities Multimap (avec Guava) Map<String, List<String>> favoriteColors = new HashMap<String, List<String>>(); Multimap<String, String> favoriteColors = HashMultimap.create(); favoriteColors2.put("Julien", "Jaune"); favoriteColors2.put("Julien", "Rouge"); 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 53
  • 54. Collection Utilities Bimap (Clé-Valeur-Clé) BiMap<String, String> cars = HashBiMap.create(); cars.put("Thierry", "1234 AB 91"); cars.put("Marie", "4369 ERD 75"); cars.put("Julien", "549 DF 87"); {Thierry=1234 AB 91, Julien=549 DF 87, Marie=4369 ERD 75} println(cars); println(cars.inverse()); Une map bijective {1234 AB 91=Thierry, 549 DF 87=Julien, 4369 ERD 75=Marie} Il est possible de changer la valeur associée à une clé mais pas d'avoir deux clés avec la même valeur (IllegalArgumentException). 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 54
  • 55. Collection Utilities Multiset Multiset<Integer> primeNumbers = HashMultiset.create(); primeNumbers.add(2); primeNumbers.add(3); primeNumbers.add(7); primeNumbers.add(11); primeNumbers.add(3); primeNumbers.add(5); println(primeNumbers); 08/11/2011 [2, 3 x 2, 5, 7, 11] Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 55
  • 56. Collection Utilities Multiset Multiset<Integer> primeNumbers = HashMultiset.create(); primeNumbers.add(2); primeNumbers.add(3); primeNumbers.add(7); primeNumbers.add(11); primeNumbers.add(3); primeNumbers.add(5); println(primeNumbers); println(premiers.count(3)) 08/11/2011 [2, 3 x 2, 5, 7, 11] 2 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 56
  • 57. Joiner / Splitter 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 57
  • 58. Joiner / Splitter Joiner List<String> dogs = newArrayList("Milou", "Idefix", "Rintintin"); String names = Joiner.on(", ").join(dogs); 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 58
  • 59. Joiner / Splitter Joiner List<String> dogs = newArrayList("Milou", "Idefix", "Rintintin"); String names = Joiner.on(", ").join(dogs); List<String> dogs = newArrayList("Milou", "Idefix", null, "Rintintin"); String names = Joiner.on(", ").join(dogs); NullPointerException 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 59
  • 60. Joiner / Splitter Joiner List<String> dogs = newArrayList("Milou", "Idefix", "Rintintin"); String names = Joiner.on(", ").join(dogs); List<String> dogs = newArrayList("Milou", "Idefix", null, "Rintintin"); String names = Joiner.on(", ").join(dogs); NullPointerException List<String> dogs = newArrayList("Milou", "Idefix", null, "Rintintin"); String names = Joiner.on(", ").skipNulls().join(dogs); Milou, Idefix, Rintintin 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 60
  • 61. Joiner / Splitter Joiner List<String> dogs = newArrayList("Milou", "Idefix", "Rintintin"); String names = Joiner.on(", ").join(dogs); List<String> dogs = newArrayList("Milou", "Idefix", null, "Rintintin"); String names = Joiner.on(", ").join(dogs); NullPointerException List<String> dogs = newArrayList("Milou", "Idefix", null, "Rintintin"); String names = Joiner.on(", ").skipNulls().join(dogs); Milou, Idefix, Rintintin List<String> dogs = newArrayList("Milou", "Idefix", null, "Rintintin"); String names = Joiner.on(", ").useForNull("Doggie").join(dogs); Milou, Idefix, Doggie, Rintintin 7 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 61
  • 62. Joiner / Splitter Splitter Iterable<String> superDogs = Splitter.on(",") .split("Lassie, Volt, Milou"); "Lassie" " Volt" " Milou" 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 62
  • 63. Joiner / Splitter Splitter Iterable<String> superDogs = Splitter.on(",") .split("Lassie, Volt, Milou"); Iterable<String> superDogs = Splitter.on(",") .split("Lassie, , Volt, Milou"); "Lassie" " " " Volt" " Milou" 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 63
  • 64. Joiner / Splitter Splitter Iterable<String> superDogs = Splitter.on(",") .split("Lassie, Volt, Milou"); Iterable<String> superDogs = Splitter.on(",") .split("Lassie, , Volt, Milou"); Iterable<String> superDogs = Splitter.on(",") .trimResults() .split("Lassie, , Volt, Milou"); "Lassie" "" "Volt" "Milou" 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 64
  • 65. Joiner / Splitter Splitter Iterable<String> superDogs = Splitter.on(",") .split("Lassie, Volt, Milou"); Iterable<String> superDogs = Splitter.on(",") .split("Lassie, , Volt, Milou"); Iterable<String> superDogs = Splitter.on(",") .trimResults() .split("Lassie, , Volt, Milou"); Iterable<String> superDogs = Splitter.on(",") .trimResults() .omitEmptyStrings() .split("Lassie, , Volt, Milou"); "Lassie" "Volt" "Milou" 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 65
  • 66. Cache – Memoization 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 66
  • 67. Cache – Memoization Exemple : service renvoyant la dernière version du JDK public class JdkService { @Inject private JdkWebService jdkWebService; public JdkVersion getLatestVersion() { return jdkWebService.checkLatestVersion(); } } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 67
  • 68. Cache – Memoization Cache manuel public class JdkService { @Inject private JdkWebService jdkWebService; public synchronized JdkVersion getLatestVersion() { if (versionCache == null) { versionCache = jdkWebService.checkLatestVersion(); } return versionCache; } private JdkVersion versionCache = null; } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 68
  • 69. Cache – Memoization Supplier public class JdkService { @Inject private JdkWebService jdkWebService; public synchronized JdkVersion getLatestVersion() { if (versionCache == null) { versionCache = jdkWebService.checkLatestVersion(); public interface Supplier<T> { } return versionCache; T get(); } } private JdkVersion versionCache = null; } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 69
  • 70. Cache – Memoization Supplier public class JdkService { @Inject private JdkWebService jdkWebService; public JdkVersion getLatestVersion() { return versionCache.get(); } private Supplier<JdkVersion> versionCache = Suppliers.memoize( new Supplier<JdkVersion>() { public JdkVersion get() { return jdkWebService.checkLatestVersion(); } } ); } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 70
  • 71. Cache – Memoization Suppliers.memoize() public class JdkService { @Inject private JdkWebService jdkWebService; public JdkVersion getLatestVersion() { return versionCache.get(); } private Supplier<JdkVersion> versionCache = Suppliers.memoize( new Supplier<JdkVersion>() { public JdkVersion get() { return jdkWebService.checkLatestVersion(); } } ); } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 71
  • 72. Cache – Memoization Suppliers.memoizeWithExpiration() public class JdkService { @Inject private JdkWebService jdkWebService; public JdkVersion getLatestVersion() { return versionCache.get(); } private Supplier<JdkVersion> versionCache = Suppliers.memoizeWithExpiration( new Supplier<JdkVersion>() { public JdkVersion get() { return jdkWebService.checkLatestVersion(); } }, 365, TimeUnit.DAYS ); } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 72
  • 73. Cache – Key-Value 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 73
  • 74. Cache – Key-Value Exemple public class FilmService { @Inject private ImdbWebService imdbWebService; public Film getFilm(Long filmId) { return imdbWebService.loadFilmInfos(filmId); } } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 74
  • 75. Cache – Key-Value Cache – Interface public interface Cache<K, V> extends Function<K, V> { V get(K key) throws ExecutionException; V getUnchecked(K key); void invalidate(Object key); void invalidateAll(); long size(); CacheStats stats(); ConcurrentMap<K, V> asMap(); } void cleanUp(); 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 75
  • 76. Cache – Key-Value CacheBuilder & CacheLoader public class FilmService { @Inject private FilmWebService imdbWebService; public Film getFilm(Long filmId) { return filmCache.getUnchecked(filmId); } private Cache<Long, Film> filmCache = CacheBuilder.newBuilder() .build(new CacheLoader<Long, Film>() { public Film load(Film filmId) { return imdbWebService.loadFilmInfos(filmId); } }); } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 76
  • 77. Cache – Key-Value Customisation du CacheBuilder public class FilmService { @Inject private FilmWebService imdbWebService; public Film getFilm(Long filmId) { return filmCache.getUnchecked(filmId); } private Cache<Long, Film> filmCache = CacheBuilder.newBuilder() .maximumSize(2000) .expireAfterWrite(30, TimeUnit.MINUTES) .build(new CacheLoader<Long, Film>() { public Film load(Long filmId) { return imdbWebService.loadFilmInfos(filmId); } }); } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 77
  • 78. I/O 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 78
  • 79. I/O Java 5 public static byte[] toByteArray(File file) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); boolean threw = true; InputStream in = new FileInputStream(file); try { byte[] buf = new byte[BUF_SIZE]; while (true) { int r = in.read(buf); if (r == -1) break; out.write(buf, 0, r); } threw = false; } finally { try { in.close(); } catch (IOException e) { if (threw) { logger.warn("IOException thrown while closing", e); } else { throw e; } } } return out.toByteArray(); } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 79
  • 80. I/O Java 7 – Automatic Resource Management (ARM) public static byte[] toByteArray(File file) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); try (InputStream in = new FileInputStream(file);) { byte[] buf = new byte[BUF_SIZE]; while (true) { int r = in.read(buf); if (r == -1) break; out.write(buf, 0, r); } } } return out.toByteArray(); 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 80
  • 81. I/O Guava public static byte[] toByteArray(File file) throws IOException { return Files.toByteArray(file) ; } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 81
  • 82. I/O InputSupplier & OutputSupplier interface InputSupplier<T> { interface OutputSupplier<T> { T getInput() throws IOException; } T getOutput() throws IOException; } InputSupplier<InputStream> OutputSupplier<OutputStream> InputSupplier<Reader> OutputSupplier<Writer> try { InputStream stream = new FileInputStream(file) ; } catch (IOException ioex) { throw Throwables.propagate(ioex); } InputSupplier<InputStream> stream = Files.newInputStreamSupplier(file); 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 82
  • 83. I/O ByteStreams byte[] toByteArray(InputStream) byte[] toByteArray(InputSupplier<InputStream>) T readBytes(InputSupplier<InputStream>, ByteProcessor<T>) void write(byte[], OutputSupplier<OutputStream>) long copy(InputStream, OutputStream) long copy(InputSupplier<InputStream>, OutputSupplier<OutputStream>) InputSupplier<InputStream> join(InputSupplier<InputStream>...) 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 83
  • 84. I/O CharStreams String toString(Readable) String toString(InputSupplier<Readable & Closeable>) T readLines(InputSupplier<Readable & Closeable>, LineProcessor<T>) void write(CharSequence, OutputSupplier<Appendable & Closeable>) long copy(Readable, Appendable) long copy(InputSupplier<Readable & Closeable>, OutputSupplier<Appendable & Closeable>) InputSupplier<Reader> join(InputSupplier<Reader>...) 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 84
  • 85. I/O Files byte[] toByteArray(File) String toString(File, Charset) List<String> readLines(File, Charset) void write(byte[], File) void write(CharSequence, File to, Charset) void copy(File from, File to) void copy(InputSupplier<...>, File) void copy(File, OutputSupplier<...>) void move(File, File) 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 85
  • 86. Concurrent 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 86
  • 87. Concurrent Future List<Note> getNotes(Film film) { Note noteImdb = imdbService.getNote(film); Note noteAllo = allocineService.getNote(film); return ImmutableList.of(noteImdb, noteAllo); } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 87
  • 88. Concurrent Future List<Note> getNotes(Film film) { Note noteImdb = imdbService.getNote(film); Note noteAllo = allocineService.getNote(film); return ImmutableList.of(noteImdb, noteAllo); } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 88
  • 89. Concurrent Future List<Note> getNotes(Film film) { Note noteImdb = imdbService.getNote(film); Note noteAllo = allocineService.getNote(film); return ImmutableList.of(noteImdb, noteAllo); } List<Note> getNotes(Film film) { Future<Note> noteImdb = imdbService.getNote(film); Future<Note> noteAllo = allocineService.getNote(film); return ImmutableList.of(noteImdb.get(), noteAllo.get()); } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 89
  • 90. Concurrent Future – Obtention public class ImdbService { private ImdbWebService imdbWebService; @Inject ImdbService(ImdbWebService imdbWs) { this.imdbWebService = imdbWs; } public Note getNote(Film film) { return imdbWebService.getNote(film); } } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 90
  • 91. Concurrent Future – Obtention public class ImdbService { private ImdbWebService imdbWebService; private ExecutorService executor; @Inject ImdbService(ImdbWebService imdbWs, ExecutorService executor) { this.imdbWebService = imdbWs; this.executor = executor; } public Future<Note> getNote(final Film film) { return executor.submit(new Callable<Note>() { public Note call() { return imdbWebService.getNote(film); } }); } } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 91
  • 92. Concurrent ListenableFuture public interface ListenableFuture<V> extends Future<V> { void addListener(Runnable listener, Executor executor); } ListenableFuture<Result> future = ... future.addListener(new Runnable() { public void run() { logger.debug("Future is done"); } }, executor); 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 92
  • 93. Concurrent ListenableFuture – Callbacks future.addListener(new Runnable() { public void run() { try { Result result = Uninterruptibles.getUninterruptibly(future); storeInCache(result); } catch (ExecutionException e) { reportError(e.getCause()); } catch (RuntimeException e) { // just in case } } }, executor); 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 93
  • 94. Concurrent ListenableFuture – Callbacks future.addListener(new Runnable() { public void run() { try { Result result = Uninterruptibles.getUninterruptibly(future); storeInCache(result); } catch (ExecutionException e) { reportError(e.getCause()); } catch (RuntimeException e) { // just in case } } }, executor); Futures.addCallback(future, new FutureCallback<Result>() { public void onSuccess(Result result) { storeInCache(result); } public void onFailure(Throwable t) { reportError(t); } }); 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 94
  • 95. Concurrent ListenableFuture – Brique élémentaire public final class Futures { ListenableFuture<O> transform(ListenableFuture<I>, Function<I, O>) ListenableFuture<O> chain(ListenableFuture<I>, Function<I, ListenableFuture<O>>) ListenableFuture<List<V>> allAsList(List<ListenableFuture<V>>) ListenableFuture<List<V>> successfullAsList(List<ListenableFuture<V>>) // ... } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 95
  • 96. Concurrent ListenableFuture – Obtention ListenableFuture<V> future = JdkFutureAdapters.listenInPoolThread(f); 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 96
  • 97. Concurrent ListenableFuture – Obtention ListenableFuture<V> future = JdkFutureAdapters.listenInPoolThread(f); Peu performant, car bloque un Thread qui va « attendre » que le Future se termine pour appeler les listeners. Mieux vaut créer des ListenableFuture directement, au lieu de simples Future. 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 97
  • 98. Concurrent ListenableFuture – Obtention ListenableFuture<V> future = JdkFutureAdapters.listenInPoolThread(f); public class ImdbService { private ImdbWebService imdbWebService; private ListeningExecutorService executor; @Inject ImdbService(ImdbWebService imdbWs, ExecutorService executor) { this.imdbWebService = imdbWs; this.executor = MoreExecutors.listeningDecorator(executor); } public ListenableFuture<Note> getNote(final Film film) { return executor.submit(new Callable<Note>() { public Note call() { return imdbWebService.getNote(film); } }); } } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 98
  • 99. Concurrent ListenableFuture – Quand ? 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 99
  • 100. Concurrent ListenableFuture – Quand ? Toujours. ● Nécessaire pour la plupart des méthodes utilitaires de Futures ● Évite de devoir changer l'API plus tard ● Permet aux clients de vos services de faire de la programmation asynchrone ● Coût en performance négligeable 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 100
  • 101. Concurrent ListenableFuture – Exemple ListenableFuture<List<Note>> getNotes(Film film) { ListenableFuture<Note> noteImdb = imdbService.getNote(film); ListenableFuture<Note> noteAllo = allocineService.getNote(film); return Futures.allAsList(noteImdb, noteAllo); } On retourne un Future au lieu de bloquer pour renvoyer une List<Note>. Permet au client de getNotes() d'exécuter d'autres actions en parallèle. 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 101
  • 102. Conclusion Effective Guava 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 102
  • 103. Bibliographie / liens Guava – http://code.google.com/p/guava-libraries/ Tuto Google-Collections (dvp) – http://thierry-lerichedessirier.developpez.com/tutoriels/java/tutogoogle-collections/ Comparaison d’API Java de programmation fonctionnelle (Xebia) – http://blog.xebia.fr/2011/06/29/comparaison-dapijava-de-programmation-fonctionnelle/ 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 103
  • 104. Bibliographie / liens Guava: faire du fonctionnel (Touilleur) – http://www.touilleur-express.fr/2010/11/03/googleguava-faire-du-fonctionnel/ Chez Thierry – http://www.thierryler.com/ 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 104
  • 105. Questions / Réponses Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique
  • 106. Sponsors 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 106
  • 107. Merci de votre attention! Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique
  • 108. Licence http://creativecommons.org/licenses/by-nc-sa/2.0/fr/ 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 108
  • 109. Functional Programming Filtre en chaine avec FluentIterable ? Predicate malePredicate = new Predicate<Dog>() { public boolean apply(Dog dog) { return dog.getSex() == MALE; }}; Milou Idefix Rintintin Medor Predicate eLetterPredicate = new Predicate<Dog>() { public boolean apply(Dog dog) { return dog.getName().contains("e"); }}; Idefix Lassie Medor FluentIterable.with(dogs) .filter(malePredicate) .filter(eLetterPredicate) Guava 11-12 ? 08/11/2011 Guava by Google Idefix Medor www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 109
  • 110. Functional Programming Ensembles... Set<Dog> dogSet = newHashSet(dogs); Milou Idefix Lassie Rintintin Lady Medor Set<Dog> superDogSet = newTreeSet(superDogs); Milou Lassie Volt 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 110
  • 111. Functional Programming Ensembles... Milou Idefix Lassie Rintintin Lady Medor Milou Lassie Volt Sets.SetView<Dog> difference = Sets.difference(dogSet, superDogSet); Idefix Medor Rintintin Lady Sets.SetView<Dog> intersection = Sets.intersection(dogSet, superDogSet); Lassie Milou Sets.SetView<Dog> union = Sets.union(dogSet, superDogSet); Milou Lady Lassie Idefix 08/11/2011 Guava by Google Rintintin Medor Volt www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 111
  • 112. Partition / limit Avec 4 chiens import static com.google.common.collect.Lists.partition; List<List<Dog>> partitions = partition(dogs, 4); Milou Idefix Lassie Rintintin Laidy Medor import static com.google.common.collect.Iterables.limit; List<Dog> subList = newArrayList(limit(dogs, 4)); Milou Idefix Lassie Rintintin 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 112
  • 113. Ordering Classement des chiens dogs = newArrayList( new Dog("Milou", new Dog("Idefix", new Dog("Lassie", new Dog("Rintintin", new Dog("Lady", new Dog("Medor", 08/11/2011 MALE, MALE, FEMALE, MALE, FEMALE, MALE, 6.0), 4.8), 23.5), 12.4), 7.8), 26.2)); Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 113
  • 114. Ordering Classement des chiens dogs = newArrayList( new Dog("Milou", new Dog("Idefix", new Dog("Lassie", new Dog("Rintintin", new Dog("Lady", new Dog("Medor", MALE, MALE, FEMALE, MALE, FEMALE, MALE, 6.0), 4.8), 23.5), 12.4), 7.8), 26.2)); Ordering<Dog> weightOrdering = new Ordering<Dog>() { public int compare(Dog left, Dog right) { return left.getWeight().compareTo(right.getWeight()); }}; 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 114
  • 115. Ordering Classement des chiens dogs = newArrayList( new Dog("Milou", new Dog("Idefix", new Dog("Lassie", new Dog("Rintintin", new Dog("Lady", new Dog("Medor", MALE, MALE, FEMALE, MALE, FEMALE, MALE, 6.0), 4.8), 23.5), 12.4), 7.8), 26.2)); Ordering<Dog> weightOrdering = new Ordering<Dog>() { public int compare(Dog left, Dog right) { return left.getWeight().compareTo(right.getWeight()); }}; List<Dog> orderedDogs = weightOrdering .nullsLast() .sortedCopy(dogs); 08/11/2011 Guava by Google Idefix Milou Lady Rintintin Lassie Medor (4.8) (6.0) (7.8) (12.4) (23.5) (26.2) www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 115
  • 116. Ordering Classement des chiens Ordering<Dog> weightOrdering = new Ordering<Dog>() { public int compare(Dog left, Dog right) { return left.getWeight().compareTo(right.getWeight()); } } 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 116
  • 117. Ordering Classement des chiens Ordering<Dog> weightOrdering = new Ordering<Dog>() { public int compare(Dog left, Dog right) { return left.getWeight().compareTo(right.getWeight()); } } Dog biggestDog = weightOrdering.max(dogs); Medor Dog smallestDog = weightOrdering.min(dogs); Idefix 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 117
  • 118. Immutables Map public static final ImmutableMap<String, Integer> AGES = ImmutableMap.of("Jean", 32, "Paul", 12, "Lucie", 37, "Marie", 17); 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 118
  • 119. Immutables Map public static final ImmutableMap<String, Integer> AGES = ImmutableMap.of("Jean", 32, "Paul", 12, "Lucie", 37, "Marie", 17); public static final ImmutableMap<String, Integer> AGES = new ImmutableMap.Builder<String, Integer>() .put("Jean", 32) .put("Paul", 12) .put("Lucie", 37) .put("Marie", 17) .put("Bernard", 17) .put("Toto", 17) .put("Loulou", 17) .build(); 08/11/2011 Guava by Google www.parisjug.org Copyright © 2008 ParisJug. Licence CC – Creative Commons 2.0 France – Paternité – Pas d'Utilisation Commerciale – Partage des Conditions Initiales à l'Identique 119

Hinweis der Redaktion

  1. Thierry : * 35 ans * 12 ans d’expérience * Consultant freelance (ICAUDA) - Assurance - Grande distribution * Professeur de Génie Logiciel à l&apos;ESIEA * Rédacteur pour developpez.com Etienne : * 25 ans * Sfeirien * Ingénieur généraliste, consultant Java depuis 2008 - Comptabilité - Édition - E-commerce * Utilise Google Collections / Guava depuis 3 ans
  2. THIERRY Dans cette présentation, on ne peut pas parler de tout ce que contient Guava. On a fait le choix de ne présenter que des aspects simples mais qui nous semblent importants. Ces points sont ceux qui donnent envie d&apos;en savoir plus. Open Source - Licence Apache 2.0
  3. THIERRY Effective Java, Item 1 : « Consider static factory methods instead of constructors»
  4. Premier contact avec guava, on commence par un truc bien pratique, même si ce n&apos;est pas révolutionnaire .
  5. La plupart d&apos;entre nous n&apos;aurons pas accès à Java 7 avant 2 ou 3 ans sur les projets de leur entreprise. Je travaille moi-même encore sur des projets en java 1.4 et même en 1.2
  6. Les static factories sont recommandées dans effective Java. D’ailleurs Guava est très inspiré par le contenu de ce livre. Avec les imports statiques de : * Lists.newArrayList * Sets.newTreeSet * Maps.newHashMap
  7. Le Dog est un peu le fil conducteur de cette présentation.
  8. Varargs
  9. THIERRY
  10. Si on utilise souvent ce Predicate, on peut le définir avec une variable et pas forcément en param
  11. In, and, or, etc. sont dans Predicates
  12. Ici j&apos;ai besoin d&apos;introduire un objet Chien pour la suite.
  13. C&apos;est assez courant de devoir convertir des Objets sur un projet. Disons par exemple que le projet en cours utilise encore des objet en francais et ne s&apos;est pas encore mis à la nouvelle norme de la société.
  14. Il faut bien comprendre qu&apos;on travaille avec des vues. La transformation est faite de façon lazy. L&apos;appel à size ou à isempty ne déclenche pas le transform. Par contre elle sera faite à chaque fois qu&apos;on va itérer sur la liste. Du coup, si on pense qu&apos;on utilisera plus d&apos;une fois la liste, il vaut mieux directement convertir la vue en une vraie liste.
  15. Ca se marie relativement bien avec les Converters de Spring
  16. Guava n&apos;aime pas les null et renvoie une exception si aucun élément n&apos;est trouvé
  17. THIERRY Il ne faut pas se demander si une collection doit etre immutable mais plutôt si elle a besoin d’être mutable. Et en général, la réponse est non : elle n&apos;a pas besoin d’être mutable, donc autant utiliser une immutable. Les Immutable ont notamment un interet du point de vue de la concurrence, ce que va expliquer Etienne plus tard Etienne : Je ne vais pas vraiment l&apos;expliquer. Je vais juste dire en deux phrases que Guava est particulièrement adapté à la programmation concurrente, en particulier grâce à ses collections immutables. Mais je ne rentre pas ds les détails.
  18. C&apos;est super complexe comme écriture. On a tous déjà pondu au moins une fois ce genre de chose, voire pire. Ici les gens oublient souvent le « final »... Penser à dire que la vue n&apos;est pas modifiable, mais le set d&apos;origine, si.
  19. Ici je ne déclare pas la constante sous forme de Set mais comme un ImmutableSet pour bien faire passer le message. « constante » → « variable »
  20. ETIENNE Je vais maintenant vous présenter les classes qui sont à mon avis les plus utiles dans le package Guava Base. Ce package contient un grand nombre de classes et méthodes utilitaires « basiques ». On peut considérer qu&apos;il étend en quelque sorte « java.lang ».
  21. Commençons par la classe Objects, qui simplifie beaucoup l&apos;écriture des méthodes classiques d&apos;Object. Pour cela, on va reprendre pour exemple notre chien, un bean avec 3 champs.
  22. Lorsque les champs peuvent être null, la méthode equals() devient vite verbeuse...
  23. Objects.equal() permet de faire un test d&apos;égalité qui gère les objets nulls, ce qui simplifie beaucoup le code.
  24. De même pour la méthode hashCode(), qui peut être implémentée en une ligne grâce à Objects.hashCode.
  25. Objects.toStringHelper() simplifie l&apos;écriture de la méthode toString(), grâce au builder pattern.
  26. Le code est aussi beaucoup plus lisible.
  27. Pour finir, la méthode compareTo() peut être simplifiée grâce à ComparisonChain.
  28. Le builder pattern nous permet d&apos;enchaîner des comparaisons très simplement..
  29. Il est possible de customiser chaque comparaison de ComparisonChain en passant un comparateur. C&apos;est notamment utile pour comparer des objects nulls, en utilisant un comparateur qui classe ces derniers à la fin plutôt que de jetter une NPE...
  30. ETIENNE Passons maintenant à la classe Preconditions, l&apos;une de mes classes préférées, qui permet de valider les arguments des méthodes et constructeurs..
  31. Je vais prendre pour exemple une classe Money, associant un montant et une devise. C&apos;est une classe que l&apos;on retrouve dans de nombreux projets. Une bonne pratique est de rendre immutables les value objects de ce genre. Cela permet d&apos;éviter les copies défensives, de simplifier la programmation concurrente, et de préserver les invariants une fois l&apos;objet construit.
  32. On voudrait valider les arguments de son constructeur, pour s&apos;assurer qu&apos;elle est correctement construite. On va donc vérifier que le montant et la devise ne sont pas nulls, et vérifier que le montant est positif. En Java classique, c&apos;est assez verbeux.
  33. La classe Preconditions permet de simplifier ces checks, grâce à checkNotNull, qui lance une NPE si l&apos;argument est null, et checkArgument, qui lance une IllegalArgumentException si une condition est fausse. Notez que l&apos;on peut paramétrer les messages d&apos;erreur. Le code est plus court et plus lisible.
  34. Mais on peut encore simplifier. Les designers de Guava ont été astucieux, car checkNotNull() retourne son argument après validation. Cela permet de valider un argument avec checkNotNull et de l&apos;assigner à un champ, en une seule ligne. C&apos;est une fonctionnalité que j&apos;utilise tout le temps.
  35. ETIENNE Je vais maintenant vous présenter la classe CharMatcher, qui est très utile pour manipuler les chaînes de caractères.
  36. Google avait à l&apos;origine une classe StringUtils, contenant de nombreuses méthodes utilitaires pour manipuler les chaînes de caractères. Ils avaient par exemple différentes version de la méthode remove(). La première, remove(), supprimait des caractères précis d&apos;une chaîne. La seconde, removeDigits(), supprimait tous les nombres. La troisième, removeWhitespace(), enlevait les espaces blancs.
  37. Les méthodes se multipliant, ils ont réalisé qu&apos;elles représentaient en réalité un produit croisé de deux notions : (a) qu&apos;est-ce qu&apos;un caractère qui « matche » (b) que faire de ces caractères Cette approche n&apos;étant pas scalable, ils ont créé CharMatcher. Une instance de CharMatcher correspond à la première notion, et les opérations que l&apos;on invoque sur ce CharMatcher correspondent à la seconde.
  38. On peut obtenir un CharMatcher de différentes manières. La première consiste à utiliser l&apos;une des constantes disponibles.
  39. THIERRY * Multimap * BiMap * MultiSet
  40. THIERRY Une Multimap, c&apos;est grossomodo une « Map de List »
  41. THIERRY
  42. Pour faire une Bimap en java pur, il faut en gros faire deux map symétriques
  43. THIERRY List : Ordre + Doublon Set : Sans ordre significatif + Sans Doublon MultiSet : Sans ordre significatif + Doublon
  44. THIERRY
  45. C&apos;est le genre de fonction qu&apos;on a tous eut à écrire un jour ou l&apos;autre.
  46. Le splitter est grosso modo l&apos;inverse du joiner.
  47. ETIENNE Je vais maintenant vous présenter deux types de caches disponibles dans Guava : - la mémoization d&apos;une part, qui permet de cacher le résultat unique d&apos;un appel à une fonction - les caches « classiques » d&apos;autre part, qui permettent de cacher des couples clé-valeur, comme dans une Map
  48. Prenons pour exemple un service permettant d&apos;obtenir des informations sur la dernière version du JDK disponible. Pour ce faire, ce service appelle un web-service, ce qui est lent et gourmand en ressources. On voudrait donc cacher son résultat.
  49. Une première approche consiste à faire de la mémoization « manuelle », en cachant le résultat dans un champ. Cela nécessite cependant de synchroniser la méthode, ce qui peut poser des problèmes de contention. On pourrait éviter la synchronisation, en mettant en place un double-checked locking, mais le code est complexe, verbeux, et souvent mal implémenté.
  50. Guava permet de mémoizer une valeur très simplement, grâce à l&apos;interface Supplier. Un Supplier est une classe qui peut fournir des objets d&apos;un certain type, une Factory en quelque sorte.
  51. Pour mémoizer notre appel, on créé un Supplier, qui va appeller notre web-service lorsque l&apos;on invoque sa méthode « get ».
  52. On combine ce Supplier avec la méthode utilitaire Suppliers.memoize(). Elle renvoie un nouveau Supplier, qui décore le premier, et cache le résultat du premier appel. L&apos;avantage, c&apos;est que les problématiques de synchronization sont gérées par Guava, avec une variante du double-checked locking. Problème : nous cachons la version du JDK éternellement... Or, il arrive -certes rarement- qu&apos;une nouvelle version soit disponible.
  53. Pas de problème, Guava propose une seconde méthode, Suppliers.memoizeWithExpiration(), qui permet de mémoizer le résultat pour une durée déterminée. Dans notre exemple, un an me semble raisonnable ;)
  54. ETIENNE Nous allons maintenant voir comment mettre en place un cache clé-valeur.
  55. Prenons pour exemple un service permettant de récupérer des informations sur un film, en appelant IMDB, l&apos;Internet Movie DataBase, via un web service. On voudrait cacher les appels à ce service. Contrairement à l&apos;exemple précédent, le service peut renvoyer des résultats différents selon l&apos;ID du film passé en paramètre.
  56. Guava 10 a introduit un nouveau package dédié aux caches, com.google.common.cache. Il contient une interface pour représenter un cache, avec des méthodes pour charger et invalider des valeurs, obtenir des statistiques d&apos;utilisation, et obtenir une vue du cache sous la forme d&apos;une Map.
  57. Introduisons le cache Guava dans notre exemple. Pour le construire, il est recommandé d&apos;utiliser CacheBuilder, qui permet de configurer simplement un cache via une interface fluide. On passe à notre builder un CacheLoader, l&apos;interface à implémenter pour indiquer à Guava comment charger les nouvelles valeurs. Il nous suffit maintenant d&apos;appeler filmCache.getUnchecked() dans la méthode getFilm(). Le cache se charge du reste. Problème : nous voulons expirer les éléments régulièrement, et limiter la taille totale du cache, qui utilise trop de mémoire.
  58. Nous pouvons configurer ces propriétés via l&apos;interface fluide de CacheBuilder: - taille maximum de 2000 éléments - expiration des éléments après 30 minutes CacheBuilder est un excellent exemple d&apos;une API très simplequi cache (;)) des fonctionnalités puissantes et complexes.
  59. ETIENNE Le package common.io contient des classes et méthodes utilitaires pour travailler avec Java I/O, c&apos;est-à-dire les input streams, output streams, readers, writers, et fichiers.
  60. La gestion des entrées/sorties est très verbeuse en Java. Il faut fermer correctement les ressources, et gérer les IOExceptions pouvant être lancé lors de l&apos;ouverture, l&apos;utilisation, ou la fermeture de ces dernières. La bonne pratique est de fermer les ressources dans des blocs finally, comme dans cet exemple. Si une exception est lancée lors de l&apos;utilisation de la ressource, il faut veiller à ne pas l&apos;« avaler » en jettant une nouvelle exception dans le bloc finally. http://www.ibm.com/developerworks/java/library/j-jtp03216/index.html
  61. Java 7 simplifie la gestion des ressources, avec les interfaces AutoCloseable, et le méchanisme de multi-exceptions (todo). Mais nombre d&apos;entreprises sont timides (?) à l&apos;adoption de Java 7 (?). Et Guava I/O a plus d&apos;un tour dans son sac...
  62. Voici l&apos;équivalent Guava du code précédent.
  63. Guava I/O est basé sur la notion d&apos;IntputSupplier et d&apos;OutputSupplier. Ces deux interfaces représentent des fabriques d&apos;objets I/O, encapsulant la création d&apos;InputStream, OutputStream, Reader, et Writer. La construction de ces ressources peut souvent lancer des IOExceptions. En utilisant ces suppliers, on laisse Guava se charger du cycle de vie des ressources (ouverture, fermeture, gestion des exceptions). Cette approche est aussi très modulaire. Elle permet par exemple à Google d&apos;avoir des suppliers basés sur GFS, le file-system interne de Google.
  64. Les méthodes utilitaires de Guava I/O sont réparties dans 3 classes. ByteStreams permet de manipuler des bytes.
  65. CharStreams contient des méthodes équivalentes, mais fonctionnant avec des caractères, càd en terme de Reader, Writer, CharSequence, et String.
  66. Enfin, Files, se base sur ByteStreams et CharStreams pour faciliter la manipulation de fichiers
  67. ETIENNE Introduire brièvement util.concurrent en disant que Guava est tout particulièrement indiqué pour la programmation concurrente, car privilégiant l&apos;immutabilité (collections immutables, mais aussi nombre autre classes telles que CharMatcher / Joiner / Splitter)
  68. ListenableFuture est un Future avec une méthode supplémentaire, qui permet d&apos;ajouter des listeners. Ils sont appelés lorsque le Future est terminé, qu&apos;il s&apos;agisse d&apos;un succès, d&apos;une exception, ou d&apos;une annulation. Si le Future est déjà terminé lorsque l&apos;on appelle addListener(), le listener est appelé immédiatement.
  69. Cela permet de faire de la programmation asynchrone,
  70. ETIENNE ou THIERRY
  71. Déjà possible avec les Functionnal-Collections
  72. THIERRY Ici j&apos;utilise des Set à la place des listes
  73. THIERRY Attention : ne pas oublier equals et hashCode
  74. THIERRY Petit bonus du genre de fonctionnalité qu&apos;on est tout le temps obligés de faire.
  75. THIERRY
  76. THIERRY
  77. THIERRY
  78. THIERRY
  79. THIERRY
  80. THIERRY
  81. THIERRY