• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Guava au Paris JUG
 

Guava au Paris JUG

on

  • 178 views

 

Statistics

Views

Total Views
178
Views on SlideShare
178
Embed Views
0

Actions

Likes
0
Downloads
2
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • Thierry : <br /> * 35 ans <br /> * 12 ans d’expérience <br /> * Consultant freelance (ICAUDA) <br /> - Assurance <br /> - Grande distribution <br /> * Professeur de Génie Logiciel à l&apos;ESIEA <br /> * Rédacteur pour developpez.com <br /> Etienne : <br /> * 25 ans <br /> * Sfeirien <br /> * Ingénieur généraliste, consultant Java depuis 2008 <br /> - Comptabilité <br /> - Édition <br /> - E-commerce <br /> * Utilise Google Collections / Guava depuis 3 ans <br />
  • THIERRY <br /> 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. <br /> Open Source - Licence Apache 2.0 <br />
  • THIERRY <br /> Effective Java, Item 1 : « Consider static factory methods instead of constructors» <br />
  • Premier contact avec guava, on commence par un truc bien pratique, même si ce n&apos;est pas révolutionnaire . <br />
  • 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 <br />
  • Les static factories sont recommandées dans effective Java. D’ailleurs Guava est très inspiré par le contenu de ce livre. <br /> Avec les imports statiques de : <br /> * Lists.newArrayList <br /> * Sets.newTreeSet <br /> * Maps.newHashMap <br />
  • Le Dog est un peu le fil conducteur de cette présentation. <br />
  • Varargs <br />
  • THIERRY <br />
  • Si on utilise souvent ce Predicate, on peut le définir avec une variable et pas forcément en param <br />
  • In, and, or, etc. sont dans Predicates <br />
  • Ici j&apos;ai besoin d&apos;introduire un objet Chien pour la suite. <br />
  • 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é. <br />
  • Il faut bien comprendre qu&apos;on travaille avec des vues. La transformation est faite de façon lazy. <br /> L&apos;appel à size ou à isempty ne déclenche pas le transform. <br /> Par contre elle sera faite à chaque fois qu&apos;on va itérer sur la liste. <br /> 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. <br />
  • Ca se marie relativement bien avec les Converters de Spring <br />
  • Guava n&apos;aime pas les null et renvoie une exception si aucun élément n&apos;est trouvé <br />
  • THIERRY <br /> 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. <br /> Les Immutable ont notamment un interet du point de vue de la concurrence, ce que va expliquer Etienne plus tard <br /> 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. <br />
  • C&apos;est super complexe comme écriture. On a tous déjà pondu au moins une fois ce genre de chose, voire pire. <br /> Ici les gens oublient souvent le « final »... <br /> Penser à dire que la vue n&apos;est pas modifiable, mais le set d&apos;origine, si. <br />
  • Ici je ne déclare pas la constante sous forme de Set mais comme un ImmutableSet pour bien faire passer le message. <br /> « constante » → « variable » <br />
  • ETIENNE <br /> Je vais maintenant vous présenter les classes qui sont à mon avis les plus utiles dans le package Guava Base. <br /> 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 ». <br />
  • Commençons par la classe Objects, qui simplifie beaucoup l&apos;écriture des méthodes classiques d&apos;Object. <br /> Pour cela, on va reprendre pour exemple notre chien, un bean avec 3 champs. <br />
  • Lorsque les champs peuvent être null, la méthode equals() devient vite verbeuse... <br />
  • Objects.equal() permet de faire un test d&apos;égalité qui gère les objets nulls, ce qui simplifie beaucoup le code. <br />
  • De même pour la méthode hashCode(), qui peut être implémentée en une ligne grâce à Objects.hashCode. <br />
  • Objects.toStringHelper() simplifie l&apos;écriture de la méthode toString(), grâce au builder pattern. <br />
  • Le code est aussi beaucoup plus lisible. <br />
  • Pour finir, la méthode compareTo() peut être simplifiée grâce à ComparisonChain. <br />
  • Le builder pattern nous permet d&apos;enchaîner des comparaisons très simplement.. <br />
  • Il est possible de customiser chaque comparaison de ComparisonChain en passant un comparateur. <br /> 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... <br />
  • ETIENNE <br /> 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.. <br />
  • 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. <br /> 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. <br />
  • On voudrait valider les arguments de son constructeur, pour s&apos;assurer qu&apos;elle est correctement construite. <br /> On va donc vérifier que le montant et la devise ne sont pas nulls, et vérifier que le montant est positif. <br /> En Java classique, c&apos;est assez verbeux. <br />
  • 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. <br /> Notez que l&apos;on peut paramétrer les messages d&apos;erreur. <br /> Le code est plus court et plus lisible. <br />
  • Mais on peut encore simplifier. <br /> 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. <br /> C&apos;est une fonctionnalité que j&apos;utilise tout le temps. <br />
  • ETIENNE <br /> Je vais maintenant vous présenter la classe CharMatcher, qui est très utile pour manipuler les chaînes de caractères. <br />
  • Google avait à l&apos;origine une classe StringUtils, contenant de nombreuses méthodes utilitaires pour manipuler les chaînes de caractères. <br /> 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. <br />
  • Les méthodes se multipliant, ils ont réalisé qu&apos;elles représentaient en réalité un produit croisé de deux notions : <br /> (a) qu&apos;est-ce qu&apos;un caractère qui « matche » <br /> (b) que faire de ces caractères <br /> Cette approche n&apos;étant pas scalable, ils ont créé CharMatcher. <br /> Une instance de CharMatcher correspond à la première notion, et les opérations que l&apos;on invoque sur ce CharMatcher correspondent à la seconde. <br />
  • On peut obtenir un CharMatcher de différentes manières. <br /> La première consiste à utiliser l&apos;une des constantes disponibles. <br />
  • THIERRY <br /> * Multimap <br /> * BiMap <br /> * MultiSet <br />
  • THIERRY <br /> Une Multimap, c&apos;est grossomodo une « Map de List » <br />
  • THIERRY <br />
  • Pour faire une Bimap en java pur, il faut en gros faire deux map symétriques <br />
  • THIERRY <br /> List : Ordre + Doublon <br /> Set : Sans ordre significatif + Sans Doublon <br /> MultiSet : Sans ordre significatif + Doublon <br />
  • THIERRY <br />
  • C&apos;est le genre de fonction qu&apos;on a tous eut à écrire un jour ou l&apos;autre. <br />
  • Le splitter est grosso modo l&apos;inverse du joiner. <br />
  • ETIENNE <br /> Je vais maintenant vous présenter deux types de caches disponibles dans Guava : <br /> - la mémoization d&apos;une part, qui permet de cacher le résultat unique d&apos;un appel à une fonction <br /> - les caches « classiques » d&apos;autre part, qui permettent de cacher des couples clé-valeur, comme dans une Map <br />
  • Prenons pour exemple un service permettant d&apos;obtenir des informations sur la dernière version du JDK disponible. <br /> Pour ce faire, ce service appelle un web-service, ce qui est lent et gourmand en ressources. <br /> On voudrait donc cacher son résultat. <br />
  • Une première approche consiste à faire de la mémoization « manuelle », en cachant le résultat dans un champ. <br /> Cela nécessite cependant de synchroniser la méthode, ce qui peut poser des problèmes de contention. <br /> On pourrait éviter la synchronisation, en mettant en place un double-checked locking, mais le code est complexe, verbeux, et souvent mal implémenté. <br />
  • Guava permet de mémoizer une valeur très simplement, grâce à l&apos;interface Supplier. <br /> Un Supplier est une classe qui peut fournir des objets d&apos;un certain type, une Factory en quelque sorte. <br />
  • Pour mémoizer notre appel, on créé un Supplier, qui va appeller notre web-service lorsque l&apos;on invoque sa méthode « get ». <br />
  • 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. <br /> 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. <br /> Problème : nous cachons la version du JDK éternellement... Or, il arrive -certes rarement- qu&apos;une nouvelle version soit disponible. <br />
  • 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. <br /> Dans notre exemple, un an me semble raisonnable ;) <br />
  • ETIENNE <br /> Nous allons maintenant voir comment mettre en place un cache clé-valeur. <br />
  • 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. <br /> On voudrait cacher les appels à ce service. <br /> 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. <br />
  • 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. <br />
  • Introduisons le cache Guava dans notre exemple. <br /> Pour le construire, il est recommandé d&apos;utiliser CacheBuilder, qui permet de configurer simplement un cache via une interface fluide. <br /> On passe à notre builder un CacheLoader, l&apos;interface à implémenter pour indiquer à Guava comment charger les nouvelles valeurs. <br /> Il nous suffit maintenant d&apos;appeler filmCache.getUnchecked() dans la méthode getFilm(). Le cache se charge du reste. <br /> Problème : nous voulons expirer les éléments régulièrement, et limiter la taille totale du cache, qui utilise trop de mémoire. <br />
  • Nous pouvons configurer ces propriétés via l&apos;interface fluide de CacheBuilder: <br /> - taille maximum de 2000 éléments <br /> - expiration des éléments après 30 minutes <br /> CacheBuilder est un excellent exemple d&apos;une API très simplequi cache (;)) des fonctionnalités puissantes et complexes. <br />
  • ETIENNE <br /> 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. <br />
  • 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. <br /> 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. <br /> http://www.ibm.com/developerworks/java/library/j-jtp03216/index.html <br />
  • Java 7 simplifie la gestion des ressources, avec les interfaces AutoCloseable, et le méchanisme de multi-exceptions (todo). <br /> 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... <br />
  • Voici l&apos;équivalent Guava du code précédent. <br />
  • 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. <br /> 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). <br /> 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. <br />
  • Les méthodes utilitaires de Guava I/O sont réparties dans 3 classes. ByteStreams permet de manipuler des bytes. <br />
  • CharStreams contient des méthodes équivalentes, mais fonctionnant avec des caractères, càd en terme de Reader, Writer, CharSequence, et String. <br />
  • Enfin, Files, se base sur ByteStreams et CharStreams pour faciliter la manipulation de fichiers <br />
  • ETIENNE <br /> 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) <br />
  • 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. <br />
  • Cela permet de faire de la programmation asynchrone, <br />
  • ETIENNE ou THIERRY <br />
  • Déjà possible avec les Functionnal-Collections <br />
  • THIERRY <br /> Ici j&apos;utilise des Set à la place des listes <br />
  • THIERRY <br /> Attention : ne pas oublier equals et hashCode <br />
  • THIERRY <br /> Petit bonus du genre de fonctionnalité qu&apos;on est tout le temps obligés de faire. <br />
  • THIERRY <br />
  • THIERRY <br />
  • THIERRY <br />
  • THIERRY <br />
  • THIERRY <br />
  • THIERRY <br />
  • THIERRY <br />

Guava au Paris JUG Guava au Paris JUG Presentation Transcript

  • 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