Guava au Paris JUG

402 views

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
402
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
3
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • Thierry :
    * 35 ans
    * 12 ans d’expérience
    * Consultant freelance (ICAUDA)
    - Assurance
    - Grande distribution
    * Professeur de Génie Logiciel à l'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
  • 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'en savoir plus.
    Open Source - Licence Apache 2.0
  • THIERRY
    Effective Java, Item 1 : « Consider static factory methods instead of constructors»
  • Premier contact avec guava, on commence par un truc bien pratique, même si ce n'est pas révolutionnaire .
  • La plupart d'entre nous n'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
  • 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
  • Le Dog est un peu le fil conducteur de cette présentation.
  • Varargs
  • THIERRY
  • Si on utilise souvent ce Predicate, on peut le définir avec une variable et pas forcément en param
  • In, and, or, etc. sont dans Predicates
  • Ici j'ai besoin d'introduire un objet Chien pour la suite.
  • C'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'est pas encore mis à la nouvelle norme de la société.
  • Il faut bien comprendre qu'on travaille avec des vues. La transformation est faite de façon lazy.
    L'appel à size ou à isempty ne déclenche pas le transform.
    Par contre elle sera faite à chaque fois qu'on va itérer sur la liste.
    Du coup, si on pense qu'on utilisera plus d'une fois la liste, il vaut mieux directement convertir la vue en une vraie liste.
  • Ca se marie relativement bien avec les Converters de Spring
  • Guava n'aime pas les null et renvoie une exception si aucun élément n'est trouvé
  • 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'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'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.
  • C'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'est pas modifiable, mais le set d'origine, si.
  • Ici je ne déclare pas la constante sous forme de Set mais comme un ImmutableSet pour bien faire passer le message.
    « constante » → « variable »
  • 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'il étend en quelque sorte « java.lang ».
  • Commençons par la classe Objects, qui simplifie beaucoup l'écriture des méthodes classiques d'Object.
    Pour cela, on va reprendre pour exemple notre chien, un bean avec 3 champs.
  • Lorsque les champs peuvent être null, la méthode equals() devient vite verbeuse...
  • Objects.equal() permet de faire un test d'égalité qui gère les objets nulls, ce qui simplifie beaucoup le code.
  • De même pour la méthode hashCode(), qui peut être implémentée en une ligne grâce à Objects.hashCode.
  • Objects.toStringHelper() simplifie l'écriture de la méthode toString(), grâce au builder pattern.
  • Le code est aussi beaucoup plus lisible.
  • Pour finir, la méthode compareTo() peut être simplifiée grâce à ComparisonChain.
  • Le builder pattern nous permet d'enchaîner des comparaisons très simplement..
  • Il est possible de customiser chaque comparaison de ComparisonChain en passant un comparateur.
    C'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...
  • ETIENNE
    Passons maintenant à la classe Preconditions, l'une de mes classes préférées, qui permet de valider les arguments des méthodes et constructeurs..
  • Je vais prendre pour exemple une classe Money, associant un montant et une devise. C'est une classe que l'on retrouve dans de nombreux projets.
    Une bonne pratique est de rendre immutables les value objects de ce genre. Cela permet d'éviter les copies défensives, de simplifier la programmation concurrente, et de préserver les invariants une fois l'objet construit.
  • On voudrait valider les arguments de son constructeur, pour s'assurer qu'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'est assez verbeux.
  • La classe Preconditions permet de simplifier ces checks, grâce à checkNotNull, qui lance une NPE si l'argument est null, et checkArgument, qui lance une IllegalArgumentException si une condition est fausse.
    Notez que l'on peut paramétrer les messages d'erreur.
    Le code est plus court et plus lisible.
  • 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'assigner à un champ, en une seule ligne.
    C'est une fonctionnalité que j'utilise tout le temps.
  • ETIENNE
    Je vais maintenant vous présenter la classe CharMatcher, qui est très utile pour manipuler les chaînes de caractères.
  • Google avait à l'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'une chaîne. La seconde, removeDigits(), supprimait tous les nombres. La troisième, removeWhitespace(), enlevait les espaces blancs.
  • Les méthodes se multipliant, ils ont réalisé qu'elles représentaient en réalité un produit croisé de deux notions :
    (a) qu'est-ce qu'un caractère qui « matche »
    (b) que faire de ces caractères
    Cette approche n'étant pas scalable, ils ont créé CharMatcher.
    Une instance de CharMatcher correspond à la première notion, et les opérations que l'on invoque sur ce CharMatcher correspondent à la seconde.
  • On peut obtenir un CharMatcher de différentes manières.
    La première consiste à utiliser l'une des constantes disponibles.
  • THIERRY
    * Multimap
    * BiMap
    * MultiSet
  • THIERRY
    Une Multimap, c'est grossomodo une « Map de List »
  • THIERRY
  • Pour faire une Bimap en java pur, il faut en gros faire deux map symétriques
  • THIERRY
    List : Ordre + Doublon
    Set : Sans ordre significatif + Sans Doublon
    MultiSet : Sans ordre significatif + Doublon
  • THIERRY
  • C'est le genre de fonction qu'on a tous eut à écrire un jour ou l'autre.
  • Le splitter est grosso modo l'inverse du joiner.
  • ETIENNE
    Je vais maintenant vous présenter deux types de caches disponibles dans Guava :
    - la mémoization d'une part, qui permet de cacher le résultat unique d'un appel à une fonction
    - les caches « classiques » d'autre part, qui permettent de cacher des couples clé-valeur, comme dans une Map
  • Prenons pour exemple un service permettant d'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.
  • 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é.
  • Guava permet de mémoizer une valeur très simplement, grâce à l'interface Supplier.
    Un Supplier est une classe qui peut fournir des objets d'un certain type, une Factory en quelque sorte.
  • Pour mémoizer notre appel, on créé un Supplier, qui va appeller notre web-service lorsque l'on invoque sa méthode « get ».
  • 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'avantage, c'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'une nouvelle version soit disponible.
  • 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 ;)
  • ETIENNE
    Nous allons maintenant voir comment mettre en place un cache clé-valeur.
  • Prenons pour exemple un service permettant de récupérer des informations sur un film, en appelant IMDB, l'Internet Movie DataBase, via un web service.
    On voudrait cacher les appels à ce service.
    Contrairement à l'exemple précédent, le service peut renvoyer des résultats différents selon l'ID du film passé en paramètre.
  • 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'utilisation, et obtenir une vue du cache sous la forme d'une Map.
  • Introduisons le cache Guava dans notre exemple.
    Pour le construire, il est recommandé d'utiliser CacheBuilder, qui permet de configurer simplement un cache via une interface fluide.
    On passe à notre builder un CacheLoader, l'interface à implémenter pour indiquer à Guava comment charger les nouvelles valeurs.
    Il nous suffit maintenant d'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.
  • Nous pouvons configurer ces propriétés via l'interface fluide de CacheBuilder:
    - taille maximum de 2000 éléments
    - expiration des éléments après 30 minutes
    CacheBuilder est un excellent exemple d'une API très simplequi cache (;)) des fonctionnalités puissantes et complexes.
  • ETIENNE
    Le package common.io contient des classes et méthodes utilitaires pour travailler avec Java I/O, c'est-à-dire les input streams, output streams, readers, writers, et fichiers.
  • 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'ouverture, l'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'utilisation de la ressource, il faut veiller à ne pas l'« avaler » en jettant une nouvelle exception dans le bloc finally.
    http://www.ibm.com/developerworks/java/library/j-jtp03216/index.html
  • Java 7 simplifie la gestion des ressources, avec les interfaces AutoCloseable, et le méchanisme de multi-exceptions (todo).
    Mais nombre d'entreprises sont timides (?) à l'adoption de Java 7 (?). Et Guava I/O a plus d'un tour dans son sac...
  • Voici l'équivalent Guava du code précédent.
  • Guava I/O est basé sur la notion d'IntputSupplier et d'OutputSupplier. Ces deux interfaces représentent des fabriques d'objets I/O, encapsulant la création d'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'avoir des suppliers basés sur GFS, le file-system interne de Google.
  • Les méthodes utilitaires de Guava I/O sont réparties dans 3 classes. ByteStreams permet de manipuler des bytes.
  • CharStreams contient des méthodes équivalentes, mais fonctionnant avec des caractères, càd en terme de Reader, Writer, CharSequence, et String.
  • Enfin, Files, se base sur ByteStreams et CharStreams pour faciliter la manipulation de fichiers
  • ETIENNE
    Introduire brièvement util.concurrent en disant que Guava est tout particulièrement indiqué pour la programmation concurrente, car privilégiant l'immutabilité (collections immutables, mais aussi nombre autre classes telles que CharMatcher / Joiner / Splitter)
  • ListenableFuture est un Future avec une méthode supplémentaire, qui permet d'ajouter des listeners. Ils sont appelés lorsque le Future est terminé, qu'il s'agisse d'un succès, d'une exception, ou d'une annulation. Si le Future est déjà terminé lorsque l'on appelle addListener(), le listener est appelé immédiatement.
  • Cela permet de faire de la programmation asynchrone,
  • ETIENNE ou THIERRY
  • Déjà possible avec les Functionnal-Collections
  • THIERRY
    Ici j'utilise des Set à la place des listes
  • THIERRY
    Attention : ne pas oublier equals et hashCode
  • THIERRY
    Petit bonus du genre de fonctionnalité qu'on est tout le temps obligés de faire.
  • THIERRY
  • THIERRY
  • THIERRY
  • THIERRY
  • THIERRY
  • THIERRY
  • THIERRY
  • Guava au Paris JUG

    1. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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

    ×