On Github BloumineX / ReXStreamLambda
Created by Xavier BLOUMINE / @bloumix
Développeur Java 6 Ans xp Passionné par le Clean Code et les best practices ! (TDD/BDD/DDD/Craftman/conférences/...)
En mission chez Natixis crédit consommation Contexte : JBoss EAP 6.4 / Java 8 / JPA / Rest / ...
Comparator<String> c = new comparator<String>() { @Override public boolean compare(String s1, String s2) { return s1.compageIgnoreCase(s2); } } /// stuff there /// list.sort(c);Utilisation d'une classe anonyme pour pouvoir utiliser le Comparator Résultat : Rend le code moins lisible en devant réimplémenter la classe Comparator (cas simple)...
list.sort((s1, s2) -> s1.compareIgnoreCase(s2));Utilisation d'une Lambda
//On ne peux pas modifier une liste sur lequel on iterer // donc on la copie dans une nouvelle liste List< Integer> listResult = new ArrayList< >(list); //enlever les éléments impairs for (Integer i : list) { if (i%2 != 0) listResult.remove(i); } //enlever les doublons Set< Integer> setInte = new HashSet<>(listResult); //Multiplier par 2 les élements et renvoyer la somme Integer result = 0; for (Integer i : setInte) { result = result + i * 2; }
list.stream() .filter((value -> value % 2 != 0)) .map(value -> value * 2) .distinct() .reduce(0, (val1, val2) -> val1 + val2)
Rien de plus facile !
//le for n'a pas de d'équivalent pur car il est trop générique //les streams peuvent parcourir les éléments facilement et faire des opérations dessus. list.stream() .filter((value -> value % 2 != 0)) .map(value -> value * 2) .distinct() .forEach(value -> System::println) //forEach ;)
Interface ne possédant qu'une seule méthode abstraite
Peut avoir n méthodes implémentées mais uniquement une méthode abstraite Sert de conteneur pour la méthode abstraiteL'Annotation @FunctionnalInterface indique au compilateur que cette interface est une interface Fonctionnelle
@FunctionnalInterface public Interface StringComparator { default int methodFolle(String a) { /* Some stuff there */} int compare(String a, String b); }
La liste des interfaces fonctionnelles disponibles de l'api
Equivalent en C++ : functeur pointeur de fonction Le principe : encapsuler la methode abstraite au sein d'un objet javaConsumer< Integer> consumer = new Consumer< Integer>() { @Override public void accept(Integer integer) { System.out.println(integer); } }; list.stream().forEach(consumer);Nous passons un objet et non une méthode !
public class PrinterList { //static obligatoire car il n'y a pas d'implementation ! public static void print(Integer i) { System.out.println(i); } } //Le compilateur va avec cette nouvelle syntaxe comprendre que cette méthode //peut etre utiliser en tant que Consumer list.stream().forEach(PrinterList::print); //Possibilité aussi de passer par : list.stream().forEach(System.out::println);Même si le compilateur effectue des transformations en interne, nous envoyons maintenant notre méthode au lieu d'un objet !Nous devons quand même créer une classe pour paramètrer notre fonction
list.stream().forEach((value) -> System.out.println(value));
//value n'a pas de parametre mais le compilateur sais le reconnaitre Arrays.<String>asList("tst1", "tst2").stream() .forEach(value -> System.out.println(value)); //Lambda expression et inférence du type des paramètres Arrays.<String>asList("tst1", "tst2") .forEach((String value) -> System.out.println(value)); //block de données possible Arrays.<String>asList("tst1", "tst2") .forEach(value -> { System.out.println(value); });
//Plusieurs parametre (reduce), parenthèse Obligatoire list.stream() .filter((value -> value % 2 != 0)) .map(value -> value * 2) .distinct() .reduce(0, (val1, val2) -> val1 + val2)
public void test() { int x = 0; //variable locale Arrays.asList(1, 2, 3).forEach(value -> x+=value); //erreur !!!! //La variable x est considérée final par la lambda. }
Choisit les élements si le predicat est vrai
.map(Function< E, R>) → Stream< R>Transforme les élements
.flatMap(Function< E, Stream< R>>) → Stream< R>Applatit l'ensemble des Streams de chaque élement
.skip(), .limit()Saute des élements, reduit le nombre d'élement
.distinct(), .sorted(Comparator< E>)Sans doublon (par rapport à equals), trie
Compte les élements
.forEach(Consumer< E>)Applique le consumer pour chaque élement
.allMatch(Predicate< E>), .anyMatch(Predicate< E>)Vrai si tout les/au moins un élement(s) match
.findAny(), .findFirst() → Optional< E>Trouver un ou le premier, renvoie une posibilité d'élement
.toArray(IntFunction)Crée un tableau ex: .toArray(String[]::new)
.reduce(), collect(Collector) Aggège les éléments en 1 valeur (resp. non-mutable, mutable)