les streams sont parmi nous
TRANSCRIPT
![Page 1: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/1.jpg)
@JosePaumard
Les
sont parmi nous
![Page 2: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/2.jpg)
@JosePaumard
Les
sont parmi nouspour le meilleur !
![Page 3: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/3.jpg)
#J8Stream @JosePaumard
Pourquoi s’intéresser aux API Streams ?
![Page 4: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/4.jpg)
#J8Stream @JosePaumard
Traitement de donnéesTraitement de données
• De 1998 à 2014… seul outil : l’API Collection Common collections
![Page 5: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/5.jpg)
#J8Stream @JosePaumard
Traitement de donnéesTraitement de données
• De 1998 à 2014… seul outil : l’API Collection Common collections
• À partir de 2014… un foisonnement !
![Page 6: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/6.jpg)
#J8Stream @JosePaumard
Traitement de donnéesTraitement de données
• Pourquoi autant d’offres ?
• Parce que le traitement de données devient central…
![Page 7: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/7.jpg)
#J8Stream @JosePaumard
Traitement de donnéesTraitement de données
• Pourquoi autant d’offres ?
• Parce que le traitement de données devient central… et complexe !
![Page 8: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/8.jpg)
#J8Stream @JosePaumard
Traitement de donnéesTraitement de données
• Pourquoi autant d’offres ?
• Parce que le traitement de données devient central… et complexe ! Volumes de plus en plus importants
![Page 9: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/9.jpg)
#J8Stream @JosePaumard
Traitement de donnéesTraitement de données
• Pourquoi autant d’offres ?
• Parce que le traitement de données devient central… et complexe ! Volumes de plus en plus importants Temps de réponse maîtrisés
![Page 10: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/10.jpg)
#J8Stream @JosePaumard
Traitement de donnéesTraitement de données
• Pourquoi autant d’offres ?
• Parce que le traitement de données devient central… et complexe ! Volumes de plus en plus importants Temps de réponse maîtrisés Algorithmes complexes
![Page 11: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/11.jpg)
#J8Stream @JosePaumard
Traitement de donnéesTraitement de données
• Le traitement de données a besoin de « primitives » de haut niveau
![Page 12: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/12.jpg)
#J8Stream @JosePaumard
Traitement de donnéesTraitement de données
• Le traitement de données a besoin de « primitives » de haut niveau Qui permettent d’accéder aux données où qu’elles
soient
![Page 13: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/13.jpg)
#J8Stream @JosePaumard
Traitement de donnéesTraitement de données
• Le traitement de données a besoin de « primitives » de haut niveau Qui permettent d’accéder aux données où qu’elles
soient Qui exposent des fonctions (map / filter / reduce)
![Page 14: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/14.jpg)
#J8Stream @JosePaumard
Traitement de donnéesTraitement de données
• Le traitement de données a besoin de « primitives » de haut niveau Qui permettent d’accéder aux données où qu’elles
soient Qui exposent des fonctions (map / filter / reduce) Qui soient efficaces !
![Page 15: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/15.jpg)
#J8Stream @JosePaumard
Traitement de donnéesTraitement de données
• Le traitement de données a besoin de « primitives » de haut niveau Qui permettent d’accéder aux données où qu’elles
soient Qui exposent des fonctions (map / filter / reduce) Qui soient efficaces ! Éventuellement parallèles
![Page 16: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/16.jpg)
#J8Stream @JosePaumard
Objet de la présentationObjet de la présentation
• Présenter trois API Exposer les concepts fondamentaux Présenter les fonctions implémentées Montrer des patterns de code (Java 8, lambdas)
• Comparer ces API Point de vue de l’utilisateur Performances !
![Page 17: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/17.jpg)
#J8Stream @JosePaumard
Objet de la présentationObjet de la présentation
• Proposer une grille de lecture et d’analyse Comparer des outils qui proposent des solutions
différentes pour un même problème
![Page 18: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/18.jpg)
#J8Stream @JosePaumard
Objet de la présentationObjet de la présentation
• Proposer une grille de lecture et d’analyse Comparer des outils qui proposent des solutions
différentes pour un même problème
• Du point de vue du développeur
![Page 19: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/19.jpg)
#J8Stream @JosePaumard
Objet de la présentationObjet de la présentation
• Proposer une grille de lecture et d’analyse Comparer des outils qui proposent des solutions
différentes pour un même problème
• Du point de vue du développeur Performance Patterns écriture / lecture
![Page 20: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/20.jpg)
![Page 21: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/21.jpg)
![Page 22: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/22.jpg)
![Page 23: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/23.jpg)
![Page 24: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/24.jpg)
![Page 25: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/25.jpg)
#J8Stream @JosePaumard
Questions ?
#J8Stream
Questions ?
#J8Stream
![Page 26: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/26.jpg)
#J8Stream @JosePaumard
Les forces en présenceLes forces en présence
• Les 3 API sont : L’API Stream de Java 8
![Page 27: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/27.jpg)
#J8Stream @JosePaumard
Les forces en présenceLes forces en présence
• Les 3 API sont : L’API Stream de Java 8 GS Collections
![Page 28: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/28.jpg)
#J8Stream @JosePaumard
Les forces en présenceLes forces en présence
• Les 3 API sont : L’API Stream de Java 8 GS Collections RxJava
![Page 29: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/29.jpg)
#J8Stream @JosePaumard
Les forces en présenceLes forces en présence
• Les 3 API sont : L’API Stream de Java 8 GS Collections RxJava
• Comparaison des performances sur un exemple commun
![Page 30: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/30.jpg)
#J8Stream @JosePaumard
API Stream
![Page 31: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/31.jpg)
#J8Stream @JosePaumard
API StreamAPI Stream
• Qu’est-ce qu’un Stream Java 8 ? Un objet que l’on connecte à une source
![Page 32: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/32.jpg)
#J8Stream @JosePaumard
API StreamAPI Stream
• Qu’est-ce qu’un Stream Java 8 ? Un objet que l’on connecte à une source Un objet qui ne porte pas les données qu’il traite
![Page 33: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/33.jpg)
#J8Stream @JosePaumard
API StreamAPI Stream
• Qu’est-ce qu’un Stream Java 8 ? Un objet que l’on connecte à une source Un objet qui ne porte pas les données qu’il traite Un objet qui expose le pattern map / filter / reduce
![Page 34: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/34.jpg)
#J8Stream @JosePaumard
API StreamAPI Stream
• Qu’est-ce qu’un Stream Java 8 ? Un objet que l’on connecte à une source Un objet qui ne porte pas les données qu’il traite Un objet qui expose le pattern map / filter / reduce
• Nouveau concept introduit dans le JDK
![Page 35: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/35.jpg)
#J8Stream @JosePaumard
API StreamAPI Stream
• ExempleList<String> liste = Arrays.asList("un", "deux", "trois") ;
liste.stream() .map(s ‐> s.toUpperCase()).max(Comparator.comparing(s ‐> s.length())).ifPresent(s ‐> System.out.println(s)) ;
![Page 36: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/36.jpg)
#J8Stream @JosePaumard
API StreamAPI Stream
• ExempleList<String> liste = Arrays.asList("un", "deux", "trois") ;
liste.stream() // ouverture d’un stream de String.map(s ‐> s.toUpperCase()) .max(Comparator.comparing(s ‐> s.length())).ifPresent(s ‐> System.out.println(s)) ;
![Page 37: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/37.jpg)
#J8Stream @JosePaumard
API StreamAPI Stream
• ExempleList<String> liste = Arrays.asList("un", "deux", "trois") ;
liste.stream().map(s ‐> s.toUpperCase()) // mise en majuscules des éléments.max(Comparator.comparing(s ‐> s.length())).ifPresent(s ‐> System.out.println(s)) ;
![Page 38: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/38.jpg)
#J8Stream @JosePaumard
API StreamAPI Stream
• ExempleList<String> liste = Arrays.asList("un", "deux", "trois") ;
liste.stream().map(s ‐> s.toUpperCase()).max(Comparator.comparing(s ‐> s.length())) // plus longue.ifPresent(s ‐> System.out.println(s)) ;
![Page 39: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/39.jpg)
#J8Stream @JosePaumard
API StreamAPI Stream
• ExempleList<String> liste = Arrays.asList("un", "deux", "trois") ;
liste.stream().map(s ‐> s.toUpperCase()).max(Comparator.comparing(s ‐> s.length())).ifPresent(s ‐> System.out.println(s)) ; // Optional !
![Page 40: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/40.jpg)
#J8Stream @JosePaumard
API StreamAPI Stream
• ExempleList<String> liste = Arrays.asList("un", "deux", "trois") ;
liste.stream().map(String::toUpperCase).max(Comparator.comparing(String::length).ifPresent(System.out::println) ; // Optional !
![Page 41: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/41.jpg)
#J8Stream @JosePaumard
CollectorsCollectors
• On peut collecter des donnéesList<Person> liste = ... ;
liste.stream().filter(person ‐> person.getAge() > 30).collect(Collectors.groupingBy(
Person::getAge, // key extractorCollectors.counting() // downstream collector
)) ;
![Page 42: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/42.jpg)
#J8Stream @JosePaumard
CollectorsCollectors
• On peut collecter des donnéesList<Person> liste = ... ;
liste.stream().filter(person ‐> person.getAge() > 30).collect(Collectors.groupingBy(
Person::getAge, // key extractorCollectors.counting() // downstream collector
)) ;
![Page 43: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/43.jpg)
#J8Stream @JosePaumard
CollectorsCollectors
• On peut collecter des donnéesList<Person> liste = ... ;
Map<Integer, Long> map = liste.stream()
.filter(person ‐> person.getAge() > 30)
.collect(Collectors.groupingBy(
Person::getAge, // key extractorCollectors.counting() // downstream collector
)) ;
![Page 44: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/44.jpg)
#J8Stream @JosePaumard
CollectorsCollectors
• Et on peut paralléliser les traitementsList<Person> liste = ... ;
Map<Integer, Long> map = liste.stream().parallel()
.filter(person ‐> person.getAge() > 30)
.collect(Collectors.groupingBy(
Person::getAge, // key extractorCollectors.counting() // downstream collector
)) ;
![Page 45: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/45.jpg)
#J8Stream @JosePaumard
Particularisation d’un StreamParticularisation d’un Stream
• On peut le connecter à sa propre source de données Implémenter un Spliterator (~ Iterator)
![Page 46: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/46.jpg)
#J8Stream @JosePaumard
Particularisation d’un StreamParticularisation d’un Stream
• On peut le connecter à sa propre source de données Implémenter un Spliterator (~ Iterator)
• On peut implémenter son propre Collector
![Page 47: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/47.jpg)
#J8Stream @JosePaumard
GS Collections
![Page 48: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/48.jpg)
#J8Stream @JosePaumard
IntroductionIntroduction
• API Open source, Github• Développé par Goldman Sachs• Contribution importante
https://github.com/goldmansachs/gs-collections
![Page 49: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/49.jpg)
#J8Stream @JosePaumard
GS CollectionsGS Collections
• Une alternative à l’API Collection Parfois très ressemblante…
• Des interfaces supplémentaires Beaucoup ! Des méthodes supplémentaires sur les interfaces
existantes
![Page 50: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/50.jpg)
#J8Stream @JosePaumard
GS CollectionsGS Collections
• Nouveaux concepts ?
![Page 51: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/51.jpg)
#J8Stream @JosePaumard
GS CollectionsGS Collections
• Nouveaux concepts ?
• Oui et non…
![Page 52: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/52.jpg)
#J8Stream @JosePaumard
GS CollectionsGS Collections
• Nouveaux concepts ?
• Oui et non… Bag
![Page 53: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/53.jpg)
#J8Stream @JosePaumard
GS CollectionsGS Collections
• Nouveaux concepts ?
• Oui et non… Bag MultiMap
![Page 54: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/54.jpg)
#J8Stream @JosePaumard
GS CollectionsGS Collections
• Nouveaux concepts ?
• Oui et non… Bag MultiMap MutableSet
![Page 55: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/55.jpg)
#J8Stream @JosePaumard
GS CollectionsGS Collections
• Nouveaux concepts ?
• Plutôt des extensions des concepts de l’API Collection
![Page 56: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/56.jpg)
#J8Stream @JosePaumard
GS CollectionsGS Collections
• Nouveaux concepts ?
• Plutôt des extensions des concepts de l’API Collection Certains sont dans Common collections ou Guava
![Page 57: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/57.jpg)
#J8Stream @JosePaumard
Structures fondamentalesStructures fondamentales
• Bag = Collection• Existe en plusieurs couleurs !
![Page 58: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/58.jpg)
#J8Stream @JosePaumard
Structures fondamentalesStructures fondamentales
• Bag = Collection• Existe en plusieurs couleurs !
• Primitifs : IntBag, LongBag, …
![Page 59: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/59.jpg)
#J8Stream @JosePaumard
Structures fondamentalesStructures fondamentales
• Bag = Collection• Existe en plusieurs couleurs !
• Primitifs : IntBag, LongBag, …• ImmutableBag, MutableBag
![Page 60: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/60.jpg)
#J8Stream @JosePaumard
Structures fondamentalesStructures fondamentales
• Bag = Collection• Existe en plusieurs couleurs !
• Primitifs : IntBag, LongBag, …• ImmutableBag, MutableBag• Sorted, Unsorted
![Page 61: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/61.jpg)
#J8Stream @JosePaumard
Structures fondamentalesStructures fondamentales
• Bag = Collection• Existe en plusieurs couleurs !
• Primitifs : IntBag, LongBag, …• ImmutableBag, MutableBag• Sorted, Unsorted• Synchronized
![Page 62: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/62.jpg)
#J8Stream @JosePaumard
Structures fondamentalesStructures fondamentales
• Bag, List, Set, Stack, Map, Multimap
![Page 63: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/63.jpg)
#J8Stream @JosePaumard
Structures fondamentalesStructures fondamentales
• Bag, List, Set, Stack, Map, Multimap• Nombreuses implémentations
![Page 64: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/64.jpg)
#J8Stream @JosePaumard
BagBag
• Méthodes originales type CollectionBag<Person> bag = ... ;
int numberOfPaul = bag.occurenceOf(paul) ;
![Page 65: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/65.jpg)
#J8Stream @JosePaumard
BagBag
• Méthodes originales type CollectionBag<Person> bag = ... ;
int numberOfPaul = bag.occurenceOf(paul) ;int numberOfDistinct = bag.sizeDistinct() ;
![Page 66: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/66.jpg)
#J8Stream @JosePaumard
BagBag
• Méthodes originales type CollectionBag<Person> bag = ... ;
int numberOfPaul = bag.occurenceOf(paul) ;int numberOfDistinct = bag.sizeDistinct() ;
Bag<Customer> customers = bag.instanceOf(Customer.class) ;
![Page 67: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/67.jpg)
#J8Stream @JosePaumard
BagBag
• Méthodes originales type CollectionBag<Person> bag = ... ;
Partition<Person> partition = bag.partition(person ‐> person.getAge() > 30) ;
![Page 68: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/68.jpg)
#J8Stream @JosePaumard
BagBag
• Méthodes originales type CollectionBag<Person> bag = ... ;
Partition<Person> partition = bag.partition(person ‐> person.getAge() > 30) ;
Bag<Person> selected = partition.getSelected() ;Bag<Person> rejected = partition.getRejected() ;
![Page 69: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/69.jpg)
#J8Stream @JosePaumard
BagBag
• Méthodes originales type CollectionBag<Person> bag = ... ;
Partition<Person> partition = bag.partition(person ‐> person.getAge() > 30) ;
Bag<Person> selected = partition.getSelected() ;Bag<Person> rejected = partition.getRejected() ;
Bag<Person> selected = bag.select(person ‐> person.getAge() > 30) ;Bag<Person> rejected = bag.reject(person ‐> person.getAge() > 30) ;
![Page 70: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/70.jpg)
#J8Stream @JosePaumard
BagBag
• Méthode forEach()Bag<Person> bag = ... ;
bag.forEach(System.out::println) ;
![Page 71: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/71.jpg)
#J8Stream @JosePaumard
BagBag
• Méthode forEach()Bag<Person> bag = ... ;
bag.forEach(System.out::println) ; // compiler error
![Page 72: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/72.jpg)
#J8Stream @JosePaumard
BagBag
• Méthode forEach()Bag<Person> bag = ... ;
bag.forEach(System.out::println) ; // compiler error
public interface Iterable<T> { // java.util
default void forEach(Consumer<? super T> action) {...}}
![Page 73: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/73.jpg)
#J8Stream @JosePaumard
BagBag
• Méthode forEach()Bag<Person> bag = ... ;
bag.forEach(System.out::println) ; // compiler error
public interface InternalIterable<T> { // GS Collection
void forEach(Procedure<? super T> procedure) ;}
![Page 74: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/74.jpg)
#J8Stream @JosePaumard
BagBag
• Méthode forEach()Bag<Person> bag = ... ;
bag.forEach((Procedure<String>)System.out::println) ;
![Page 75: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/75.jpg)
#J8Stream @JosePaumard
BagBag
• Méthodes map & filterBag<Person> bag = ... ;
Bag<String> names = bag.collect(Person::getAge) ; // eq. map()Bag<String> names = bag.select(p ‐> p.getAge() > 30) ; // eq filter()
![Page 76: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/76.jpg)
#J8Stream @JosePaumard
BagBag
• Méthodes map & filterBag<Person> bag = ... ;
Bag<String> names = bag.collect(Person::getAge) ; // eq. map()Bag<String> names = bag.select(p ‐> p.getAge() > 30) ; // eq filter()
Bag<T> tap(Procedure<? super T> procedure) ;
![Page 77: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/77.jpg)
#J8Stream @JosePaumard
BagBag
• Méthodes map & flatMapBag<T> collect( // eq. map()
Function<? super T, ? extends V> function) {...}
Bag<T> flatCollect( // eq. flatMap()Function<? super T, ? extends Iterable<V>> function) {...}
![Page 78: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/78.jpg)
#J8Stream @JosePaumard
BagBag
• Méthodes map & filter fusionnéesBag<Person> bag = ... ;
names = bag.collectIf(person ‐> person.getAge() > 30, Peson::getName) ;
![Page 79: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/79.jpg)
#J8Stream @JosePaumard
BagBag
• Méthodes de réductionBag<Person> bag = ... ;
boolean b1 = bag.allSatisfy(person ‐> person.getAge() > 30) ;
boolean b2 = bag.anySatisfy(person ‐> person.getAge() > 100) ;
boolean b3 = bag.noneSatisfy(person ‐> person.getAge() < 18) ;
![Page 80: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/80.jpg)
#J8Stream @JosePaumard
BagBag
• Méthodes de réductionBag<Person> bag = ... ;
Person first = bag.detect(person ‐> person.getAge() > 30) ;
Person p = bag.detectIfNone(person ‐> person.getAge() > 100, () ‐> Person.NOBODY) ;
![Page 81: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/81.jpg)
#J8Stream @JosePaumard
BagBag
• Méthodes de réductionBag<Person> bag = ... ;
Person first = bag.detectWith((person, param) ‐> person.getAge() > param, 30) ;
Person p = bag.detectWithIfNone((person, param) ‐> person.getAge() > param, 100, () ‐> Person.NOBODY) ;
![Page 82: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/82.jpg)
#J8Stream @JosePaumard
BagBag
• Méthodes de foldingBag<Person> bag = ... ;
long sum = bag.injectInto(0L, (sum, person) ‐> sum + person.getAge()) ;
long count = bag.injectInto(0L, (sum, person) ‐> sum + 1L) ;
![Page 83: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/83.jpg)
#J8Stream @JosePaumard
BagBag
• Méthodes de foldingBag<Person> bag = ... ;
long sum = bag.injectInto(0L, (l, person) ‐> l + person.getAge()) ;
long sumOfAge = bag.sumOfInt(Person::getAge)) ;
![Page 84: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/84.jpg)
#J8Stream @JosePaumard
BagBag
• Méthodes de foldingBag<Person> bag = ... ;
String names = bag.collect(Person::getName).makeString() ;
Charles, Michelle, Paul, Barbara
![Page 85: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/85.jpg)
#J8Stream @JosePaumard
BagBag
• Réduction dans une chaîne de caractèresBag<Person> bag = ... ;
String names = bag.collect(Person::getAge).makeString() ;
String names = bag.collect(Person::getAge).makeString(" ; ") ;
Charles ; Michelle ; Paul ; Barbara
![Page 86: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/86.jpg)
#J8Stream @JosePaumard
BagBag
• Réduction dans une chaîne de caractèresBag<Person> bag = ... ;
String names = bag.collect(Person::getAge).makeString() ;
String names = bag.collect(Person::getAge).makeString(" ; ") ;
String names = bag.collect(Person::getAge).makeString("{", " ; ", "}") ;
{Charles ; Michelle ; Paul ; Barbara}
![Page 87: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/87.jpg)
#J8Stream @JosePaumard
BagBag
• Réduction dans une chaîne de caractèresBag<Person> bag = ... ;
bag.collect(Person::getAge).appendString(StringBuilder::new) ;
![Page 88: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/88.jpg)
#J8Stream @JosePaumard
BagBag
• Réduction dans une table de hachageBag<Person> bag = ... ;
MapIterable<Integer, Bag<Person>> map = bag.aggregateBy(
Person::getAge, // key extractorFastList::new, // zero factory(list, person) ‐> { //
list.add(person) ; // merge operationreturn list ; //
}) ;
![Page 89: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/89.jpg)
#J8Stream @JosePaumard
BagBag
• Réduction dans une table de hachageBag<Person> bag = ... ;
MultiMap<Integer, Person> map = bag.groupBy(Person::getAge) ;
![Page 90: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/90.jpg)
#J8Stream @JosePaumard
MutableMapMutableMap
• Méthodes de MapV getIfAbsentPut(K key,
Function0<? extends V> function) ;
V getIfAbsentPutWithKey(K key, Function<? super K, ? extends V> function) ;
V getIfAbsentPutWith(K key, Function<? super P, ? extends V> functionP parameter) ;
![Page 91: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/91.jpg)
#J8Stream @JosePaumard
MutableMapMutableMap
• Méthodes forEach()void forEachKeyValue(Procedure2<? super K, ? super V> procedure) ;
void forEachKey(Procedure<? super T> procedure) ;
void forEachValue(Procedure<? super T> procedure) ;
![Page 92: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/92.jpg)
#J8Stream @JosePaumard
MutableMapMutableMap
• Méthodes map
• Une table de hachage est aussi une liste de valeurs
MapIterable<K2, V2> collect(Function2<? super K, ? super V, Pair<K2, V2>> function) ;
public interface MapIterable<K, V> extends RichIterable<V> {}
![Page 93: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/93.jpg)
#J8Stream @JosePaumard
PairPair
• Modélisation d’un tuplepublic interface Pair<T1, T2>
extends Serializable, Comparable<Pair<T1, T2>> {
T1 getOne();T2 getTwo();
void put(Map<T1, T2> map);
Map.Entry<T1, T2> toEntry(); // pont avec API Collection Pair<T2, T1> swap();
}
![Page 94: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/94.jpg)
#J8Stream @JosePaumard
MutableMapMutableMap
• Les méthodes map, filter et méthodes de réduction sont définies sur RichIterable Donc disponibles sur les tables de hachage Elles opèrent sur les valeurs
• Méthodes groupBy, retournent de nouvelles tables
reject(Predicate2<? super K, ? super V> predicate) ;
select(Predicate2<? super K, ? super V> predicate) ;
![Page 95: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/95.jpg)
#J8Stream @JosePaumard
ImmutableMapImmutableMap
• Méthodes pour « ajouter » des clés / valeursMutableMapIterable<K, V> withKeyValue(K key, V value) ; // put
MutableMapIterable<K, V> withoutKey(K key) ; // remove
![Page 96: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/96.jpg)
#J8Stream @JosePaumard
MultiMapMultiMap
• Concept qui ne fait pas partie de l’API Collection• Map qui associe plusieurs valeurs à une même clé Gère une collection de valeurs en interne
MultiMap<Integer, Person> map ; // GS Collections
Map<Integer, List<Person>> map ; // API Collection
![Page 97: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/97.jpg)
#J8Stream @JosePaumard
MultiMapMultiMap
• La plupart des méthodes sont les mêmes• Méthodes get différentesRichIterable<V> values = multiMap.get(K key) ;
MutableMap<K, RichIterable<V>> map = multiMap.toMap() ;
![Page 98: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/98.jpg)
#J8Stream @JosePaumard
Structures concurrentesStructures concurrentes
• ConcurrentHashMap Construite sur un tableau de Entry
(AtomicReferenceArray) Accès via des AtomicReference Même structure que java.util.HashMap
![Page 99: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/99.jpg)
#J8Stream @JosePaumard
Opérations de type ZipOpérations de type Zip
• Permet d’appairer deux ensemblesBag<Person> bag1 = ImmutableBagImpl.of(anna, charles) ;Bag<Person> bag2 = ImmutableBagImpl.of(paul, barbara) ;
Bag<Pair<Person, Person>> friends = bag1.zip(bag2) ;
![Page 100: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/100.jpg)
#J8Stream @JosePaumard
Opérations de type ZipOpérations de type Zip
• Permet d’appairer deux ensemblesBag<Person> bag1 = ImmutableBagImpl.of(anna, charles) ;Bag<Person> bag2 = ImmutableBagImpl.of(paul, barbara) ;Bag<City> bag3 = ImmutableBagImpl.of(paris, sanFrancisco) ;
Bag<Pair<Person, Person>> friends = bag1.zip(bag2) ;
Bag<Pair<Person, City>> living = bag1.zip(bag3) ;
![Page 101: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/101.jpg)
#J8Stream @JosePaumard
Opérations de type ZipOpérations de type Zip
• Permet d’appairer deux ensemblesBag<Person> bag1 = ImmutableBagImpl.of(anna, charles) ;Bag<Person> bag2 = ImmutableBagImpl.of(paul, barbara) ;Bag<City> bag3 = ImmutableBagImpl.of(paris, sanFrancisco) ;
Bag<Pair<Person, Person>> friends = bag1.zip(bag2) ;
Bag<Pair<Person, City>> living = bag1.zip(bag3) ;
Bag<Pair<City, Integer>> cities = bag3.zipWithIndex() ;
![Page 102: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/102.jpg)
#J8Stream @JosePaumard
Classes factoryClasses factory
• Factory pour Bag, List, Set, Stack, MapBag<Long> bagOfInteger = MutableBagFactoryImpl.of(1L, 2L, 5L) ;
Bag<Person> bagOfPerson = MutableBagFactoryImpl.of(persons) ;
![Page 103: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/103.jpg)
#J8Stream @JosePaumard
Implémentations Implémentations
• Pas de miracle à attendre…// class FastListpublic boolean add(T newItem) {
if (this.items.length == this.size) {this.ensureCapacityForAdd();
}this.items[this.size++] = newItem;return true;
}
![Page 104: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/104.jpg)
#J8Stream @JosePaumard
Implémentations Implémentations
• Pas de miracle à attendre…// class FastListpublic boolean add(T newItem) {
if (this.items.length == this.size) {this.ensureCapacityForAdd();
}this.items[this.size++] = newItem;return true;
}
// class ArrayListpublic boolean add(E e) {
ensureCapacityInternal(size + 1);elementData[size++] = e;return true;
}
![Page 105: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/105.jpg)
#J8Stream @JosePaumard
Implémentations Implémentations
• Une implémentation est différente : celle des tables de hachage Fonctionne avec un tableau unique
![Page 106: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/106.jpg)
#J8Stream @JosePaumard
Bizarreries Bizarreries
• Quelques bizarreriesMutableMap<K, V> map1 = map.asUnmodifiable() ; // UnmodifiableMap ?
![Page 107: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/107.jpg)
#J8Stream @JosePaumard
Bilan sur l’APIBilan sur l’API
• Une API complète (complexe)• Concept de MultiMap• Des méthodes que l’on trouve sur Stream Ajoutées aux collections
• Des méthodes supplémentaires Que l’on aura peut-être sur Stream (zip)
![Page 108: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/108.jpg)
#J8Stream @JosePaumard
RxJava
![Page 109: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/109.jpg)
#J8Stream @JosePaumard
RxJavaRxJava
• API Open source, Github• Développé par Netflix• Version Java de ReactiveX .NET Python, Kotlin, JavaScript, Scala, Ruby, Groovy, Rust Android
https://github.com/ReactiveX/RxJava
![Page 110: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/110.jpg)
#J8Stream @JosePaumard
Vue d’ensembleVue d’ensemble
• Approche différente de GS Collections• Il ne s’agit pas d’une implémentation alternative de
l’API Collection
• Mais plutôt de l’implémentation du pattern Reactor
![Page 111: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/111.jpg)
#J8Stream @JosePaumard
Pattern ReactorPattern Reactor
• Set (fixed size, mutable, immutable, primitifs)• SortedSet (fixed size, mutable, immutable, primitifs)• Pool• Stack (mutable, immutable, primitifs)
http://www.dre.vanderbilt.edu/~schmidt/PDF/reactor-siemens.pdf
![Page 112: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/112.jpg)
#J8Stream @JosePaumard
Notions fondamentalesNotions fondamentales
• Observable : source de données
![Page 113: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/113.jpg)
#J8Stream @JosePaumard
Notions fondamentalesNotions fondamentales
• Observable : source de données Objet complexe ~100 méthodes statiques + ~150
méthodes non statiques
![Page 114: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/114.jpg)
#J8Stream @JosePaumard
Notions fondamentalesNotions fondamentales
• Observable : source de données Objet complexe ~100 méthodes statiques + ~150
méthodes non statiques• Observer : permet d’observer un observable Objet simple : 3 méthodes
![Page 115: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/115.jpg)
#J8Stream @JosePaumard
Notions fondamentalesNotions fondamentales
• Observable : source de données Objet complexe ~100 méthodes statiques + ~150
méthodes non statiques• Observer : permet d’observer un observable Objet simple : 3 méthodes
• Subscription : lien qui existe entre un observable et un observer
![Page 116: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/116.jpg)
#J8Stream @JosePaumard
Notions fondamentalesNotions fondamentales
• Observerpublic interface Observer<T> {
public void onNext(T t);
public void onCompleted();
public void onError(Throwable e);}
![Page 117: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/117.jpg)
#J8Stream @JosePaumard
Notions fondamentalesNotions fondamentales
• Associer un observer à un observableObservable<T> observable = ... ;
Subscription subscription = observable.subscribe(observer) ;
public interface Subscription {
public void unsubscribe();
public void isUnsubscribe();}
![Page 118: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/118.jpg)
#J8Stream @JosePaumard
Création d’un ObservableCréation d’un Observable
• Constructeur non vide protégé
![Page 119: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/119.jpg)
#J8Stream @JosePaumard
Création d’un ObservableCréation d’un Observable
• Constructeur non vide protégé• On peut construire un Observable par extension en utilisant une des méthodes statiques
![Page 120: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/120.jpg)
#J8Stream @JosePaumard
Création d’un ObservableCréation d’un Observable
• Constructeur non vide protégé• On peut construire un Observable par extension en utilisant une des méthodes statiques
• Prend un producer en paramètre
![Page 121: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/121.jpg)
#J8Stream @JosePaumard
Création d’un ObservableCréation d’un Observable
• Création à partir de collectionsObservable<String> obs1 = Observable.just("one", "two", "three") ;
List<String> strings = Arrays.asList("one", "two", "three") ;Observable<String> obs2 = Observable.from(strings) ;
![Page 122: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/122.jpg)
#J8Stream @JosePaumard
Création d’un ObservableCréation d’un Observable
• Création à partir de collectionsObservable<String> obs1 = Observable.just("one", "two", "three") ;
List<String> strings = Arrays.asList("one", "two", "three") ;Observable<String> obs2 = Observable.from(strings) ;
Observable<String> empty = Observable.empty() ;Observable<String> never = Observable.never() ;Observable<String> error = Observable.<String>error(exception) ;
![Page 123: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/123.jpg)
#J8Stream @JosePaumard
Création d’un ObservableCréation d’un Observable
• Création de sériesObservable<Long> longs = Observable.range(1L, 100L) ;
![Page 124: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/124.jpg)
#J8Stream @JosePaumard
Création d’un ObservableCréation d’un Observable
• Création de sériesObservable<Long> longs = Observable.range(1L, 100L) ;
// intervalObservable<Long> timeSerie1 =
Observable.interval(1L, TimeUnit.MILLISECONDS) ; // a serie of longs
// initial delay, then intervalObservable<Long> timeSerie2 =
Observable.timer(10L, 1L, TimeUnit.MILLISECONDS) ; // one 0
![Page 125: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/125.jpg)
#J8Stream @JosePaumard
Création d’un ObservableCréation d’un Observable
• Méthode using()public final static <T, Resource> Observable<T> using(
final Func0<Resource> resourceFactory, // producerfinal Func1<Resource, Observable<T>> observableFactory, // functionfinal Action1<? super Resource> disposeAction // consumer
) { }
![Page 126: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/126.jpg)
#J8Stream @JosePaumard
Notion de SchedulerNotion de Scheduler
• Ces méthodes peuvent prendre un autre paramètre
• Scheduler : interface• Associée à la factory Schedulers
Observable<Long> longs = Observable.range(0L, 100L, scheduler) ;
![Page 127: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/127.jpg)
#J8Stream @JosePaumard
Notion de SchedulerNotion de Scheduler
• Factory Schedulerspublic final class Schedulers {
public static Scheduler immediate() {...} // immediate, same thread
public static Scheduler newThread() {...} // new thread
public static Scheduler computation() {...} // computation ES
public static Scheduler io() {...} // IO growing ES}
![Page 128: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/128.jpg)
#J8Stream @JosePaumard
Notion de SchedulerNotion de Scheduler
• Factory Schedulerspublic final class Schedulers {
public static Scheduler trampoline() {...} // queued in the current// thread
public static Scheduler test() {...}
public static Scheduler fromExecutor(Executor executor) {...}}
![Page 129: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/129.jpg)
#J8Stream @JosePaumard
Notion de SchedulerNotion de Scheduler
• RxJava permet de créer des Observable dans différents threads
• Certains pools sont spécialisés : IO, Computation• On peut passer ses propres pools
• Les observateurs sont appelés dans les threads des observables
![Page 130: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/130.jpg)
#J8Stream @JosePaumard
Notion de SchedulerNotion de Scheduler
• La classe Scheduler n’est pas immédiate à étendre
• On utilise from() pour les threads IHM (Swing, JavaFX)
![Page 131: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/131.jpg)
@JosePaumard
Pause café ?
#J8Stream
![Page 132: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/132.jpg)
@JosePaumard
Pause café !
#J8Stream
Encore du RxJavaPatterns
Extensions de StreamPerformance
![Page 133: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/133.jpg)
@JosePaumard
Les
sont parmi nous
![Page 134: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/134.jpg)
#J8Stream @JosePaumard
Observable : méthodes statiques Observable : méthodes statiques
• Série de méthodes statiques de combinaisons d’Observable en un seul
![Page 135: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/135.jpg)
#J8Stream @JosePaumard
Observable de listesObservable de listes
• amb() : prend une liste d’Observable et suit le premier qui parle
©RxJava
O1
O2
O1
![Page 136: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/136.jpg)
#J8Stream @JosePaumard
Observable de listesObservable de listes
• combineLatest() : applique une fonction aux deux derniers éléments émis
©RxJava
O1
O2
F(O1, O2)
![Page 137: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/137.jpg)
#J8Stream @JosePaumard
Observable de listesObservable de listes
• zip() : équivalent d’un combine, mais prend les éléments un par un
©RxJava
O1
O2
F(O1, O2)
![Page 138: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/138.jpg)
#J8Stream @JosePaumard
Observable de listesObservable de listes
• concat() : émet O1 puis O2, sans les mélanger• merge() : émet O1 et O2, s’arrête sur erreur
![Page 139: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/139.jpg)
#J8Stream @JosePaumard
Observable de listesObservable de listes
• concat() : émet O1 puis O2, sans les mélanger• merge() : émet O1 et O2, s’arrête sur erreur
©RxJava©RxJava
![Page 140: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/140.jpg)
#J8Stream @JosePaumard
Observable de listesObservable de listes
• concat() : émet O1 puis O2, sans les mélanger• merge() : émet O1 et O2, s’arrête avec le premier• mergeDelayError() : reporte l’erreur à la fin
©RxJava
![Page 141: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/141.jpg)
#J8Stream @JosePaumard
Observable de listesObservable de listes
• sequenceEqual() : compare deux séquences
©RxJava
O1
O2
boolean
![Page 142: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/142.jpg)
#J8Stream @JosePaumard
Observable d’ObservableObservable d’Observable
• switchOnNext() : un peu spécial…
![Page 143: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/143.jpg)
#J8Stream @JosePaumard
Observable d’ObservableObservable d’Observable
• Paramètres des méthodes précédentes :public final static <T> Observable<T> merge(
Iterable<Observable<T>> listOfSequences) { }
![Page 144: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/144.jpg)
#J8Stream @JosePaumard
Observable d’ObservableObservable d’Observable
• Paramètres des méthodes précédentes :public final static <T> Observable<T> merge(
Iterable<Observable<T>> listOfSequences) { }
public final static <T> Observable<T> merge(Observable<Observable<T>> sequenceOfSequences) { }
![Page 145: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/145.jpg)
#J8Stream @JosePaumard
Observable d’ObservableObservable d’Observable
• Paramètres des méthodes précédentes :public final static <T> Observable<T> merge(
Iterable<Observable<T>> listOfSequences) { }
©RxJava
![Page 146: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/146.jpg)
#J8Stream @JosePaumard
Observable d’ObservableObservable d’Observable
• Paramètres des méthodes précédentes :public final static <T> Observable<T> merge(
Observable<Observable<T>> sequenceOfSequences) { }
©RxJava
![Page 147: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/147.jpg)
#J8Stream @JosePaumard
Observable d’ObservableObservable d’Observable
• switchOnNext() : prend le nouvel Observable
©RxJava
public final static <T> Observable<T> switchOnNext(Observable<Observable<T>> sequenceOfSequences) { }
![Page 148: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/148.jpg)
#J8Stream @JosePaumard
ExemplesExemples
• Un petit cas simpleObservable<Integer> range1To100 = Observable.range(1L, 100L) ;manyStrings.subscribe(System.out::println) ;
![Page 149: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/149.jpg)
#J8Stream @JosePaumard
ExemplesExemples
• Un petit cas simpleObservable<Integer> range1To100 = Observable.range(1L, 100L) ;manyStrings.subscribe(System.out::println) ;
> 1 2 3 4 ... 100
![Page 150: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/150.jpg)
#J8Stream @JosePaumard
ExemplesExemples
• Un petit cas un peu plus durObservable<Integer> timer = Observable.timer(1, TimeUnit.SECONDS) ;timer.subscribe(System.out::println) ;
![Page 151: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/151.jpg)
#J8Stream @JosePaumard
ExemplesExemples
• Un petit cas un peu plus dur
• N’affiche rien…
Observable<Integer> timer = Observable.timer(1, TimeUnit.SECONDS) ;timer.subscribe(System.out::println) ;
>
![Page 152: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/152.jpg)
#J8Stream @JosePaumard
ExemplesExemples
• Un petit cas un peu plus durObservable<Integer> timer = Observable.timer(1, TimeUnit.SECONDS) ;timer.subscribe(() ‐> {
System.out.println(Thread.currentThread().getName() + " " + Thread.currentThread().isDaemon()) ;
}) ;Thread.sleep(2) ;
![Page 153: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/153.jpg)
#J8Stream @JosePaumard
ExemplesExemples
• Un petit cas un peu plus durObservable<Integer> timer = Observable.timer(1, TimeUnit.SECONDS) ;timer.subscribe(() ‐> {
System.out.println(Thread.currentThread().getName() + " " + Thread.currentThread().isDaemon()) ;
}) ;Thread.sleep(2) ;
> RxComputationThreadPool‐1 ‐ true
![Page 154: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/154.jpg)
#J8Stream @JosePaumard
ExemplesExemples
• Encore un peu plus durObservable<Integer> range1To100 = Observable.range(1, 100) ;
Observable<String> manyStrings = Observable.combineLatest(
range1To100, Observable.just("one"),(integer, string) ‐> string) ;
![Page 155: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/155.jpg)
#J8Stream @JosePaumard
ExemplesExemples
• Encore un peu plus durObservable<Integer> range1To100 = Observable.range(1, 100) ;
Observable<String> manyStrings = Observable.combineLatest(
range1To100, Observable.just("one"),(integer, string) ‐> string) ;
> one (et c’est tout)
Combines two source Observables by emitting an item that aggregatesthe latest values of each of the source Observables each time an item is received from either of the source Observables, where this aggregation is defined by a specified function.
![Page 156: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/156.jpg)
#J8Stream @JosePaumard
ExemplesExemples
• Encore un peu plus durObservable<Integer> serie = Observable.interval(3, TimeUnit.MILLISECONDS) ;
Observable<String> manyStrings = Observable.combineLatest(
serie, Observable.just("one"),(integer, string) ‐> string) ;
![Page 157: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/157.jpg)
#J8Stream @JosePaumard
ExemplesExemples
• Encore un peu plus durObservable<Integer> serie = Observable.interval(3, TimeUnit.MILLISECONDS) ;
Observable<String> manyStrings = Observable.combineLatest(
serie, Observable.just("one"),(integer, string) ‐> string) ;
> one one one one one one ...
![Page 158: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/158.jpg)
#J8Stream @JosePaumard
Observables hot & coldObservables hot & cold
• Deux mécanismes d’Observable : Ceux qui émettent des données lorsqu’elles sont
consommées = cold observables Ceux qui émettent des données, qu’elles soient
consommées ou pas = hot observables• Un hot observable peut générer ses données
indépendamment de ses observateurs
![Page 159: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/159.jpg)
#J8Stream @JosePaumard
Méthodes d’instance
![Page 160: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/160.jpg)
#J8Stream @JosePaumard
Opérations callbackOpérations callback
• Retournent un Observable<T>
• ~10 versions doOn*
doOnNext(Action1<T> onNext) { } // consumer
![Page 161: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/161.jpg)
#J8Stream @JosePaumard
Opérations booléennesOpérations booléennes
• Retournent un Observable<Boolean>
• Retournent un Observable<T> vide ou singleton
exists(Func1<T, Boolean> predicate) { }elementAt(int index) { }
ignoreElement() { } // returns an empty Observablesingle() { } // completes on error or transmitssingle(Func1<T, Boolean> predicate) { } // returns the item or error
![Page 162: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/162.jpg)
#J8Stream @JosePaumard
Opérations de mappingOpérations de mapping
• Retournent un Observable<R>map(Func1<T, R> mapping) { } cast(Class<R> clazz) { } // casts the elementstimestamp() { } // wraps the elements in a timestamped object
zipWith(Observable<U> other, Func2<T, U, R> zipFunction) { } // BiFunction
flatMap(Func1<T, Observable<R>> mapping) { }
![Page 163: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/163.jpg)
#J8Stream @JosePaumard
Opérations de filtrageOpérations de filtrage
• Retourne un Observable<T>filter(Func1<T, Boolean> predicate) { }
![Page 164: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/164.jpg)
#J8Stream @JosePaumard
Opérations de sélectionOpérations de sélection
• Retournent un Observable<R>sample(long period, TimeUnit timeUnit) { }
©RxJava
O1
sampler
![Page 165: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/165.jpg)
#J8Stream @JosePaumard
Opérations de sélectionOpérations de sélection
• Retournent un Observable<R>sample(Observable<U> sampler) { } // samples on emission & completion
©RxJava
O1
sampler
![Page 166: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/166.jpg)
#J8Stream @JosePaumard
Remarque sur le tempsRemarque sur le temps
• RxJava peut mesurer le temps « en réel »• Peut aussi utiliser un Observable comme mesure du
temps Appels à onNext() et onComplete()
![Page 167: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/167.jpg)
#J8Stream @JosePaumard
Sélection d’élémentsSélection d’éléments
• Retournent Observable<T>
• Exception en cas de timeout entre deux émissions
first() { }last() { }skip(int n) { }limit(int n) { }take(int n) { }
timeout(long n, TimeUnit timeUnit) { }timeout(Func0<Observable<U>> firstTimeoutSelector, // producer
Func1<T, Observable<V>> timeoutSelector) { } // function
![Page 168: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/168.jpg)
#J8Stream @JosePaumard
Méthodes de réductionMéthodes de réduction
• Retourne un Observable<> singleton
• Retourne un Observable<T>
all(Func1<T, Boolean> predicate) { } // Observable<Boolean>count() { } // Observable<Long>reduce(Func2<T, T, T> accumulator) { } // Observable<T>
scan(Func2<T, T, T> accumulator) { } // Observable<T>
forEach(Action1<T> consumer) { } // void
![Page 169: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/169.jpg)
#J8Stream @JosePaumard
Méthodes de collectionMéthodes de collection
• Méthode collectcollect(Func0<R> stateFactory, // producer
Action2<R, T> collector) { } // BiConsumer
![Page 170: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/170.jpg)
#J8Stream @JosePaumard
Méthodes de collectionMéthodes de collection
• Méthode collect
• Construit une Map<T, List<String>>
collect(Func0<R> stateFactory, // producerAction2<R, T> collector) { } // BiConsumer
collect(() ‐> new ArrayList<String>(), // producerArrayList::add) { } // BiConsumer
![Page 171: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/171.jpg)
#J8Stream @JosePaumard
Méthodes de collectionMéthodes de collection
• Retournent des Observable<> singletontoList() { } // Observable<List<T>>toSortedList() { } // Observable<List<T>>
toMultimap(Func1<T, K> keySelector, // Observable<Func1<T, V> valueSelector) { } // Map<K, Collection<T>>
toMap(Func1<T, K> keySelector) { } // Observable<Map<K, T>>
![Page 172: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/172.jpg)
#J8Stream @JosePaumard
Opérations join / groupJoinOpérations join / groupJoin
• Retourne un Observable<GroupedObservable<K, T>>
• GroupedObservable : observable avec une clé
groupBy(Func1<T, K> keySelector) { } // function
![Page 173: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/173.jpg)
#J8Stream @JosePaumard
Opérations join / groupJoinOpérations join / groupJoin
• Combine deux observables, sur un timerpublic final <T2, D1, D2, R> Observable<R> groupJoin(
Observable<T2> right, Func1<T, Observable<D1>> leftDuration, // functionFunc1<T2, Observable<D2>> rightDuration, // functionFunc2<T, Observable<T2>, R> resultSelector // bifunction
) { }
![Page 174: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/174.jpg)
#J8Stream @JosePaumard
Opérations join / groupJoinOpérations join / groupJoin
• Les fenêtres de temps sont définies par des observables Elles démarrent lorsque l’observable démarre Et se ferment lorsque l’observable émet un objet ou
s’arrête
![Page 175: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/175.jpg)
#J8Stream @JosePaumard
Opérations join / groupJoinOpérations join / groupJoin
• Combine deux observables
![Page 176: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/176.jpg)
#J8Stream @JosePaumard
Méthodes de debugMéthodes de debug
• Deux méthodes, font du mapping
• Notification : objet qui englobe des meta-données en plus
materialize() { } // Observable<Notification<T>>
![Page 177: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/177.jpg)
#J8Stream @JosePaumard
Méthodes de debugMéthodes de debug
• Deux méthodes, font du mapping
• Notification : objet qui englobe des métadonnées en plus des objets de l’Observable
materialize() { } // Observable<Notification<T>>
dematerialize() { } // Observable<T>
![Page 178: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/178.jpg)
#J8Stream @JosePaumard
Méthodes synchronesMéthodes synchrones
• Associent des opérations avec une horlogedelay(long delay, TimeUnit timeUnit) ; // Observable<T>
![Page 179: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/179.jpg)
#J8Stream @JosePaumard
Méthodes synchronesMéthodes synchrones
• Associent des opérations avec une horloge
• Ou avec un autre Observable
delay(long delay, TimeUnit timeUnit) ; // Observable<T>
delay(Func1<T, Observable<U> func1) ; // Observable<T>
![Page 180: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/180.jpg)
#J8Stream @JosePaumard
Méthodes synchronesMéthodes synchrones
• Limite le nombre d’éléments émisdebounce(long delay, TimeUnit timeUnit) ; // Observable<T>
©RxJava
![Page 181: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/181.jpg)
#J8Stream @JosePaumard
Méthodes synchronesMéthodes synchrones
• Limite le nombre d’éléments émis
• Peut aussi se caler sur les événements d’un Observable
debounce(long delay, TimeUnit timeUnit) ; // Observable<T>
debounce(Func1<T, Observable<U> func1) ; // Observable<T>
![Page 182: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/182.jpg)
#J8Stream @JosePaumard
Méthodes synchronesMéthodes synchrones
• Mesure du temps entre événements
• TimeInterval : wrapper pour la durée en ms et la valeur émise
timeInterval() { } // Observable<TimeInterval<T>>
![Page 183: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/183.jpg)
#J8Stream @JosePaumard
Méthodes synchronesMéthodes synchrones
• Méthodes throttle()throttleFirst(long windowDuration, TimeUnit unit) { } // Observable<T>
throttleLast(long windowDuration, TimeUnit unit) { }
throttleWithTimeout(long windowDuration, TimeUnit unit) { }
![Page 184: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/184.jpg)
#J8Stream @JosePaumard
Backpressure
![Page 185: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/185.jpg)
#J8Stream @JosePaumard
Méthodes backpressureMéthodes backpressure
• Problème : une source peut générer « trop » d’éléments Par rapport à la vitesse des consommateurs
• Certaines méthodes permettent de « sauter » des éléments
![Page 186: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/186.jpg)
#J8Stream @JosePaumard
Méthodes backpressureMéthodes backpressure
• Problème : une source peut émettre « trop » d’éléments Par rapport à la vitesse des consommateurs
• Ne peut pas arriver avec les cold observables
![Page 187: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/187.jpg)
#J8Stream @JosePaumard
Méthodes backpressureMéthodes backpressure
• Problème : une source peut émettre « trop » d’éléments Par rapport à la vitesse des consommateurs
• Ne peut pas arriver avec les cold observables
• Un observable cold peut devenir hot…
![Page 188: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/188.jpg)
#J8Stream @JosePaumard
Méthodes backpressureMéthodes backpressure
• Certaines méthodes permettent de « sauter » des éléments
![Page 189: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/189.jpg)
#J8Stream @JosePaumard
Méthodes backpressureMéthodes backpressure
• Certaines méthodes permettent de « sauter » des éléments
• Backpressure : consiste à ralentir le rythme d’émission
![Page 190: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/190.jpg)
#J8Stream @JosePaumard
Méthodes backpressureMéthodes backpressure
• Méthodes utiles : sample() et debounce()• Méthode buffer() : stocke les éléments avant de les
émettre
![Page 191: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/191.jpg)
#J8Stream @JosePaumard
Méthodes backpressureMéthodes backpressure
• Méthodes buffer()buffer(int size) { } // Observable<List<T>>
![Page 192: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/192.jpg)
#J8Stream @JosePaumard
Méthodes backpressureMéthodes backpressure
• Méthodes buffer()buffer(int size) { } // Observable<List<T>>
buffer(long timeSpan, TimeUnit unit) { } // Observable<List<T>>buffer(long timeSpan, TimeUnit unit, int maxSize) { }
![Page 193: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/193.jpg)
#J8Stream @JosePaumard
Méthodes backpressureMéthodes backpressure
• Méthodes buffer()buffer(int size) { } // Observable<List<T>>
buffer(long timeSpan, TimeUnit unit) { } // Observable<List<T>>buffer(long timeSpan, TimeUnit unit, int maxSize) { }
buffer(Observable<O> bufferOpenings, // Openings eventsFunc1<O, Observable<C>> bufferClosings) { } // Closings events
![Page 194: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/194.jpg)
#J8Stream @JosePaumard
Méthodes backpressureMéthodes backpressure
• Méthodes window()window(int size) { } // Observable<Observable<T>>
window(long timeSpan, TimeUnit unit) { } // Observable<Observable<T>>window(long timeSpan, TimeUnit unit, int maxSize) { }
window(Observable<O> bufferOpenings, // Openings eventsFunc1<O, Observable<C>> bufferClosings) { } // Closings events
![Page 195: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/195.jpg)
#J8Stream @JosePaumard
Méthodes repeat & retryMéthodes repeat & retry
• repeat() : répète l’émission d’objets indéfinimentrepeat() { } // Observable<T>repeat(long times) { } // Observable<T>
![Page 196: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/196.jpg)
#J8Stream @JosePaumard
Méthodes repeat & retryMéthodes repeat & retry
• repeat() : répète l’émission d’objets indéfiniment
• Quand l’observable appelle onComplete(), le notification handler est invoqué
repeat() { } // Observable<T>repeat(long times) { } // Observable<T>
repeatWhen(Func1<Observable<Void>>, Observable<?>> notificationHandler
) { }
![Page 197: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/197.jpg)
#J8Stream @JosePaumard
Méthodes repeat & retryMéthodes repeat & retry
• repeat() : répète l’émission d’objets indéfiniment
• Sur cet Observable, le notification handler peut alors invoquer : onComplete() ou onError(), ce qui déclenche le même
appel sur l’Observable source onNext(), ce qui déclenche la répétition
![Page 198: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/198.jpg)
#J8Stream @JosePaumard
Méthodes repeat & retryMéthodes repeat & retry
• retry() : répète l’émission d’objets sur erreurretry() { } // Observable<T>retry(long times) { } // Observable<T>
![Page 199: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/199.jpg)
#J8Stream @JosePaumard
Méthodes repeat & retryMéthodes repeat & retry
• retry() : répète l’émission d’objets sur erreur
• Quand l’observable appelle onError(), le notification handler est invoqué avec l’exception
retry() { } // Observable<T>retry(long times) { } // Observable<T>
retryWhen(Func1<Observable<Throwable>>, Observable<?>> notificationHandler
) { }
![Page 200: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/200.jpg)
#J8Stream @JosePaumard
Méthodes repeat & retryMéthodes repeat & retry
• Sur cet Observable, le notification handler peut alors invoquer : onComplete() ou onError(), ce qui déclenche le même
appel sur l’Observable source onNext(), ce qui déclenche la répétition
![Page 201: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/201.jpg)
#J8Stream @JosePaumard
Plusieurs ObserverPlusieurs Observer
• À la différence des Stream de Java 8, un Observable peut avoir plusieurs observateurs
![Page 202: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/202.jpg)
#J8Stream @JosePaumard
Plusieurs ObserverPlusieurs Observer
• À la différence des Stream de Java 8, un Observable peut avoir plusieurs observateurs
• Ce qui peut poser des problèmes…
![Page 203: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/203.jpg)
#J8Stream @JosePaumard
Plusieurs ObserverPlusieurs Observer
• Cas d’un cold Observable : La consommation par plusieurs observateurs ne pose
pas de problème• Cas d’un hot Observable : Un deuxième observateur peut « manquer » les
premières valeurs
![Page 204: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/204.jpg)
#J8Stream @JosePaumard
Plusieurs ObserverPlusieurs Observer
• Méthode cache()
• Permet de ne pas « manquer » les premières valeurs
cache() { }cache(int capacity) { }
![Page 205: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/205.jpg)
#J8Stream @JosePaumard
Plusieurs ObserverPlusieurs Observer
• Notion de ConnectableObserverObservable<T> observable = ... ;ConnectableObservable<T> connectable = observable.publish() ;
![Page 206: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/206.jpg)
#J8Stream @JosePaumard
Plusieurs ObserverPlusieurs Observer
• Notion de ConnectableObserver
• L’enregistrement d’observateurs ne déclenche pas la production des éléments
Observable<T> observable = ... ;ConnectableObservable<T> connectable = observable.publish() ;
![Page 207: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/207.jpg)
#J8Stream @JosePaumard
Plusieurs ObserverPlusieurs Observer
• Notion de ConnectableObserver
• L’enregistrement d’observateurs ne déclenche pas la production des éléments
• Pour cela : appeler connect()
Observable<T> observable = ... ;ConnectableObservable<T> connectable = observable.publish() ;
connectable.publish() ;
![Page 208: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/208.jpg)
#J8Stream @JosePaumard
Bilan sur RxJavaBilan sur RxJava
• API Complète (complexe)• Permet de gérer le lancement de traitements dans
différents pools de threads
![Page 209: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/209.jpg)
#J8Stream @JosePaumard
Bilan sur RxJavaBilan sur RxJava
• API Complète (complexe)• Permet de gérer le lancement de traitements dans
différents pools de threads• Permet de synchroniser les opérations Sur une horloge Sur des références applicatives
![Page 210: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/210.jpg)
#J8Stream @JosePaumard
Ponts entre Java 8 Stream /
GS Collections / RxJava
![Page 211: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/211.jpg)
#J8Stream @JosePaumard
Le meilleur des deux mondes ?Le meilleur des deux mondes ?
• Connecter GS Collections et Java 8 Stream ?= connecter Stream et Iterable
![Page 212: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/212.jpg)
#J8Stream @JosePaumard
Le meilleur des deux mondes ?Le meilleur des deux mondes ?
• Connecter GS Collections et Java 8 Stream ?= connecter Stream et Iterable
• Connecter Java 8 Stream et RxJava ? = connecter Stream et Observable
![Page 213: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/213.jpg)
#J8Stream @JosePaumard
Spliterator et IteratorSpliterator et Iterator
• Les collections sont construites sur des Iterator• Les Stream sont construits sur des Spliterator
Iterator<T> iterator = ... ;Spliterator<T> spliterator =
Spliterators.spliteratorUnknownSize(iterator, 0) ;
Spliterator<T> spliterator = Spliterators.spliterator(iterator, size, 0) ;
![Page 214: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/214.jpg)
#J8Stream @JosePaumard
Spliterator et IteratorSpliterator et Iterator
• Les collections sont construites sur des Iterator• Les Stream sont construits sur des Spliterator
Spliterator<T> spliterator = ... ;
Iterator<T> iterator = Spliterators.iterator(spliterator) ;
Iterator<T> iterator = ... ;
Iterable<T> iterable = () ‐> iterator ;
![Page 215: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/215.jpg)
#J8Stream @JosePaumard
GS Collections & StreamGS Collections & Stream
• Le problème consiste à passer d’une Collection à un Stream (et réciproquement)
![Page 216: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/216.jpg)
#J8Stream @JosePaumard
GS Collections & StreamGS Collections & Stream
• Le problème consiste à passer d’une Collection à un Stream (et réciproquement)
• Donc d’un Iterator à un Spliterator (et réciproquement)
![Page 217: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/217.jpg)
#J8Stream @JosePaumard
RxJava & StreamRxJava & Stream
• Si l’on a un Iterator : facile !Iterator<T> iterator = ... ;
Observable<T> observable = Observable.from(() ‐> iterator) ;
![Page 218: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/218.jpg)
#J8Stream @JosePaumard
RxJava & StreamRxJava & Stream
• Si l’on a un Iterator : facile !
• Si l’on a un Spliterator : facile !
Iterator<T> iterator = ... ;
Observable<T> observable = Observable.from(() ‐> iterator) ;
Spliterator<T> spliterator = ... ;
Observable<T> observable = Observable.from(() ‐> Spliterators.iterator(spliterator)) ;
![Page 219: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/219.jpg)
#J8Stream @JosePaumard
RxJava & StreamRxJava & Stream
• Donc si l’on a un Stream, on peut facilement construire un Observable
![Page 220: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/220.jpg)
#J8Stream @JosePaumard
RxJava & StreamRxJava & Stream
• Donc si l’on a un Stream, on peut facilement construire un Observable
• L’inverse ?
![Page 221: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/221.jpg)
#J8Stream @JosePaumard
RxJava & StreamRxJava & Stream
• Donc si l’on a un Stream, on peut facilement construire un Observable
• L’inverse ? On peut construire un Iterator sur un Observable Puis un Spliterator sur un Iterator
![Page 222: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/222.jpg)
#J8Stream @JosePaumard
RxJava & StreamRxJava & Stream
• Implémenter un Iterator : Deux méthodes next() et hasNext() La méthode remove() et une méthode par défaut
![Page 223: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/223.jpg)
#J8Stream @JosePaumard
RxJava & StreamRxJava & Stream
• Un Iterator « tire » les données d’une source• Alors qu’un Observable « pousse » les données vers
des callbacks
![Page 224: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/224.jpg)
#J8Stream @JosePaumard
RxJava & StreamRxJava & Stream
• Un Iterator « tire » les données d’une source• Alors qu’un Observable « pousse » les données vers
des callbacks
• Il nous faut donc une adaptation entre les deux
![Page 225: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/225.jpg)
#J8Stream @JosePaumard
RxJava & StreamRxJava & Stream
• On peut s’inspirer du JDKpublic static<T> Iterator<T> iterator(Spliterator<? extends T> spliterator) {
class Adapter implements Iterator<T>, Consumer<T> {// implementation
}
return new Adapter() ;}
![Page 226: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/226.jpg)
#J8Stream @JosePaumard
RxJava & StreamRxJava & Stream
• On peut s’inspirer du JDK
class Adapter implements Iterator<T>, Consumer<T> {boolean valueReady = false ;T nextElement;
public void accept(T t) {valueReady = true ;nextElement = t ;
}
public boolean hasNext() {if (!valueReady)
spliterator.tryAdvance(this) ; // calls accept()return valueReady ;
}
public T next() {if (!valueReady && !hasNext())
throw new NoSuchElementException() ;else {
valueReady = false ;return nextElement ;
}}
}
![Page 227: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/227.jpg)
#J8Stream @JosePaumard
RxJava & StreamRxJava & Stream
• On peut s’inspirer du JDKpublic static<T> Iterator<T> of(Observable<? extends T> obsevable) {
class Adapter implements Iterator<T> {// implementation
}
return new Adapter() ;}
![Page 228: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/228.jpg)
#J8Stream @JosePaumard
RxJava & StreamRxJava & Stream
• On peut s’inspirer du JDK
class Adapter implements Iterator<T>, Consumer<T> {boolean valueReady = false ;T nextElement;
public void accept(T t) {valueReady = true ;nextElement = t ;
}
public boolean hasNext() {return valueReady ;
}
public T next() {if (!valueReady && !hasNext())
throw new NoSuchElementException() ;else {
valueReady = false ;return nextElement ;
}}
}
![Page 229: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/229.jpg)
#J8Stream @JosePaumard
RxJava & StreamRxJava & Stream
• On peut s’inspirer du JDKclass Adapter implements Iterator<T>, Consumer<T> {boolean valueReady = false ;T nextElement;
public void accept(T t) {observable.subscribe(
element ‐> nextElement = element, // onNextexception ‐> valueReady = false, // onError() ‐> valueReady = false // onComplete
) ;}
// next
// hasNext}
![Page 230: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/230.jpg)
#J8Stream @JosePaumard
RxJava & StreamRxJava & Stream
• On peut s’inspirer du JDKclass Adapter implements Iterator<T>, Consumer<T> {AtomicBoolean valueReady = new AtomicBoolean(false) ;AtomicReference<T> nextElement = new AtomicReference() ;
public void accept(T t) {observable.subscribe(
element ‐> nextElement.set(element), // onNextexception ‐> valueReady.set(false), // onError() ‐> valueReady.set(false) // onComplete
) ;}
// next
// hasNext}
![Page 231: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/231.jpg)
#J8Stream @JosePaumard
RxJava & StreamRxJava & Stream
• Peut mieux faire ? interface Wrapper<E> {
E get() ;
}
Wrapper<Boolean> wb = () ‐> true ;
![Page 232: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/232.jpg)
#J8Stream @JosePaumard
RxJava & StreamRxJava & Stream
• Peut mieux faire ? interface Wrapper<E> {
E get() ;
}
Wrapper<Boolean> wb = () ‐> true ;Action1<Boolean> onNext = b ‐> wb.set(b) ; // should return Wrapper<T>
![Page 233: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/233.jpg)
#J8Stream @JosePaumard
RxJava & StreamRxJava & Stream
• Peut mieux faire ? interface Wrapper<E> {
E get() ;
public default Wrapper<E> set(E e) {// should return e
}}
Wrapper<Boolean> wb = () ‐> true ;Action1<Boolean> onNext = b ‐> wb.set(b) ; // should return Wrapper<T>
![Page 234: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/234.jpg)
#J8Stream @JosePaumard
RxJava & StreamRxJava & Stream
• Peut mieux faire ? interface Wrapper<E> {
E get() ;
public default Wrapper<E> set(E e) {return () ‐> e ;
}}
Wrapper<Boolean> wb = () ‐> true ;Action1<Boolean> onNext = b ‐> wb.set(b) ; // should return Wrapper<T>
![Page 235: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/235.jpg)
#J8Stream @JosePaumard
RxJava & StreamRxJava & Stream
• On peut s’inspirer du JDKclass Adapter implements Iterator<T>, Consumer<T> {Wrapper<Boolean> valueReady = () ‐> false ;Wrapper<T> nextElement ;
public void accept(T t) {observable.subscribe(
element ‐> nextElement.set(element), // onNextexception ‐> valueReady.set(false), // onError() ‐> valueReady.set(false) // onComplete
) ;}
// next
// hasNext}
![Page 236: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/236.jpg)
#J8Stream @JosePaumard
RxJava & StreamRxJava & Stream
• On peut construire un Iterator sur un Observable Et donc un Spliterator sur un Observable
![Page 237: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/237.jpg)
#J8Stream @JosePaumard
RxJava & StreamRxJava & Stream
• On peut construire un Iterator sur un Observable Et donc un Spliterator sur un Observable
• Fonctionne sur les cold Observable
![Page 238: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/238.jpg)
#J8Stream @JosePaumard
Spliterators avancésSpliterators avancés
• Peut-on construire des Stream à la façon des Observable ?
• Partant d’un Stream [1, 2, 3, 4, 5, …]
![Page 239: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/239.jpg)
#J8Stream @JosePaumard
Spliterators avancésSpliterators avancés
• Peut-on construire des Stream à la façon des Observable ?
• Partant d’un Stream [1, 2, 3, 4, 5, …] [[1, 2, 3], [4, 5, 6], [7, 8, 9], …] ?
![Page 240: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/240.jpg)
#J8Stream @JosePaumard
Spliterators avancésSpliterators avancés
• Peut-on construire des Stream à la façon des Observable ?
• Partant d’un Stream [1, 2, 3, 4, 5, …] [[1, 2, 3], [4, 5, 6], [7, 8, 9], …] ? [[1, 2, 3], [2, 3, 4], [3, 4, 5], …] ?
![Page 241: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/241.jpg)
#J8Stream @JosePaumard
Spliterators avancésSpliterators avancés
• Peut-on construire des Stream à la façon des Observable ?
• Deux Stream [10, 11, 12, …] et [50, 51, 52, …]
![Page 242: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/242.jpg)
#J8Stream @JosePaumard
Spliterators avancésSpliterators avancés
• Peut-on construire des Stream à la façon des Observable ?
• Deux Stream [10, 11, 12, …] et [50, 51, 52, …] [10, 50, 11, 51, 12, 52, …] ?
![Page 243: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/243.jpg)
#J8Stream @JosePaumard
Spliterators avancésSpliterators avancés
• Peut-on construire des Stream à la façon des Observable ?
• Deux Stream [10, 11, 12, …] et [50, 51, 52, …] [10, 50, 11, 51, 12, 52, …] ? [Pair(10, 50), Pair(11, 51), Pair(12, 52), …] ?
![Page 244: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/244.jpg)
#J8Stream @JosePaumard
Spliterators avancésSpliterators avancés
• Trois méthodes pour un Spliterator tryAdvance(Consumer) trySplit(), retourne un sous-spliterator estimateSize()
![Page 245: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/245.jpg)
#J8Stream @JosePaumard
GroupingSpliteratorGroupingSpliterator
• [1, 2, 3, 4, 5, …] -> [[1, 2, 3], [4, 5, 6], [7, 8, 9], …]public class GroupingSpliterator<E> implements Spliterator<Stream<E>> {
private final long grouping ;private final Spliterator<E> spliterator ;
// implementation}
![Page 246: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/246.jpg)
#J8Stream @JosePaumard
GroupingSpliteratorGroupingSpliterator
• [1, 2, 3, 4, 5, …] -> [[1, 2, 3], [4, 5, 6], [7, 8, 9], …]public boolean tryAdvance(Consumer<? super Stream<E>> action) {
boolean finished = false ;Stream.Builder<E> builder = Stream.builder() ;for (int i = 0 ; i < grouping ; i++) {
if (!spliterator.tryAdvance(element ‐> { builder.add(element) ; })) {finished = true ;
}}Stream<E> subStream = subBuilder.build() ;action.accept(subStream) ;return !finished ;
}
![Page 247: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/247.jpg)
#J8Stream @JosePaumard
GroupingSpliteratorGroupingSpliterator
• [1, 2, 3, 4, 5, …] -> [[1, 2, 3], [4, 5, 6], [7, 8, 9], …]public Spliterator<Stream<E>> trySplit() {
Spliterator<E> spliterator = this.spliterator.trySplit() ;return new GroupingSpliterator<E>(spliterator, grouping) ;
}
![Page 248: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/248.jpg)
#J8Stream @JosePaumard
GroupingSpliteratorGroupingSpliterator
• [1, 2, 3, 4, 5, …] -> [[1, 2, 3], [4, 5, 6], [7, 8, 9], …]public long estimateSize() {
return spliterator.estimateSize() / grouping ;}
![Page 249: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/249.jpg)
#J8Stream @JosePaumard
RollingSpliteratorRollingSpliterator
• [1, 2, 3, 4, 5, …] -> [[1, 2, 3], [2, 3, 4], [3, 4, 5], …]
![Page 250: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/250.jpg)
#J8Stream @JosePaumard
RollingSpliteratorRollingSpliterator
• [1, 2, 3, 4, 5, …] -> [[1, 2, 3], [4, 5, 6], [7, 8, 9], …]public class RollingSpliterator<E> implements Spliterator<Stream<E>> {
private final int grouping ;private final Spliterator<E> spliterator ;private Object [] buffer ; // we cant create arrays of Eprivate AtomicInteger bufferWriteIndex = new AtomicInteger(0) ;private AtomicInteger bufferReadIndex = new AtomicInteger(0) ;
// implementation}
![Page 251: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/251.jpg)
#J8Stream @JosePaumard
RollingSpliteratorRollingSpliterator
• [1, 2, 3, 4, 5, …] -> [[1, 2, 3], [4, 5, 6], [7, 8, 9], …]
public boolean tryAdvance(Consumer<? super Stream<E>> action) {boolean finished = false ;
if (bufferWriteIndex.get() == bufferReadIndex.get()) {for (int i = 0 ; i < grouping ; i++) {
if (!advanceSpliterator()) {finished = true ;
}}
}if (!advanceSpliterator()) {
finished = true ;}
Stream<E> subStream = buildSubstream() ;action.accept(subStream) ;return !finished ;
}
![Page 252: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/252.jpg)
#J8Stream @JosePaumard
RollingSpliteratorRollingSpliterator
• [1, 2, 3, 4, 5, …] -> [[1, 2, 3], [4, 5, 6], [7, 8, 9], …]private boolean advanceSpliterator() {
return spliterator.tryAdvance(element ‐> {
buffer[bufferWriteIndex.get() % buffer.length] = element ; bufferWriteIndex.incrementAndGet() ;
});}
![Page 253: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/253.jpg)
#J8Stream @JosePaumard
RollingSpliteratorRollingSpliterator
• [1, 2, 3, 4, 5, …] -> [[1, 2, 3], [4, 5, 6], [7, 8, 9], …]public Spliterator<Stream<E>> trySplit() {
return new RollingSpliterator<E>(spliterator.trySplit(), grouping) ;}
public long estimateSize() {return spliterator.estimateSize() ‐ grouping ;
}
![Page 254: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/254.jpg)
#J8Stream @JosePaumard
ZippingSpliteratorZippingSpliterator
• [1, 2, 3, …], [a, b, c, …] -> [F(1, a), F(2, b), F(3, c), …]public class ZippingSpliterator<E1, E2, R> implements Spliterator<R> {
private final Spliterator<E1> spliterator1 ;private final Spliterator<E2> spliterator2 ;private final BiFunction<E1, E2, R> tranform ;
// implementation}
![Page 255: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/255.jpg)
#J8Stream @JosePaumard
ZippingSpliteratorZippingSpliterator
• [1, 2, 3, …], [a, b, c, …] -> [F(1, a), F(2, b), F(3, c), …]public boolean tryAdvance(Consumer<? super R> action) {
return spliterator1.tryAdvance(e1 ‐> {
spliterator2.tryAdvance(e2 ‐> {action.accept(tranform.apply(e1, e2)) ;
}) ;}) ;
}
![Page 256: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/256.jpg)
#J8Stream @JosePaumard
ZippingSpliteratorZippingSpliterator
• [1, 2, 3, …], [a, b, c, …] -> [F(1, a), F(2, b), F(3, c), …]public Spliterator<R> trySplit() {
return new ZippingSpliterator<E1, E2, R>(spliterator1.trySplit(), spliterator2.trySplit(), tranform) ;
}
public long estimateSize() {return this.spliterator1.estimateSize() ;
}
![Page 257: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/257.jpg)
#J8Stream @JosePaumard
PairingSpliteratorPairingSpliterator
• [1, 2, 3, …], [a, b, c, …] -> [(1, a), (2, b), (3, c), …]public class PairingSpliterator<E1, E2> extends ZippingSpliterator<E1, E2, Pair<E1, E2>> {
public PairingSpliterator(Spliterator<E1> spliterator1, Spliterator<E2> spliterator2) {
super(spliterator1, spliterator2, (e1, e2) ‐> new Pair<E1, E2>(e1, e2)) ;
}}
}
![Page 258: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/258.jpg)
#J8Stream @JosePaumard
Stream vs RxJavaStream vs RxJava
• Pour la partie cold : on peut l’implémenter avec des Stream
• Pour la partie hot : on peut interfacer les deux API
![Page 259: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/259.jpg)
#J8Stream @JosePaumard
Comparaisons
![Page 260: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/260.jpg)
#J8Stream @JosePaumard
ComparaisonsComparaisons
• Cas applicatif unique• Implémentés avec les trois API
• Comparaisons des patterns• Mesure des temps de traitement avec JMH
![Page 261: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/261.jpg)
#J8Stream @JosePaumard
Shakespeare joue an ScrabbleShakespeare joue an Scrabble
• « Shakespeare joue au Scrabble »• Ensemble de mots Les mots utilisés par Shakespeare Les mots autorisés au Scrabble
• Question : quel aurait été le meilleur mot que Shakespeare aurait pu jouer ?
![Page 262: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/262.jpg)
#J8Stream @JosePaumard
Shakespeare joue an ScrabbleShakespeare joue an Scrabble
• Comparaison des principaux patterns• Puis comparaison des performances globales
![Page 263: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/263.jpg)
#J8Stream @JosePaumard
Histogramme des lettresHistogramme des lettres
• Java Stream GS Collections Rx Java// Histogram of the letters in a given wordFunction<String, Map<Integer, Long>> histoOfLetters =
word ‐> word.chars().boxed().collect(
Collectors.groupingBy(Function.identity(),Collectors.counting()
)) ;
![Page 264: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/264.jpg)
#J8Stream @JosePaumard
Histogramme des lettresHistogramme des lettres
• Java Stream GS Collections Rx Java// Histogram of the letters in a given wordFunction<String, MutableMap<Integer, Long>> histoOfLetters =
word ‐> new CharArrayList(word.toCharArray()).collect(c ‐> new Integer((int)c))// .groupBy(letter ‐> letter) ;.aggregateBy(
letter ‐> letter, () ‐> 0L, (value, letter) ‐> { return value + 1 ; }
) ;
![Page 265: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/265.jpg)
#J8Stream @JosePaumard
Histogramme des lettresHistogramme des lettres
• Java Stream GS Collections Rx Java// Histogram of the letters in a given wordFunc1<String, Observable<HashMap<Integer, LongWrapper>>> histoOfLetters =
word ‐> toIntegerObservable.call(word).collect(
() ‐> new HashMap<Integer, LongWrapper>(), (HashMap<Integer, LongWrapper> map, Integer value) ‐> {
LongWrapper newValue = map.get(value) ;if (newValue == null) {
newValue = () ‐> 0L ;}map.put(value, newValue.incAndSet()) ;
}) ;
![Page 266: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/266.jpg)
#J8Stream @JosePaumard
Histogramme des lettresHistogramme des lettres
• Java Stream GS Collections Rx Javainterface LongWrapper {
long get() ;
public default LongWrapper set(long l) {return () ‐> l ;
}
public default LongWrapper incAndSet() {return () ‐> get() + 1L ;
}
public default LongWrapper add(LongWrapper other) {return () ‐> get() + other.get() ;
}}
![Page 267: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/267.jpg)
#J8Stream @JosePaumard
Nombre de blancs pour une lettreNombre de blancs pour une lettre
• Java Stream GS Collections Rx Java// number of blanks for a given letterToLongFunction<Map.Entry<Integer, Long>> blank =
entry ‐> Long.max(
0L, entry.getValue() ‐
scrabbleAvailableLetters[entry.getKey() ‐ 'a']) ;
![Page 268: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/268.jpg)
#J8Stream @JosePaumard
Nombre de blancs pour une lettreNombre de blancs pour une lettre
• Java Stream GS Collections Rx Java// number of blanks for a given letterLongFunction<Map.Entry<Integer, Long>> blank =
entry ‐> Long.max(
0L, entry.getValue() ‐
scrabbleAvailableLetters[entry.getKey() ‐ 'a']) ;
![Page 269: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/269.jpg)
#J8Stream @JosePaumard
Nombre de blancs pour une lettreNombre de blancs pour une lettre
• Java Stream GS Collections Rx Java// number of blanks for a given letterFunc1<Entry<Integer, LongWrapper>, Observable<Long>> blank =
entry ‐>Observable.just(
Long.max(0L, entry.getValue().get() ‐
scrabbleAvailableLetters[entry.getKey() ‐ 'a']
![Page 270: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/270.jpg)
#J8Stream @JosePaumard
Nombre de blancs pour un motNombre de blancs pour un mot
• Java Stream GS Collections Rx Java// number of blanks for a given wordFunction<String, Long> nBlanks =
word ‐> histoOfLetters.apply(word).entrySet().stream().mapToLong(blank).sum();
![Page 271: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/271.jpg)
#J8Stream @JosePaumard
Nombre de blancs pour un motNombre de blancs pour un mot
• Java Stream GS Collections Rx Java// number of blanks for a given wordFunction<String, Long> nBlanks =
word ‐> UnifiedSet.newSet(histoOfLetters.valueOf(word)
.entrySet()).sumOfLong(blank) ;
![Page 272: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/272.jpg)
#J8Stream @JosePaumard
Nombre de blancs pour un motNombre de blancs pour un mot
• Java Stream GS Collections Rx Java// number of blanks for a given wordFunc1<String, Observable<Long>> nBlanks =
word ‐> histoOfLetters.call(word).flatMap(map ‐> Observable.from(() ‐> map.entrySet().iterator())).flatMap(blank).reduce(Long::sum) ;
![Page 273: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/273.jpg)
#J8Stream @JosePaumard
Prédicat sur 2 blancsPrédicat sur 2 blancs
• Java Stream GS Collections Rx Java// can a word be written with 2 blanks?Predicate<String> checkBlanks = word ‐> nBlanks.apply(word) <= 2 ;
// can a word be written with 2 blanks?Predicate<String> checkBlanks = word ‐> nBlanks.valueOf(word) <= 2 ;
// can a word be written with 2 blanks?Func1<String, Observable<Boolean>> checkBlanks =
word ‐> nBlanks.call(word).flatMap(l ‐> Observable.just(l <= 2L)) ;
![Page 274: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/274.jpg)
#J8Stream @JosePaumard
Bonus lettre doublée – 1Bonus lettre doublée – 1
• Java Stream GS Collections Rx Java// Placing the word on the board// Building the streams of first and last lettersFunction<String, IntStream> first3 =
word ‐> word.chars().limit(3);
![Page 275: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/275.jpg)
#J8Stream @JosePaumard
Bonus lettre doublée – 1Bonus lettre doublée – 1
• Java Stream GS Collections Rx Java// Placing the word on the board// Building the streams of first and last lettersFunction<String, MutableList<Integer>> first3 =
word ‐> new CharArrayList(word.toCharArray()).collect(c ‐> (int)c) ;.subList(0, Integer.min(list.size(), 3)) ;
![Page 276: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/276.jpg)
#J8Stream @JosePaumard
Bonus lettre doublée – 1Bonus lettre doublée – 1
• Java Stream GS Collections Rx Java// Placing the word on the board// Building the streams of first and last lettersFunc1<String, Observable<Integer>> first3 =
word ‐> Observable.from(
IterableSpliterator.of(word.chars().boxed().limit(3).spliterator()
)) ;
![Page 277: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/277.jpg)
#J8Stream @JosePaumard
Bonus lettre doublée – 2Bonus lettre doublée – 2
• Java Stream GS Collections Rx Java// Bonus for double letterToIntFunction<String> bonusForDoubleLetter =
word ‐> Stream.of(first3.apply(word), last3.apply(word)).flatMapToInt(Function.identity()).map(scoreOfALetter).max().orElse(0) ;
![Page 278: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/278.jpg)
#J8Stream @JosePaumard
Bonus lettre doublée – 2Bonus lettre doublée – 2
• Java Stream GS Collections Rx Java// Bonus for double letterFunction<String, MutableList<Integer>> toBeMaxed =
word ‐> { MutableList<Integer> list = first3.valueOf(word) ;list.addAll(last3.valueOf(word)) ;return list ;
} ;
IntFunction<String> bonusForDoubleLetter =word ‐> toBeMaxed.valueOf(word)
.collect(scoreOfALetter)
.max() ;
![Page 279: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/279.jpg)
#J8Stream @JosePaumard
Bonus lettre doublée – 2Bonus lettre doublée – 2
• Java Stream GS Collections Rx Java// Bonus for double letterFunc1<String, Observable<Integer>> bonusForDoubleLetter =
word ‐> Observable.just(first3.call(word), last3.call(word)).flatMap(observable ‐> observable).flatMap(scoreOfALetter).reduce(Integer::max) ;
![Page 280: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/280.jpg)
#J8Stream @JosePaumard
Score d’un motScore d’un mot
• Java Stream GS Collections Rx Java// score of the word put on the boardFunction<String, Integer> score3 =
word ‐> 2*(score2.apply(word) + bonusForDoubleLetter.applyAsInt(word))+ (word.length() == 7 ? 50 : 0);
![Page 281: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/281.jpg)
#J8Stream @JosePaumard
Score d’un motScore d’un mot
• Java Stream GS Collections Rx Java// score of the word put on the boardFunction<String, Integer> score3 =
word ‐>2*(score2.valueOf(word) + bonusForDoubleLetter.intValueOf(word))+ (word.length() == 7 ? 50 : 0);
![Page 282: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/282.jpg)
#J8Stream @JosePaumard
Score d’un motScore d’un mot
• Java Stream GS Collections Rx Java// score of the word put on the boardFunc1<String, Observable<Integer>> score3 =
word ‐>Observable.just(
score2.call(word), score2.call(word), bonusForDoubleLetter.call(word), bonusForDoubleLetter.call(word), Observable.just(word.length() == 7 ? 50 : 0)
).flatMap(observable ‐> observable).reduce(Integer::sum) ;
![Page 283: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/283.jpg)
#J8Stream @JosePaumard
Histogramme des scoresHistogramme des scores
• Java Stream GS Collections Rx JavaFunction<Function<String, Integer>, Map<Integer, List<String>>>buildHistoOnScore =
score ‐> shakespeareWords.stream().parallel().filter(scrabbleWords::contains).filter(checkBlanks).collect(
Collectors.groupingBy(score, () ‐> new TreeMap<>(Comparator.reverseOrder()), Collectors.toList()
)) ;
![Page 284: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/284.jpg)
#J8Stream @JosePaumard
Histogramme des scoresHistogramme des scores
• Java Stream GS Collections Rx JavaFunction<
Function<String, Integer>, MutableMap<Integer, MutableList<String>>>buildHistoOnScore =
score ‐> shakespeareWords.select(scrabbleWords::contains).select(checkBlanks).aggregateBy(
score, FastList::new, (list, value) ‐> { list.add(value) ; return list ; }
) ;
![Page 285: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/285.jpg)
#J8Stream @JosePaumard
Histogramme des scoresHistogramme des scores
• Java Stream GS Collections Rx JavaFunc1<Func1<String, Observable<Integer>>, Observable<TreeMap<Integer, List<String>>>> buildHistoOnScore =
score ‐> Observable.from(() ‐> shakespeareWords.iterator()).filter(scrabbleWords::contains).filter(word ‐> checkBlanks.call(word).toBlocking().first()).collect(
() ‐> new TreeMap<Integer, List<String>>(Comparator.reverseOrder()), (TreeMap<Integer, List<String>> map, String word) ‐> {
Integer key = score.call(word).toBlocking().first() ;List<String> list = map.get(key) ;if (list == null) {
list = new ArrayList<String>() ;map.put(key, list) ;
}list.add(word) ;
}) ;
![Page 286: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/286.jpg)
#J8Stream @JosePaumard
Meilleurs motsMeilleurs mots
• Java Stream GS Collections Rx Java// best key / value pairsList<Entry<Integer, List<String>>> finalList =
buildHistoOnScore.apply(score3).entrySet().stream().limit(3).collect(Collectors.toList()) ;
![Page 287: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/287.jpg)
#J8Stream @JosePaumard
Meilleurs motsMeilleurs mots
• Java Stream GS Collections Rx Java// best key / value pairsMutableList<Entry<Integer, MutableList<String>>> finalList =
new FastList<Map.Entry<Integer,MutableList<String>>>(new TreeSortedMap<Integer, MutableList<String>>(
Comparator.reverseOrder(), buildHistoOnScore.valueOf(score3)
).entrySet()
).subList(0, 3) ;
![Page 288: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/288.jpg)
#J8Stream @JosePaumard
Meilleurs motsMeilleurs mots
• Java Stream GS Collections Rx Java// best key / value pairsList<Entry<Integer, List<String>>> finalList2 =
buildHistoOnScore.call(score3).flatMap(map ‐> Observable.from(() ‐> map.entrySet().iterator())).take(3).collect(
() ‐> new ArrayList<Entry<Integer, List<String>>>(), (list, entry) ‐> { list.add(entry) ; }
).toBlocking().first() ;
![Page 289: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/289.jpg)
#J8Stream @JosePaumard
Meilleurs motsMeilleurs mots
• Java Stream GS Collections Rx Java// best key / value pairsCountDownLatch latch = new CountDownLatch(3) ;
buildHistoOnScore.call(score3).flatMap(map ‐> Observable.from(() ‐> map.entrySet().iterator())).take(3).collect(
() ‐> new ArrayList<Entry<Integer, List<String>>>(), (list, entry) ‐> { list.add(entry) ; latch.countDown() ; }
).forEach(...) ;
latch.await() ;
![Page 290: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/290.jpg)
#J8Stream @JosePaumard
1er bilan : patterns1er bilan : patterns
• Java 8 Stream donne les patterns les plus simples
![Page 291: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/291.jpg)
#J8Stream @JosePaumard
1er bilan : patterns1er bilan : patterns
• Java 8 Stream donne les patterns les plus simples• Java 8 Stream & GS Collections se ressemblent
![Page 292: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/292.jpg)
#J8Stream @JosePaumard
1er bilan : patterns1er bilan : patterns
• Java 8 Stream donne les patterns les plus simples• Java 8 Stream & GS Collections se ressemblent• RxJava fait le choix du « tout flatMap » ce qui mène à
des patterns inutilement lourds
![Page 293: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/293.jpg)
#J8Stream @JosePaumard
Performances Performances
• Utilisation de JMH• Outil standard de mesure de performances du JDK• Développé dans le cadre de l’Open JDK• Aleksey Shipilev http://shipilev.net/• https://twitter.com/shipilev
http://openjdk.java.net/projects/code-tools/jcstress/
http://openjdk.java.net/projects/code-tools/jmh/
https://www.parleys.com/tutorial/java-microbenchmark-harness-the-lesser-two-evils
![Page 294: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/294.jpg)
#J8Stream @JosePaumard
Performances Performances
• Utilisation de JMH• Outil standard de mesure de performances du JDK• Développé dans le cadre de l’Open JDK• Aleksey Shipilev http://shipilev.net/• https://twitter.com/shipilev
http://openjdk.java.net/projects/code-tools/jcstress/
http://openjdk.java.net/projects/code-tools/jmh/
https://www.parleys.com/tutorial/java-microbenchmark-harness-the-lesser-two-evils
Aleksey Shipilëv @shipilev
Чувак из ТВ-службы пришёл отключать антенну. Оказался масс-спектрометристом, сцепился языком с тестем: стоят, обсуждают девайсы. #наукоград
![Page 295: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/295.jpg)
#J8Stream @JosePaumard
JMHJMH
• Simple à utiliser<dependency>
<groupId>org.openjdk.jmh</groupId><artifactId>jmh‐core</artifactId><version>1.7</version>
</dependency>
![Page 296: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/296.jpg)
#J8Stream @JosePaumard
JMHJMH
• État partagé entre les exécutions@State(Scope.Benchmark)public class ShakespearePlaysScrabble {
Set<String> scrabbleWords = null ;Set<String> shakespeareWords = null ;
@Setuppublic void init() {
scrabbleWords = Util.readScrabbleWords() ;shakespeareWords = Util.readShakespeareWords() ;
}}
![Page 297: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/297.jpg)
#J8Stream @JosePaumard
JMHJMH
• Simple à mettre en œuvre @Benchmark@BenchmarkMode(Mode.AverageTime)@OutputTimeUnit(TimeUnit.MILLISECONDS)@Warmup(iterations=5)@Measurement(iterations=5)@Fork(3)public List<Entry<Integer, List<String>>> measureAverage() {
// implementation to test}
![Page 298: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/298.jpg)
#J8Stream @JosePaumard
JMHJMH
• Utilisation particulière> mvn clean install> java –jar target/benchmark.jar
![Page 299: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/299.jpg)
#J8Stream @JosePaumard
JMHJMH
• 3 façons de mesurer les performances Temps moyen d’exécution Nombre d’exécutions par seconde Échantillonnage (diagramme par quantiles)
![Page 300: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/300.jpg)
#J8Stream @JosePaumard
Performances Performances
• Mesure du temps moyenBenchmark Mode Cnt Score Error UnitsGSCollections avgt 100 25,392 ± 0,253 ms/op
![Page 301: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/301.jpg)
#J8Stream @JosePaumard
Performances Performances
• Mesure du temps moyenBenchmark Mode Cnt Score Error UnitsGSCollections avgt 100 25,392 ± 0,253 ms/opNonParallelStreams avgt 100 29,027 ± 0,279 ms/op
![Page 302: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/302.jpg)
#J8Stream @JosePaumard
Performances Performances
• Mesure du temps moyenBenchmark Mode Cnt Score Error UnitsGSCollections avgt 100 25,392 ± 0,253 ms/opNonParallelStreams avgt 100 29,027 ± 0,279 ms/opRxJava avgt 100 253,788 ± 1,421 ms/op
![Page 303: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/303.jpg)
#J8Stream @JosePaumard
Performances Performances
• Mesure du temps moyenBenchmark Mode Cnt Score Error UnitsGSCollections avgt 100 25,392 ± 0,253 ms/opNonParallelStreams avgt 100 29,027 ± 0,279 ms/opRxJava avgt 100 253,788 ± 1,421 ms/opParallelStreams avgt 100 7,624 ± 0,055 ms/op
![Page 304: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/304.jpg)
#J8Stream @JosePaumard
Performances Performances
• Mesure du temps moyen
• Attention à la mémoire avec GS Collections
Benchmark Mode Cnt Score Error UnitsGSCollections avgt 100 25,392 ± 0,253 ms/opNonParallelStreams avgt 100 29,027 ± 0,279 ms/opRxJava avgt 100 253,788 ± 1,421 ms/opParallelStreams avgt 100 7,624 ± 0,055 ms/op
![Page 305: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/305.jpg)
#J8Stream @JosePaumard
Conclusion
![Page 306: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/306.jpg)
#J8Stream @JosePaumard
Conclusion Conclusion
• La programmation fonctionnelle est « à la mode »• Du point de vue performance, les choses ne sont pas
si simples• Le choix de l’API Stream : « une dose de fonctionnel »
est probablement le bon
![Page 307: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/307.jpg)
#J8Stream @JosePaumard
Conclusion Conclusion
• GS Collections : bonne API Beaucoup de patterns en doublon des Streams Compatible Java 7
• RxJava : API riche et complexe Approche différente, patterns complémentaires Attention aux performances
![Page 308: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/308.jpg)
#J8Stream @JosePaumard
Conclusion Conclusion
• Java 8 Stream Performante, efficace en mémoire Seule à offrir la parallélisation « gratuite » Extensible au travers des Spliterator
![Page 309: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/309.jpg)
@JosePaumard#J8Stream
![Page 310: Les Streams sont parmi nous](https://reader034.vdocuments.net/reader034/viewer/2022051213/55a8eca51a28abbf2b8b46b5/html5/thumbnails/310.jpg)
@JosePaumard#J8Stream