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 java
Consumer< 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)