This document discusses Java 8 streams and collectors. It provides an overview of streams, operations on streams like forEach(), filter(), and peek(), and functional interfaces like Consumer and Predicate. It notes that streams efficiently process data in a parallel and pipelined manner without storing intermediate data. Key points covered include what streams are, how to create them from collections, common stream operations, and issues around concurrency with mutable operations.
Les slides de ma présentation à Devoxx France 2017.
Introduite en Java 8, l'API Collector vit dans l'ombre de l'API Stream, ce qui est logique puisqu'un collecteur doit se connecter à un stream pour fonctionner. Le JDK est organisé de sorte que l'on utilise surtout les collectors sur étagère : groupingBy, counting et quelques autres. Ces deux éléments masquent non seulement le modèle de traitement de données des collectors, mais aussi sa puissance et ses performances.
Ces présentation parle des collectors qui existent et qu'il faut connaître, ceux que l'on peut créer, ceux dont on se doute que l'on peut les créer une fois que l'on comprend un peu les choses, et les autres, tant les possibilités offertes par cette API sont illimitées.
Lambda and Stream Master class - part 1José Paumard
These are the slides of the talk we made with Stuart Marks at Devoxx Belgium 2018. This first part covers Lambda Expressions and API design with functional interfaces.
What is the state of lambda expressions in Java 11? Lambda expressions are the major feature of Java 8, having an impact on most of the API, including the Streams and Collections API. We are now living the Java 11 days; new features have been added and new patterns have emerged. This highly technical Deep Dive session will visit all these patterns, the well-known ones and the new ones, in an interactive hybrid of lecture and laboratory. We present a technique and show how it helps solve a problem. We then present another problem, and give you some time to solve it yourself. Finally, we present a solution, and open for questions, comments, and discussion. Bring your laptop set up with JDK 11 and your favorite IDE, and be prepared to think!
Spring Framework Petclinic sample applicationAntoine Rey
Spring Petclinic is a sample application that has been designed to show how the Spring Framework can be used to build simple but powerful database-oriented applications.
The fork named Spring Framework Petclinic maintains a version both with a plain old Spring Framework configuration and a 3-layer architecture (i.e. presentation --> service --> repository).
Spring Data is a high level SpringSource project whose purpose is to unify and ease the access to different kinds of persistence stores, both relational database systems and NoSQL data stores.
Les slides de ma présentation à Devoxx France 2017.
Introduite en Java 8, l'API Collector vit dans l'ombre de l'API Stream, ce qui est logique puisqu'un collecteur doit se connecter à un stream pour fonctionner. Le JDK est organisé de sorte que l'on utilise surtout les collectors sur étagère : groupingBy, counting et quelques autres. Ces deux éléments masquent non seulement le modèle de traitement de données des collectors, mais aussi sa puissance et ses performances.
Ces présentation parle des collectors qui existent et qu'il faut connaître, ceux que l'on peut créer, ceux dont on se doute que l'on peut les créer une fois que l'on comprend un peu les choses, et les autres, tant les possibilités offertes par cette API sont illimitées.
Lambda and Stream Master class - part 1José Paumard
These are the slides of the talk we made with Stuart Marks at Devoxx Belgium 2018. This first part covers Lambda Expressions and API design with functional interfaces.
What is the state of lambda expressions in Java 11? Lambda expressions are the major feature of Java 8, having an impact on most of the API, including the Streams and Collections API. We are now living the Java 11 days; new features have been added and new patterns have emerged. This highly technical Deep Dive session will visit all these patterns, the well-known ones and the new ones, in an interactive hybrid of lecture and laboratory. We present a technique and show how it helps solve a problem. We then present another problem, and give you some time to solve it yourself. Finally, we present a solution, and open for questions, comments, and discussion. Bring your laptop set up with JDK 11 and your favorite IDE, and be prepared to think!
Spring Framework Petclinic sample applicationAntoine Rey
Spring Petclinic is a sample application that has been designed to show how the Spring Framework can be used to build simple but powerful database-oriented applications.
The fork named Spring Framework Petclinic maintains a version both with a plain old Spring Framework configuration and a 3-layer architecture (i.e. presentation --> service --> repository).
Spring Data is a high level SpringSource project whose purpose is to unify and ease the access to different kinds of persistence stores, both relational database systems and NoSQL data stores.
Spring IO 2023 - Dynamic OpenAPIs with Spring Cloud GatewayIván López Martín
Imagine this scenario. You follow an OpenAPI-first approach when designing your services. You have a distributed architecture with multiple services and all of them expose a RESTful API and have their OpenAPI Specification. Now you use Spring Cloud Gateway in front of them so you can route the requests to the appropriate service and apply cross-cutting concerns. But, what happens with the OpenAPI of every service? It would be great if you could generate a unique OpenAPI for the whole system in the Gateway. You could also expose and transform only selected endpoints when defining them as public. And what about the routes? You would like to reconfigure them dynamically and on-the-fly in the Gateway when there is a change in a service, right?
Stop imagining. In this talk, I will show you how we have done that in our product and how we are leveraging the programmatic Spring Cloud Gateway API to reconfigure the routes on the fly. You will also see it in action during the demo!
Lambdas and Streams Master Class Part 2José Paumard
These are the slides of the talk we made with Stuart Marks at Devoxx Belgium 2018. This second part covers the Stream API, reduction and the Collector API.
What is the state of lambda expressions in Java 11? Lambda expressions are the major feature of Java 8, having an impact on most of the API, including the Streams and Collections API. We are now living the Java 11 days; new features have been added and new patterns have emerged. This highly technical Deep Dive session will visit all these patterns, the well-known ones and the new ones, in an interactive hybrid of lecture and laboratory. We present a technique and show how it helps solve a problem. We then present another problem, and give you some time to solve it yourself. Finally, we present a solution, and open for questions, comments, and discussion. Bring your laptop set up with JDK 11 and your favorite IDE, and be prepared to think!
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023Steve Pember
In this presentation we will present the general philosophy of Clean Architecture, Hexagonal Architecture, and Ports & Adapters: discussing why these approaches are useful and general guidelines for introducing them to your code. Chiefly, we will show how to implement these patterns within your Spring (Boot) Applications. Through a publicly available reference app, we will demonstrate what these concepts can look like within Spring and walkthrough a handful of scenarios: isolating core business logic, ease of testing, and adding a new feature or two.
NestJS (https://nestjs.com/) is a Node.js framework for building server-side applications. This slide give you a brief introduction of Nest, and shows the examples like Service, Middleware, and Pipe, etc.
Asynchronous API in Java8, how to use CompletableFutureJosé Paumard
Slides of my talk as Devoxx 2015. How to set up asynchronous data processing pipelines using the CompletionStage / CompletableFuture API, including how to control threads and how to handle exceptions.
Explanation of the fundamentals of Redux with additional tips and good practices. Presented in the Munich React Native Meetup, so the sample code is using React Native. Additional code: https://github.com/nacmartin/ReduxIntro
Presentation explain about
Spring Boot vs Spring vs Spring MVC,
Advantages,
Where to start and how does Spring boot work ?,
Dependency Management,
Logging,
Exception Handling,
Database Handling.
in Spring boot.
An intro to React Native using react-native cli, styled components, react-navigation, and an an introduction to the react native ecosystem.
Example repo: https://github.com/ladyleet/fluentConf2
Have questions? Tweet me http://twitter.com/ladyleet
Tutorial Videos: https://www.youtube.com/playlist?list=PLD8nQCAhR3tQ7KXnvIk_v_SLK-Fb2y_k_
Day 1 : Introduction to React, Babel and Webpack
Prerequisites of starting the workshop ( Basic understanding of Node & Express )
What is Virtual DOM?
What is React and why should we use it?
Install and set up React:
a-Using create-react-app
b-From scratch using Babel and Webpack. We will use Webpack Dev Server.
Day 2 : React Basic Concepts
Types of Components: Class-based and Functional based Components
Use of JSX
Parent, Child, and Nested Components
Difference between State and Props
Create and Handle Routes
Component Lifecycle Methods
Create a form and handling form inputs
Use of arrow functions and Spread Operator
Day 3: Advanced Concepts in React
Use of Refs
What are Higher Order Components( HOC )?
How to use HOC
Understanding Context in React
This talk introduces Spring's REST stack - Spring MVC, Spring HATEOAS, Spring Data REST, Spring Security OAuth and Spring Social - while refining an API to move higher up the Richardson maturity model
This is a talk on how you can monitor your microservices architecture using Prometheus and Grafana. This has easy to execute steps to get a local monitoring stack running on your local machine using docker.
GraphQL is a query language for APIs and a runtime for fulfilling those queries. It gives clients the power to ask for exactly what they need, which makes it a great fit for modern web and mobile apps. In this talk, we explain why GraphQL was created, introduce you to the syntax and behavior, and then show how to use it to build powerful APIs for your data. We will also introduce you to AWS AppSync, a GraphQL-powered serverless backend for apps, which you can use to host GraphQL APIs and also add real-time and offline capabilities to your web and mobile apps. You can follow along if you have an AWS account – no GraphQL experience required!
Level: Beginner
Speaker: Rohan Deshpande - Sr. Software Dev Engineer, AWS Mobile Applications
Slides from the NestJS MasterClass.
We learned how to build JavaScript server-side applications with NestJS - A progressive NodeJS framework built with TypeScript.
You can find the code on GitHub:
https://github.com/nirkaufman/task-manager
Clean Pragmatic Architecture - Avoiding a MonolithVictor Rentea
Talk built based on several of my trainings: http://www.victorrentea.ro/#training
Covers: Clean/Onion/Hexagonal Architecture, Domain Entities, Value Objects, Repository, Extract When it Grows Principle, Dependency Inversion Principle, Clean Code and Design Patterns.
These are the backing slides of the talks given at JPoint 2017 and Devoxx PL 2017: https://www.youtube.com/embed/4-4ahz7zDiQ
50 nouvelles choses que l'on peut faire avec Java 8José Paumard
Java 8, c'est bien sûr l'arrivée des lambdas, des Stream et des Collectors. Mais ce n'est pas que cela. Plein de nouvelles choses sont aussi offertes : un nouvelle API pour les dates, un nouveau moteur Javascript, une nouvelle version de JavaFX, une nouvelle ConcurrentHashMap, une nouvelle HashMap, des nouveautés dans le domaine de la concurrence, et toutes sortes de petites choses qui vont nous faciliter la vie, que l'on se propose de passer en revue ici.
Spring IO 2023 - Dynamic OpenAPIs with Spring Cloud GatewayIván López Martín
Imagine this scenario. You follow an OpenAPI-first approach when designing your services. You have a distributed architecture with multiple services and all of them expose a RESTful API and have their OpenAPI Specification. Now you use Spring Cloud Gateway in front of them so you can route the requests to the appropriate service and apply cross-cutting concerns. But, what happens with the OpenAPI of every service? It would be great if you could generate a unique OpenAPI for the whole system in the Gateway. You could also expose and transform only selected endpoints when defining them as public. And what about the routes? You would like to reconfigure them dynamically and on-the-fly in the Gateway when there is a change in a service, right?
Stop imagining. In this talk, I will show you how we have done that in our product and how we are leveraging the programmatic Spring Cloud Gateway API to reconfigure the routes on the fly. You will also see it in action during the demo!
Lambdas and Streams Master Class Part 2José Paumard
These are the slides of the talk we made with Stuart Marks at Devoxx Belgium 2018. This second part covers the Stream API, reduction and the Collector API.
What is the state of lambda expressions in Java 11? Lambda expressions are the major feature of Java 8, having an impact on most of the API, including the Streams and Collections API. We are now living the Java 11 days; new features have been added and new patterns have emerged. This highly technical Deep Dive session will visit all these patterns, the well-known ones and the new ones, in an interactive hybrid of lecture and laboratory. We present a technique and show how it helps solve a problem. We then present another problem, and give you some time to solve it yourself. Finally, we present a solution, and open for questions, comments, and discussion. Bring your laptop set up with JDK 11 and your favorite IDE, and be prepared to think!
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023Steve Pember
In this presentation we will present the general philosophy of Clean Architecture, Hexagonal Architecture, and Ports & Adapters: discussing why these approaches are useful and general guidelines for introducing them to your code. Chiefly, we will show how to implement these patterns within your Spring (Boot) Applications. Through a publicly available reference app, we will demonstrate what these concepts can look like within Spring and walkthrough a handful of scenarios: isolating core business logic, ease of testing, and adding a new feature or two.
NestJS (https://nestjs.com/) is a Node.js framework for building server-side applications. This slide give you a brief introduction of Nest, and shows the examples like Service, Middleware, and Pipe, etc.
Asynchronous API in Java8, how to use CompletableFutureJosé Paumard
Slides of my talk as Devoxx 2015. How to set up asynchronous data processing pipelines using the CompletionStage / CompletableFuture API, including how to control threads and how to handle exceptions.
Explanation of the fundamentals of Redux with additional tips and good practices. Presented in the Munich React Native Meetup, so the sample code is using React Native. Additional code: https://github.com/nacmartin/ReduxIntro
Presentation explain about
Spring Boot vs Spring vs Spring MVC,
Advantages,
Where to start and how does Spring boot work ?,
Dependency Management,
Logging,
Exception Handling,
Database Handling.
in Spring boot.
An intro to React Native using react-native cli, styled components, react-navigation, and an an introduction to the react native ecosystem.
Example repo: https://github.com/ladyleet/fluentConf2
Have questions? Tweet me http://twitter.com/ladyleet
Tutorial Videos: https://www.youtube.com/playlist?list=PLD8nQCAhR3tQ7KXnvIk_v_SLK-Fb2y_k_
Day 1 : Introduction to React, Babel and Webpack
Prerequisites of starting the workshop ( Basic understanding of Node & Express )
What is Virtual DOM?
What is React and why should we use it?
Install and set up React:
a-Using create-react-app
b-From scratch using Babel and Webpack. We will use Webpack Dev Server.
Day 2 : React Basic Concepts
Types of Components: Class-based and Functional based Components
Use of JSX
Parent, Child, and Nested Components
Difference between State and Props
Create and Handle Routes
Component Lifecycle Methods
Create a form and handling form inputs
Use of arrow functions and Spread Operator
Day 3: Advanced Concepts in React
Use of Refs
What are Higher Order Components( HOC )?
How to use HOC
Understanding Context in React
This talk introduces Spring's REST stack - Spring MVC, Spring HATEOAS, Spring Data REST, Spring Security OAuth and Spring Social - while refining an API to move higher up the Richardson maturity model
This is a talk on how you can monitor your microservices architecture using Prometheus and Grafana. This has easy to execute steps to get a local monitoring stack running on your local machine using docker.
GraphQL is a query language for APIs and a runtime for fulfilling those queries. It gives clients the power to ask for exactly what they need, which makes it a great fit for modern web and mobile apps. In this talk, we explain why GraphQL was created, introduce you to the syntax and behavior, and then show how to use it to build powerful APIs for your data. We will also introduce you to AWS AppSync, a GraphQL-powered serverless backend for apps, which you can use to host GraphQL APIs and also add real-time and offline capabilities to your web and mobile apps. You can follow along if you have an AWS account – no GraphQL experience required!
Level: Beginner
Speaker: Rohan Deshpande - Sr. Software Dev Engineer, AWS Mobile Applications
Slides from the NestJS MasterClass.
We learned how to build JavaScript server-side applications with NestJS - A progressive NodeJS framework built with TypeScript.
You can find the code on GitHub:
https://github.com/nirkaufman/task-manager
Clean Pragmatic Architecture - Avoiding a MonolithVictor Rentea
Talk built based on several of my trainings: http://www.victorrentea.ro/#training
Covers: Clean/Onion/Hexagonal Architecture, Domain Entities, Value Objects, Repository, Extract When it Grows Principle, Dependency Inversion Principle, Clean Code and Design Patterns.
These are the backing slides of the talks given at JPoint 2017 and Devoxx PL 2017: https://www.youtube.com/embed/4-4ahz7zDiQ
50 nouvelles choses que l'on peut faire avec Java 8José Paumard
Java 8, c'est bien sûr l'arrivée des lambdas, des Stream et des Collectors. Mais ce n'est pas que cela. Plein de nouvelles choses sont aussi offertes : un nouvelle API pour les dates, un nouveau moteur Javascript, une nouvelle version de JavaFX, une nouvelle ConcurrentHashMap, une nouvelle HashMap, des nouveautés dans le domaine de la concurrence, et toutes sortes de petites choses qui vont nous faciliter la vie, que l'on se propose de passer en revue ici.
L'API la plus utilisée du JDK est sans aucun doute l'API Collection. Brillamment conçue il y a un peu plus de 15 ans, elle est encore aujourd'hui au coeur de toutes les applications Java. En 2004, elle a subi son premier lifting, avec l'introduction des génériques. Cette mise à jour, bien qu'importante, n'a cependant pas modifié ses patterns d'utilisation. Avec l'introduction des lambdas en Java 8, l'API Collection est à nouveau réécrite, mais cette fois la situation est différente : ses patterns d'utilisation sont complètement changés.
La première partie de cette conférence introduit les lambda expressions, comment les écrire, et ce qu'elle nous apportent en tant que développeurs. La deuxième partir présente en détail les nouveaux patterns introduits par les API Stream et Collector. Ces nouvelles API vont changer la façon dont nous allons pouvoir traiter les collections de grande taille, y compris en parallèle, avec un modèle de programmation très simple, et des patterns très puissants. Cette puissance sera montrée dans des exemples réels, qui monteront comment Java 8 va pouvoir nous aider à écrire simplement du code efficace et performant.
HTTP2 : ce qui va changer par Julien LanduréZenika
HTTP1 est omniprésent en 2016 et HTTP2 est pourtant "sorti" le 15 mai 2015. Qu'est-ce qu'on y gagne, nous développeurs ? Les principes d'optimisation Web seront-ils toujours d'actualités ? Venez découvrir HTTP2, le futur protocole du Web !
A technical description of http2, including background of HTTP what's been problematic with it and how http2 and its features improves the web.
See the "http2 explained" document with the complete transcript and more: http://daniel.haxx.se/http2/
(Updated version to slides shown on April 13th, 2016)
Dans la continuité de la conférence Java Concurrency and Non-blocking IO Lecture animée par Heinz Kabutz, Zenika vous propose d'assister à la NightClazz Java 8 - Découverte.
Au sein d’une démarche DevOps, le build et le déploiement continue sont les premiers piliers à mettre en place.
Cette session avancé de notre NighClazz “Build Tools & Continuous Delivery” a pour objectif de présenter les modes de déploiement "Blue-Green Deployment" et "Feature toggle" ainsi que les principes d'automatisation des schémas de base de données.
Le sujet principal de Java 9 est le support de la modularité mais Java 9 propose aussi de nombreuses autres fonctionnalités. Ce talk a pour but de faire une revue des principales d’entre-elles en attendant la sortie de Java 9 : support de standards, nouvelles API, évolutions dans certaines API, mises à jour des outils du JDK et améliorations de la JVM.
Java SE 8 est sûrement la version la plus importante et la plus impactante pour les développeurs. Deux ans après sa sortie, ce talk propose des retours sur les bonnes ou moins bonnes utilisations des principales fonctionnalités de Java 8. Une connaissance de ces fonctionnalités est requise.
Java 8 Stream API and RxJava ComparisonJosé Paumard
The slides of my JavaOne talk: Java 8 Stream API and RxJava Comparison: Patterns and Performances.
The spliterators patterns can be found here: https://github.com/JosePaumard/jdk8-spliterators.
The slides of my university talk at Devoxx BE 2015. Presentation of the Java 8 Stream API and RxJava, pattern and performance comparisons. Presentation of the upcoming reactive API in Java 9: the Flow API.
The spliterators patterns can be found here: https://github.com/JosePaumard/jdk8-spliterators.
The slides of my JavaOne 2016 talk. This talk is a tutorial on how to write lambda expressions, how to compose them using default methods in functional interfaces, and how to create factory methods in those interfaces. Many examples and patterns are provided.
The slides of my JavaOne 2017 talk. It describes how you can create API using functional interfaces, default and static methods starting with Java 8. You can watch the video here: https://www.youtube.com/watch?v=64UO1YjVcZ0
Java 8 will ship with a powerful new abstraction - Lambda Expressions (aka Closures) and a completely retooled set of Collections libraries. In addition interfaces have changed through the addition of default and static methods.
The ongoing debate as to whether Java should include such language changes has resulted in many vocal opinions being espoused. Sadly few of these opinions have been backed up by practical experimentation and experience.
* Are these opinions just myths?
* What mistakes does a developer make?
* Can a ‘blue collar’ Java Developer cope with functional programming?
* Can we avoid these mistakes in future?
In London we’ve been running a series of hackdays trying out Lambda Expressions as part of the Adopt-a-JSR program and have been recording and analysing the results. This gives us unprecedented insight into what will happen in future.
Java 8 Stream API. A different way to process collections.David Gómez García
A look on one of the features of Java 8 hidden behind the lambdas. A different way to iterate Collections. You'll never see the Collecions the same way.
These are the slides I used on my talk at the "Tech Thursday" by Oracle in June in Madrid.
Jaoo - Open Social A Standard For The Social WebPatrick Chanezon
see http://jaoo.dk/presentation/OpenSocial%2C+a+Standard+for+the+Social+Web
OpenSocial is a standard for the social web managed by the OpenSocial foundation. Introduced by 18 social sites in november 2007, after 8 months OpenSocial is available to 275 million users, 2000 applications have been developed and 10 million users are using them daily.
The session will start with a status of OpenSocial after a year: the ecosystem that formed around the API: social sites, developers, advertisers, tool vendors, IT consulting firms, enterprise software vendors.
For developers of social application, the OpenSocial API JavaScript and REST APIs will be described, with demos of how to build a social application using each API.
For developers of social sites, or sites that want to become OpenSocial containers, the OpenSocial reference implementation is developed as an open source project, Apache Shindig, with a Java and PHP flavors. The stated goal of Shindig is to enable a social site developer to implement OpenSocial support on her site in 2 weeks. The Shindig Java architecture will be explained, followed by a demo of how to connect Shindig to a MySql backend.
Various related projects will also be demoed:
- Friend Connect, a Google offering enabling web sites to add social capabilities with a few lines of javascript.
- Socialsite, a Sun open source project based on Shindig, enabling web sites to become social sites with their own community, using gadgets to provide a user interface to manage the network.
- OpenSocket, a hosted service that allows OpenSocial applications to be deployed on Facebook.
Talk on how to think when building Android apps using a reactive Clean Architecture. This talk was held at the Stockholm Android Meetup group April 17 2018 at Developers bay.
The Loom project has been under work for many years, and just delivered Virtual Threads as a preview feature in the JDK 19. We now have a very precise idea of what they are and what you can do with them. Our good old Threads, created more than 25 years ago, will see a new kind of lightweight threads. This presentation shows you that creating a thread is easier and much cheaper, allowing the creation of millions of them in a single JVM. These virtual threads can be block at almost no cost. These new virtual threads bring with them new notions that will be covered in this talk. Loom threads are coming, and they will change the landscape of concurrent programming in Java.
The features released between Java 11 and Java 17 have brought a greater opportunity for developers to improve application development productivity as well and code expressiveness and readability. In this deep-dive session, you will discover all the recent Project Amber features added to the Java language such as Text blocks, Records (including Records serialization), Pattern Matching for instanceof, switch expression, sealed classes, and pattern matching for switch. The main goal of the Amber Project is to bring Pattern Matching to the Java platform, which will impact both the language and the JDK APIs. You will discover record patterns, array patterns, as well as deconstruction patterns, through constructors, factory methods, and deconstructors.
The Future of Java: Records, Sealed Classes and Pattern MatchingJosé Paumard
The release of the JDK 17 brings interesting features in the Java language: sealed types and pattern matching for switch. Along with the introduction of records, the implementation of pattern matching in the Java language begins to take shape. This presentation shows you how records, sealed types, and pattern matching can change the way we write Java code, on real patterns. It also shows you what we can expect to see on this topic in the future. It is mostly a live coding presentation, with some slides when the code is shown cannot be executed.
The features released between Java 11 and Java 17 have brought a greater opportunity for developers to improve application development productivity as well and code expressiveness and readability. In this deep-dive session, you will discover all the recent Project Amber features added to the Java language such as Records (including Records serialization), Pattern Matching for `instanceof`, switch expression, sealed classes, and hidden classes. The main goal of the Amber Project is to bring Pattern Matching to the Java platform, which will impact both the language and the JDK APsI. You will discover record patterns, array patterns, as well as deconstruction patterns, through constructors, factory methods, and deconstructors.
You can find the code shown here: https://github.com/JosePaumard/devoxx-uk-2021
Designing functional and fluent API: application to some GoF patternsJosé Paumard
These are the slides of my Devnexus 2020 talk. The code is avaiblable on my GitHub account: https://github.com/JosePaumard/devnexus-2020-visitor-lambda. You can see a replay of this talk (in a slightly different version) here: https://youtu.be/gq23w9nycBs
Those are the slides of the presentation we made with Maurice Naftalin à Goto: Copenhagen 2019.
Functional programmers have been saying for decades that they know the way to the future. Clearly they've been wrong, since imperative languages are still far more popular. Clearly they've also been right, as the advantages of functional programming have become increasingly obvious. Is it possible to combine the two models? Scala is one language that does this, and Java too has been on a journey, which still continues, of learning from functional languages and carefully adding features from them. In this talk, we'll review what Java has learned from functional languages, what it can still learn, and how its added features compare to Scala's original ones.
Slides from the talk we did with Maurice Naftalin for Devoxx Belgium 2019.
Functional programmers have been saying for decades that they know the way to the future.
Clearly they have been wrong, since imperative languages are still far more popular.
Clearly they have also been right, as the advantages of functional programming have become increasingly obvious. Is it possible to face both ways, and combine the two models?
Scala is one language that does this, and Java too has been on a journey, which still continues, of learning from functional languages and carefully adding features from them.
In this talk, we will review what Java has learned from functional languages, what it can still learn, and how its added features compare to Scala's original ones.
Designing functional and fluent API: example of the Visitor PatternJosé Paumard
This is the slide deck of my talk from Devoxx Belgium 2019. You can watch the video here https://www.youtube.com/watch?v=gq23w9nycBs and get the code here: https://github.com/JosePaumard/devoxx-belgium-2019-visitor-lambda.
Among the patterns from the GoF, the Visitor is probably the more complex to implement. One of the difficulties is that you need to implement it in your object model, leading to complex refactoring for legacy applications. Based on the use of all the nifty tools brought by functional programming: chaining, composition, and partial application, you can implement Visitors without having to change your object model, using a functional and fluent API. This approach can be used to implement other patterns: Builder and Validator. Using this way of designing API leads to readable and robust code, designed following the GoF patterns.
Les slides du Tools in Action que j'ai donné à Devoxx France 2019.
Le JDK est open source et son développement aussi. L'ensemble des nouveautés vit sur des branches Mercurial qui peuvent être téléchargées et compilées à la demande. Cela permet de jouer avec des fonctionnalités encore en chantier, de regarder comment les nouvelles syntaxes fonctionneront, bref, de jouer avec un JDK du futur, qui n'existera peut-être jamais. L'objet de ce tools in action est simple : montrer comment tout ceci fonctionne, de l'installation d'une machine Ubuntu à l'exécution d'un JDK recompilé maison.
Le slide deck de l'Université que nous avons donnée avec Rémi Forax à Devoxx France 2019.
Comme promis, Java sort sa version majeure tous les 6 mois. Le train passe et amène son lot de nouveautés. Parmi elles, certaines sont sorties : une nouvelle syntaxe pour les clauses switch et l'instruction de byte code CONSTANT_DYNAMIC. D'autres sont en chantier, plus ou moins avancé : une nouvelle façon d'écrire des méthodes de façon condensée, un instanceof 'intelligent', des constantes évaluées au moment où elles sont utilisées. Les projets progressent. Loom, et son nouveau modèle de programmation concurrente que l'ont peut tester avec Jetty. Amber, qui introduit les data types et des nouvelles syntaxes. Valhalla, dont les value types donnent leurs premiers résultats. S'il est difficile de prévoir une date de sortie pour ces nouveautés, on sait en revanche qu'une fois prêtes elles sortiront en moins de 6 mois. De tout ceci nous parlerons donc au futur et en public, avec des démonstrations de code, des slides, du code, de la joie et de la bonne humeur !
Slides of the talk we gave with David Delabassee at Oracle Code One 2018.
The FnProject was released about a year ago, proposing new ways to design asynchronous systems in a very flexible way. This tutorial shows you how to set up a Fn Server on a local development machine running Windows with a first simple function. Then we cover the design of multi-functions systems, connected together in an asynchronous way, leveraging the Fn Flow API. This API is first presented, including how it compares to the the Java 8 CompletableFuture API. We then set up a real example made of several functions, producing multiple results and see how we can leverage their asynchronous nature to make a non-blocking system, handling errors in a simple and intuitive way. Most of the examples are shown both on slides and live coding parts.
Avec la version 9 sortie en septembre 2017, Java appuie sur la pédale ! Le rythme des livraisons passe à une version majeure tous les 6 mois. Java 10 est sorti en mars, prochaine version en septembre. Java 10 apporte le 'var' et l'inférence de type pour les variables locales. D'autres nouveautés sont en préparation : les constantes dynamiques, les classes de données, un nouveau switch à base de lambda, des interfaces fermées, de nouvelles choses du coté des génériques et bien plus encore.
Cela viendra-t-il en 11, 12, 15 ? Ne spéculons pas, mais quand ces nouveautés seront prêtes, elles sortiront en quelques mois. On se propose de présenter ces nouveautés, celles qui sont presque prêtes, celles qui seront prêtes bientôt, et celles qui ne seront pas prêtes avant un moment. Quels seront les impacts sur le langage, sur la JVM et donc sur les performances ? Que cela va-t-il nous apporter au quotidien, en tant que développeurs ? Quels seront les nouveaux patterns ? Voici le programme de cette présentation, avec des slides, du code, de la joie et de la bonne humeur !
JAX-RS and CDI Bike the (Reactive) BridgeJosé Paumard
This session explains how JAX-RS and CDI became reactive capable in Java EE 8. We put some new features of JAX-RS 2.1 and CDI 2.0 into perspective and show some reactive patterns to improve your application. Add Java 8 CompletionStage to the mix and this API trio becomes your best bet to easily go reactive without leaving the Java EE train.
The slides of my talk at Devoxx BE 2017. This in depth talk is all about collectors: those available, because we need to know them, those that we can create, those we had no idea they could be created, and the others, as there is in fact no limit to what can be done with this API. The concept of downstream collector will be used to show how we can write entire data processing pipelines using collectors only, and pass them as parameters to other pipelines.
The slides of my Java One 2017 talk about the Spliterator Patterns, or, how to extend the Stream API using the Spliterator API.
The video is available on YouTube: https://www.youtube.com/watch?v=xgHGpsubL5M
The slides of my university talk, Devoxx Belgium 2016.
The goal of this talk is to compare the two most popular implementations of List: LinkedList and ArrayList, and provide hints on which one to use in what case.
ArrayList et LinkedList sont dans un bateauJosé Paumard
Slides de mon université à Devoxx France 2016. Le sujet est la performance des algorithmes d'implémentation de List et leur adéquation avec la structure des CPU actuels.
Slides of the talk we made with David Delabasee (@delabassee) at Devoxx 2015. A list of Java SE 8 patterns that you can use in Java EE 7 applications, thanks to the support of the major app servers.
June 3, 2024 Anti-Semitism Letter Sent to MIT President Kornbluth and MIT Cor...Levi Shapiro
Letter from the Congress of the United States regarding Anti-Semitism sent June 3rd to MIT President Sally Kornbluth, MIT Corp Chair, Mark Gorenberg
Dear Dr. Kornbluth and Mr. Gorenberg,
The US House of Representatives is deeply concerned by ongoing and pervasive acts of antisemitic
harassment and intimidation at the Massachusetts Institute of Technology (MIT). Failing to act decisively to ensure a safe learning environment for all students would be a grave dereliction of your responsibilities as President of MIT and Chair of the MIT Corporation.
This Congress will not stand idly by and allow an environment hostile to Jewish students to persist. The House believes that your institution is in violation of Title VI of the Civil Rights Act, and the inability or
unwillingness to rectify this violation through action requires accountability.
Postsecondary education is a unique opportunity for students to learn and have their ideas and beliefs challenged. However, universities receiving hundreds of millions of federal funds annually have denied
students that opportunity and have been hijacked to become venues for the promotion of terrorism, antisemitic harassment and intimidation, unlawful encampments, and in some cases, assaults and riots.
The House of Representatives will not countenance the use of federal funds to indoctrinate students into hateful, antisemitic, anti-American supporters of terrorism. Investigations into campus antisemitism by the Committee on Education and the Workforce and the Committee on Ways and Means have been expanded into a Congress-wide probe across all relevant jurisdictions to address this national crisis. The undersigned Committees will conduct oversight into the use of federal funds at MIT and its learning environment under authorities granted to each Committee.
• The Committee on Education and the Workforce has been investigating your institution since December 7, 2023. The Committee has broad jurisdiction over postsecondary education, including its compliance with Title VI of the Civil Rights Act, campus safety concerns over disruptions to the learning environment, and the awarding of federal student aid under the Higher Education Act.
• The Committee on Oversight and Accountability is investigating the sources of funding and other support flowing to groups espousing pro-Hamas propaganda and engaged in antisemitic harassment and intimidation of students. The Committee on Oversight and Accountability is the principal oversight committee of the US House of Representatives and has broad authority to investigate “any matter” at “any time” under House Rule X.
• The Committee on Ways and Means has been investigating several universities since November 15, 2023, when the Committee held a hearing entitled From Ivory Towers to Dark Corners: Investigating the Nexus Between Antisemitism, Tax-Exempt Universities, and Terror Financing. The Committee followed the hearing with letters to those institutions on January 10, 202
A Strategic Approach: GenAI in EducationPeter Windle
Artificial Intelligence (AI) technologies such as Generative AI, Image Generators and Large Language Models have had a dramatic impact on teaching, learning and assessment over the past 18 months. The most immediate threat AI posed was to Academic Integrity with Higher Education Institutes (HEIs) focusing their efforts on combating the use of GenAI in assessment. Guidelines were developed for staff and students, policies put in place too. Innovative educators have forged paths in the use of Generative AI for teaching, learning and assessments leading to pockets of transformation springing up across HEIs, often with little or no top-down guidance, support or direction.
This Gasta posits a strategic approach to integrating AI into HEIs to prepare staff, students and the curriculum for an evolving world and workplace. We will highlight the advantages of working with these technologies beyond the realm of teaching, learning and assessment by considering prompt engineering skills, industry impact, curriculum changes, and the need for staff upskilling. In contrast, not engaging strategically with Generative AI poses risks, including falling behind peers, missed opportunities and failing to ensure our graduates remain employable. The rapid evolution of AI technologies necessitates a proactive and strategic approach if we are to remain relevant.
How to Make a Field invisible in Odoo 17Celine George
It is possible to hide or invisible some fields in odoo. Commonly using “invisible” attribute in the field definition to invisible the fields. This slide will show how to make a field invisible in odoo 17.
Honest Reviews of Tim Han LMA Course Program.pptxtimhan337
Personal development courses are widely available today, with each one promising life-changing outcomes. Tim Han’s Life Mastery Achievers (LMA) Course has drawn a lot of interest. In addition to offering my frank assessment of Success Insider’s LMA Course, this piece examines the course’s effects via a variety of Tim Han LMA course reviews and Success Insider comments.
The Roman Empire A Historical Colossus.pdfkaushalkr1407
The Roman Empire, a vast and enduring power, stands as one of history's most remarkable civilizations, leaving an indelible imprint on the world. It emerged from the Roman Republic, transitioning into an imperial powerhouse under the leadership of Augustus Caesar in 27 BCE. This transformation marked the beginning of an era defined by unprecedented territorial expansion, architectural marvels, and profound cultural influence.
The empire's roots lie in the city of Rome, founded, according to legend, by Romulus in 753 BCE. Over centuries, Rome evolved from a small settlement to a formidable republic, characterized by a complex political system with elected officials and checks on power. However, internal strife, class conflicts, and military ambitions paved the way for the end of the Republic. Julius Caesar’s dictatorship and subsequent assassination in 44 BCE created a power vacuum, leading to a civil war. Octavian, later Augustus, emerged victorious, heralding the Roman Empire’s birth.
Under Augustus, the empire experienced the Pax Romana, a 200-year period of relative peace and stability. Augustus reformed the military, established efficient administrative systems, and initiated grand construction projects. The empire's borders expanded, encompassing territories from Britain to Egypt and from Spain to the Euphrates. Roman legions, renowned for their discipline and engineering prowess, secured and maintained these vast territories, building roads, fortifications, and cities that facilitated control and integration.
The Roman Empire’s society was hierarchical, with a rigid class system. At the top were the patricians, wealthy elites who held significant political power. Below them were the plebeians, free citizens with limited political influence, and the vast numbers of slaves who formed the backbone of the economy. The family unit was central, governed by the paterfamilias, the male head who held absolute authority.
Culturally, the Romans were eclectic, absorbing and adapting elements from the civilizations they encountered, particularly the Greeks. Roman art, literature, and philosophy reflected this synthesis, creating a rich cultural tapestry. Latin, the Roman language, became the lingua franca of the Western world, influencing numerous modern languages.
Roman architecture and engineering achievements were monumental. They perfected the arch, vault, and dome, constructing enduring structures like the Colosseum, Pantheon, and aqueducts. These engineering marvels not only showcased Roman ingenuity but also served practical purposes, from public entertainment to water supply.
Biological screening of herbal drugs: Introduction and Need for
Phyto-Pharmacological Screening, New Strategies for evaluating
Natural Products, In vitro evaluation techniques for Antioxidants, Antimicrobial and Anticancer drugs. In vivo evaluation techniques
for Anti-inflammatory, Antiulcer, Anticancer, Wound healing, Antidiabetic, Hepatoprotective, Cardio protective, Diuretics and
Antifertility, Toxicity studies as per OECD guidelines
Unit 8 - Information and Communication Technology (Paper I).pdfThiyagu K
This slides describes the basic concepts of ICT, basics of Email, Emerging Technology and Digital Initiatives in Education. This presentations aligns with the UGC Paper I syllabus.
Read| The latest issue of The Challenger is here! We are thrilled to announce that our school paper has qualified for the NATIONAL SCHOOLS PRESS CONFERENCE (NSPC) 2024. Thank you for your unwavering support and trust. Dive into the stories that made us stand out!
Introduction to AI for Nonprofits with Tapp NetworkTechSoup
Dive into the world of AI! Experts Jon Hill and Tareq Monaur will guide you through AI's role in enhancing nonprofit websites and basic marketing strategies, making it easy to understand and apply.
Palestine last event orientationfvgnh .pptxRaedMohamed3
An EFL lesson about the current events in Palestine. It is intended to be for intermediate students who wish to increase their listening skills through a short lesson in power point.
Francesca Gottschalk - How can education support child empowerment.pptxEduSkills OECD
Francesca Gottschalk from the OECD’s Centre for Educational Research and Innovation presents at the Ask an Expert Webinar: How can education support child empowerment?
14. @JosePaumard
#J8Stream
What is a stream?
Answer 1: a typed interface
public interface Stream<T> extends BaseStream<T, Stream<T>> {
// ...
}
15. @JosePaumard
#J8Stream
What is a stream?
Answer 1: a typed interface
In fact: a new concept in the JDK
public interface Stream<T> extends BaseStream<T, Stream<T>> {
// ...
}
20. @JosePaumard
#J8Stream
What is a stream?
What does efficiently mean?
Two things:
1)in parallel, to leverage multicore CPU
21. @JosePaumard
#J8Stream
What is a stream?
What does efficiently mean?
Two things:
1)in parallel, to leverage multicore CPU
2)in pipeline, to avoid the computation of intermediate data structures
23. @JosePaumard
#J8Stream
What is a stream?
Why cant a collection be a stream?
In fact there are arguments for a Collection to be a Stream!
24. @JosePaumard
#J8Stream
What is a stream?
Why cant a collection be a stream?
In fact there are arguments for a Collection to be a Stream!
1)this is where my data is!
25. @JosePaumard
#J8Stream
What is a stream?
Why cant a collection be a stream?
In fact there are arguments for a Collection to be a Stream!
1)this is where my data is!
2)and I know the Collection API pretty well…
26. @JosePaumard
#J8Stream
What is a stream?
Why cant a collection be a stream?
Two reasons:
1)we want to be free to create new concepts
27. @JosePaumard
#J8Stream
What is a stream?
Why cant a collection be a stream?
Two reasons:
1)we want to be free to create new concepts
2)we dont want to add those concepts on well-known interfaces
30. @JosePaumard
#J8Stream
So: what is a Stream?
Answers:
1)an object on which I can define operations
2)that does not hold any data
31. @JosePaumard
#J8Stream
So: what is a Stream?
Answers:
1)an object on which I can define operations
2)that does not hold any data
3)that will not modify the data it processes
32. @JosePaumard
#J8Stream
So: what is a Stream?
Answers:
1)an object on which I can define operations
2)that does not hold any data
3)that will not modify the data it processes
4)that will process data in « one pass »
33. @JosePaumard
#J8Stream
So: what is a Stream?
Answers:
1)an object on which I can define operations
2)that does not hold any data
3)that will not modify the data it processes
4)that will process data in « one pass »
5)that is built on higly optimized algorithms, and that can work in parallel
35. @JosePaumard
#J8Stream
How can I build a Stream?
Many patterns!
Let us take one:
List<Person> persons = ... ;
Stream<Person> stream = persons.stream() ;
36. @JosePaumard
#J8Stream
Operations on a Stream
Let us see a first operation: forEach()
… that will display each person
List<Person> persons = ... ;
Stream<Person> stream = persons.stream() ;
stream.forEach(p -> System.out.println(p)) ;
37. @JosePaumard
#J8Stream
Operations on a Stream
Let us see a first operation: forEach()
… that will display each person
List<Person> persons = ... ;
Stream<Person> stream = persons.stream() ;
stream.forEach(System.out::println) ;
38. @JosePaumard
#J8Stream
Operations on a Stream
Let us see a first operation: forEach()
… that will display each person
List<Person> persons = ... ;
Stream<Person> stream = persons.stream() ;
stream.forEach(System.out::println) ;
o -> System.out.println(o) ≡ System.out::println
39. @JosePaumard
#J8Stream
Operation: forEach()
First operation: forEach()
forEach(): takes a Consumer<T> as a parameter
@FunctionalInterface public interface Consumer<T> { void accept(T t) ; }
40. @JosePaumard
#J8Stream
Operation: forEach()
First operation: forEach()
forEach(): takes a Consumer<T> as a parameter
What is a functional interface?
@FunctionalInterface
public interface Consumer<T> {
void accept(T t) ;
}
42. @JosePaumard
#J8Stream
Functional interface
Definition:
an interface with only one abstract method
(methods from Object do not count)
43. @JosePaumard
#J8Stream
Functional interface
Definition:
an interface with only one abstract method
(methods from Object do not count)
(default & static methods do not count)
44. @JosePaumard
#J8Stream
Functional interface
Definition:
an interface with only one abstract method
(methods from Object do not count)
(default & static methods do not count)
It « can » be annotated by @FunctionalInterface
45. @JosePaumard
#J8Stream
Functional interface
Definition:
an interface with only one abstract method
(methods from Object do not count)
(default & static methods do not count)
It « can » be annotated by @FunctionalInterface
If present: the Java 8 compiler will help me
46. @JosePaumard
#J8Stream
In fact…
Consumer is a bit more complex than that:
@FunctionalInterface
public interface Consumer<T> {
void accept(T t) ;
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
47. @JosePaumard
#J8Stream
In fact…
What is a default method?
@FunctionalInterface
public interface Consumer<T> {
void accept(T t) ;
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
49. @JosePaumard
#J8Stream
Default methods
New concept in Java 8!
Added to allow the adding of methods in interfaces without breaking the old implementations
50. @JosePaumard
#J8Stream
Default methods
New concept in Java 8!
Added to allow the adding of methods in interfaces without breaking the old implementations
Ex: stream() on the Collection interface
53. @JosePaumard
#J8Stream
Back to the Consumer interface
@FunctionalInterface
public interface Consumer<T> {
void accept(T t) ;
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
54. @JosePaumard
#J8Stream
Back to the Consumer interface
List<String> list = new ArrayList<>() ;
Consumer<String> c1 = s -> list.add(s) ;
Consumer<String> c2 = s -> System.out.println(s) ;
55. @JosePaumard
#J8Stream
Back to the Consumer interface
List<String> list = new ArrayList<>() ;
Consumer<String> c1 = list::add ;
Consumer<String> c2 = System.out::println ;
56. @JosePaumard
#J8Stream
Back to the Consumer interface
List<String> list = new ArrayList<>() ;
Consumer<String> c1 = list::add ;
Consumer<String> c2 = System.out::println ;
Consumer<String> c3 = c1.andThen(c2) ; // and we could chain more
57. @JosePaumard
#J8Stream
Back to the Consumer interface
Beware concurrency!
List<String> result = new ArrayList<>() ;
List<Person> persons = ... ;
Consumer<String> c1 = list::add ;
persons.stream()
.forEach(c1) ; // concurrency?
58. @JosePaumard
#J8Stream
Back to the Consumer interface
Beware concurrency!
List<String> result = new ArrayList<>() ;
List<Person> persons = ... ;
Consumer<String> c1 = list::add ;
persons.stream().parallel()
.forEach(c1) ; // concurrency?
59. @JosePaumard
#J8Stream
Back to the Consumer interface
Beware concurrency!
List<String> result = new ArrayList<>() ;
List<Person> persons = ... ;
Consumer<String> c1 = list::add ;
persons.stream().parallel()
.forEach(c1) ; // concurrency? Baaaad pattern!
60. @JosePaumard
#J8Stream
Back to the Consumer interface
Problem: forEach() returns void
List<String> result = new ArrayList<>() ;
List<Person> persons = ... ;
Consumer<String> c1 = list::add ;
Consumer<String> c2 = System.out::println
persons.stream()
.forEach(c1.andThen(c2)) ;
61. @JosePaumard
#J8Stream
Back to the Consumer interface
But I also have a peek() method
That returns another Stream
List<String> result = new ArrayList<>() ;
List<Person> persons = ... ;
persons.stream()
.peek(System.out::println)
.filter(person -> person.getAge() > 20)
.peek(result::add) ; // Baaad pattern !
66. @JosePaumard
#J8Stream
Interface Predicate
Another functional interface
@FunctionalInterface public interface Predicate<T> { boolean test(T t) ; }
67. @JosePaumard
#J8Stream
Interface Predicate
In fact Predicate looks like this:
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t) ;
default Predicate<T> and(Predicate<? super T> other) { ... }
default Predicate<T> or(Predicate<? super T> other) { ... }
default Predicate<T> negate() { ... }
}
68. @JosePaumard
#J8Stream
Interface Predicate
default Predicate<T> and(Predicate<? super T> other) {
return t -> test(t) && other.test(t) ;
}
default Predicate<T> or(Predicate<? super T> other) { return t -> test(t) || other.test(t) ; }
default Predicate<T> negate() {
return t -> !test(t) ;
}
69. @JosePaumard
#J8Stream
Interface Predicate: patterns
Predicate<Integer> p1 = i -> i > 20 ;
Predicate<Integer> p2 = i -> i < 30 ;
Predicate<Integer> p3 = i -> i == 0 ;
70. @JosePaumard
#J8Stream
Interface Predicate: patterns
Predicate<Integer> p1 = i -> i > 20 ;
Predicate<Integer> p2 = i -> i < 30 ;
Predicate<Integer> p3 = i -> i == 0 ;
Predicate<Integer> p = p1.and(p2).or(p3) ; // (p1 AND p2) OR p3
71. @JosePaumard
#J8Stream
Interface Predicate: patterns
Predicate<Integer> p1 = i -> i > 20 ;
Predicate<Integer> p2 = i -> i < 30 ;
Predicate<Integer> p3 = i -> i == 0 ;
Predicate<Integer> p = p1.and(p2).or(p3) ; // (p1 AND p2) OR p3
Predicate<Integer> p = p3.or(p1).and(p2) ; // (p3 OR p1) AND p2
72. @JosePaumard
#J8Stream
Interface Predicate
In fact Predicate looks like this (bis):
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t) ;
// default methods
static <T> Predicate<T> isEqual(Object o) { ... }
}
74. @JosePaumard
#J8Stream
Interface Predicate
In fact things are bit more complicated:
static <T> Predicate<T> isEqual(Object o) {
return t -> o.equals(t) ;
}
static <T> Predicate<T> isEqual(Object o) {
return (null == o)
? obj -> Objects.isNull(obj)
: t -> o.equals(t) ;
}
75. @JosePaumard
#J8Stream
Interface Predicate
In fact things are bit more complicated:
static <T> Predicate<T> isEqual(Object o) {
return t -> o.equals(t) ;
}
static <T> Predicate<T> isEqual(Object o) {
return (null == o)
? Objects::isNull
: o::equals ;
}
76. @JosePaumard
#J8Stream
Interface Predicate
We also have:
@FunctionalInterface
public interface BiPredicate<T, U> {
boolean test(T t, U u);
}
77. @JosePaumard
#J8Stream
Filtered Streams
In this code:
stream and filtered are different objects
The filter() method returns a new object
List<Person> list = ... ;
Stream<Person> stream = list.stream() ;
Stream<Person> filtered =
stream.filter(person -> person.getAge() > 20) ;
78. @JosePaumard
#J8Stream
Filtered Streams
In this code:
Question 1: what do we have in the filtered object?
List<Person> list = ... ;
Stream<Person> stream = list.stream() ;
Stream<Person> filtered =
stream.filter(person -> person.getAge() > 20) ;
79. @JosePaumard
#J8Stream
Filtered Streams
In this code:
Question 1: what do we have in the filtered object?
Answer: the filtered data!
List<Person> list = ... ;
Stream<Person> stream = list.stream() ;
Stream<Person> filtered =
stream.filter(person -> person.getAge() > 20) ;
80. @JosePaumard
#J8Stream
Filtered Streams
In this code:
Question 1: what do we have in the filtered object?
Answer: the filtered data… really?
List<Person> list = ... ;
Stream<Person> stream = list.stream() ;
Stream<Person> filtered =
stream.filter(person -> person.getAge() > 20) ;
81. @JosePaumard
#J8Stream
Filtered Streams
In this code:
Question 1: what do we have in the filtered object?
Didnt we say: « a stream does not hold any data »?
List<Person> list = ... ;
Stream<Person> stream = list.stream() ;
Stream<Person> filtered =
stream.filter(person -> person.getAge() > 20) ;
82. @JosePaumard
#J8Stream
Filtered Streams
In this code:
Question 1: what do we have in the filtered object?
Correct answer: nothing!
List<Person> list = ... ;
Stream<Person> stream = list.stream() ;
Stream<Person> filtered =
stream.filter(person -> person.getAge() > 20) ;
83. @JosePaumard
#J8Stream
Filtered Streams
In this code:
Question 2: what does this code do?
List<Person> list = ... ;
Stream<Person> stream = list.stream() ;
Stream<Person> filtered =
stream.filter(person -> person.getAge() > 20) ;
84. @JosePaumard
#J8Stream
Filtered Streams
In this code:
Question 2: what does this code do?
Answer: nothing…
List<Person> list = ... ;
Stream<Person> stream = list.stream() ;
Stream<Person> filtered =
stream.filter(person -> person.getAge() > 20) ;
85. @JosePaumard
#J8Stream
Filtered Streams
In this code:
Question 2: what does this code do?
Answer: nothing…
This call is a declaration, no data is processed!
List<Person> list = ... ;
Stream<Person> stream = list.stream() ;
Stream<Person> filtered =
stream.filter(person -> person.getAge() > 20) ;
86. @JosePaumard
#J8Stream
Filtered Streams
The filter() call is a lazy call
Generally speaking:
A call to a method that returns a Stream is a lazy call
87. @JosePaumard
#J8Stream
Filtered Streams
The filter() call is a lazy call
Another way of saying it:
An operation that returns a Stream is an intermediate operation
88. @JosePaumard
#J8Stream
Intermediate call
Stating that a Stream does not hold any data
creates the notion of intermediate operation
adds the notion of lazyness to the Stream API
89. @JosePaumard
#J8Stream
Intermediate call
Stating that a Stream does not hold any data
creates the notion of intermediate operation
adds the notion of lazyness to the Stream API
There must be some kind terminal operation somewhere…
90. @JosePaumard
#J8Stream
Back to Consumer (bis)
What happens in that code?
List<String> result = new ArrayList<>() ;
List<Person> persons = ... ;
persons.stream()
.peek(System.out::println)
.filter(person -> person.getAge() > 20)
.peek(resultat::add) ; // Baaad pattern !
91. @JosePaumard
#J8Stream
Back to Consumer (bis)
What happens in that code?
Answer is: nothing!
List<String> result = new ArrayList<>() ;
List<Person> persons = ... ;
persons.stream()
.peek(System.out::println)
.filter(person -> person.getAge() > 20)
.peek(result::add) ; // Baaad pattern !
92. @JosePaumard
#J8Stream
Back to Consumer (bis)
What happens in that code?
1) nothing displayed
2) result is empty
List<String> result = new ArrayList<>() ;
List<Person> persons = ... ;
persons.stream()
.peek(System.out::println)
.filter(person -> person.getAge() > 20)
.peek(result::add) ; // Baaad pattern !
93. @JosePaumard
#J8Stream
What do we have so far?
We saw:
-forEach(Consumer)
-peek(Consumer)
-filter(Predicate)
94. @JosePaumard
#J8Stream
What do we have so far?
We saw:
-forEach(Consumer)
-peek(Consumer)
-filter(Predicate)
The notion of lazyness / intermediate call
97. @JosePaumard
#J8Stream
Mapping
Mapping operation
The map() method returns a Stream
It is thus lazy / intermediate
List<Person> list = ... ;
Stream<Person> stream = list.stream() ;
Stream<String> names =
stream.map(person -> person.getName()) ;
98. @JosePaumard
#J8Stream
Interface Function
The map() method takes a Function:
@FunctionalInterface
public interface Function<T, R> {
R apply(T t) ;
}
99. @JosePaumard
#J8Stream
Interface Function
Which in fact is:
@FunctionalInterface
public interface Function<T, R> {
R apply(T t) ;
default <V> Function<V, R> compose(Function<V, T> before) ;
default <V> Function<T, V> andThen(Function<R, V> after) ;
}
100. @JosePaumard
#J8Stream
Interface Function
Which in fact is:
Beware the generics!
@FunctionalInterface
public interface Function<T, R> {
R apply(T t) ;
default <V> Function<V, R> compose(Function<V, T> before) ;
default <V> Function<T, V> andThen(Function<R, V> after) ;
}
101. @JosePaumard
#J8Stream
Interface Function
Which in fact is:
@FunctionalInterface
public interface Function<T, R> {
R apply(T t) ;
default <V> Function<V, R> compose(
Function<? super V, ? extends T> before) ;
default <V> Function<T, V> andThen(
Function<? super R, ? extends V> after) ;
}
102. @JosePaumard
#J8Stream
Interface Function
Which in fact is:
@FunctionalInterface
public interface Function<T, R> {
R apply(T t) ;
// default methods
static <T> Function<T, T> identity() {
return t -> t ;
}
}
103. @JosePaumard
#J8Stream
Other functions
There are special types of functions:
@FunctionalInterface
public interface UnaryOperator<T> extends Function<T, T> {
}
104. @JosePaumard
#J8Stream
Other functions
There are special types of functions:
@FunctionalInterface
public interface BiFunction<T, U, R> {
R apply(T t, U u);
}
105. @JosePaumard
#J8Stream
Other functions
There are special types of functions:
@FunctionalInterface
public interface BinaryOperator<T> extends BiFunction<T, T, T> {
}
106. @JosePaumard
#J8Stream
What do we have so far?
We saw:
-forEach(Consumer)
-peek(Consumer)
-filter(Predicate)
-map(Function)
108. @JosePaumard
#J8Stream
Method flatMap()
flatMap() = flattens a Stream
The signature is:
The passed function returns a Stream
<R> Stream<R> flatMap(Function<T, Stream<R>> mapper) ;
109. @JosePaumard
#J8Stream
Method flatMap()
Let us take an example:
List<Movie> movies = ... ; // a movie has a set of Actor
movies.stream()
.map(movie -> movie.actors()) // Stream<Set<Actors>>
110. @JosePaumard
#J8Stream
Method flatMap()
Let us take an example:
List<Movie> movies = ... ; // a movie has a set of Actor
movies.stream()
.map(movie -> movie.actors().stream()) // Stream<Stream<Actors>>
111. @JosePaumard
#J8Stream
Method flatMap()
Let us take an example:
List<Movie> movies = ... ; // a movie has a set of Actor
movies.stream()
.map(movie -> movie.actors().stream()) // Stream<Stream<Actors>>
Function<Movie, Stream<Actors>> mapper =
movie -> movie.actors().stream();
112. @JosePaumard
#J8Stream
Method flatMap()
Let us take an example:
List<Movie> movies = ... ; // a movie has a set of Actor movies.stream() .flatMap(movie -> movie.actors().stream()) // Stream<Actors>
114. @JosePaumard
#J8Stream
Method flatMap()
flatMap() = flattens a Stream
Signature:
Since it returns a Stream, it is a lazy / intermediate call
<R> Stream<R> flatMap(Function<T, Stream<R>> mapper) ;
115. @JosePaumard
#J8Stream
What do we have so far?
We have 3 types of methods:
-forEach(): consumes
-peek(): consumes, and transmits
-filter(): filters
-map(): transforms
-flatMap(): transforms and flattens
118. @JosePaumard
#J8Stream
Reduction
Reduction method:
Two things to stress out here
List<Integer> ages = ... ;
Stream<Integer> stream = ages.stream() ;
Integer sum =
stream.reduce(0, (age1, age2) -> age1 + age2) ;
119. @JosePaumard
#J8Stream
Reduction
Reduction method:
Two things to stress out here
List<Integer> ages = ... ;
Stream<Integer> stream = ages.stream() ;
Integer sum =
stream.reduce(0, Intege::sum) ;
120. @JosePaumard
#J8Stream
Reduction
Reduction method:
0 is the « default value » of the reduction operation
returned if the stream is « empty »
List<Integer> ages = ... ;
Stream<Integer> stream = ages.stream() ;
Integer sum =
stream.reduce(0, (age1, age2) -> age1 + age2) ;
121. @JosePaumard
#J8Stream
Reduction
Reduction method:
0 is the « default value » of the reduction operation
This « default value » has to be the identity element of the reduction operation
List<Integer> ages = ... ;
Stream<Integer> stream = ages.stream() ;
Integer sum =
stream.reduce(0, (age1, age2) -> age1 + age2) ;
122. @JosePaumard
#J8Stream
Reduction
Reduction method:
0 is the « default value » of the reduction operation
If it is not, then the computation will fail!
List<Integer> ages = ... ;
Stream<Integer> stream = ages.stream() ;
Integer sum =
stream.reduce(0, (age1, age2) -> age1 + age2) ;
123. @JosePaumard
#J8Stream
Reduction
Why?
-This 0 is returned in case of an empty Stream
-Red(0, p) is returned in case of a singleton Stream
In fact, 0 is used to compute the reduction of the Stream
125. @JosePaumard
#J8Stream
Reduction
What is going to happen if the reduction operation has no identity value?
But of course we do not use such reductions…
126. @JosePaumard
#J8Stream
Reduction
Reduction method:
The reduction operation should be associative
List<Integer> ages = ... ;
Stream<Integer> stream = ages.stream() ;
Integer sum =
stream.reduce(0, (age1, age2) -> age1 + age2) ;
127. @JosePaumard
#J8Stream
Reduction
Reduction method:
The reduction operation should be associative
If not, we will have trouble in parallel
List<Integer> ages = ... ;
Stream<Integer> stream = ages.stream() ;
Integer sum =
stream.reduce(0, (age1, age2) -> age1 + age2) ;
135. @JosePaumard
#J8Stream
Example of max
Let us reduce with a max
List<Integer> ages = ... ;
Stream<Integer> stream = ages.stream() ;
Integer max =
stream.reduce(0, (age1, age2) -> age1 > age2 ? age1 : age2) ;
136. @JosePaumard
#J8Stream
Example of max
Let us reduce with a max
List<Integer> ages = ... ;
Stream<Integer> stream = ages.stream() ;
Integer max =
stream.reduce(0, Integer::max) ;
137. @JosePaumard
#J8Stream
Example of max
Let us reduce with a max
List<Integer> ages = ... ;
Stream<Integer> stream = ages.stream() ;
Integer max =
stream.reduce(0, (age1, age2) -> age1 > age2 ? age1 : age2) ;
List<Integer> ages = new ArrayList<>() ;
Stream<Integer> stream = ages.stream() ; // empty stream
> max = 0
138. @JosePaumard
#J8Stream
Example of max
Let us reduce with a max
List<Integer> ages = ... ;
Stream<Integer> stream = ages.stream() ;
Integer max =
stream.reduce(0, (age1, age2) -> age1 > age2 ? age1 : age2) ;
List<Integer> ages = Arrays.asList(2) ;
Stream<Integer> stream = ages.stream() ; // singleton stream
> max = 2
139. @JosePaumard
#J8Stream
Example of max
Let us reduce with a max
List<Integer> ages = ... ;
Stream<Integer> stream = ages.stream() ;
Integer max =
stream.reduce(0, (age1, age2) -> age1 > age2 ? age1 : age2) ;
List<Integer> ages = Arrays.asList(-1) ;
Stream<Integer> stream = ages.stream() ; // singleton stream
> max = 0
140. @JosePaumard
#J8Stream
Example of max
Let us reduce with a max
List<Integer> ages = ... ;
Stream<Integer> stream = ages.stream() ;
Integer max =
stream.reduce(0, (age1, age2) -> age1 > age2 ? age1 : age2) ;
List<Integer> ages = Arrays.asList(-1, -2) ;
Stream<Integer> stream = ages.stream() ;
> max = 0
142. @JosePaumard
#J8Stream
Example of max
The reduction with a max has a problem : why?
Answer: the max reduction has no identity element, thus no default value
143. @JosePaumard
#J8Stream
Example of max
The reduction with a max has a problem : why?
Answer: the max reduction has no identity element, thus no default value
Solution: introduce the notion of Optional
144. @JosePaumard
#J8Stream
Method max()
Optional is the return type of the max() method
List<Integer> ages = ... ;
Stream<Integer> stream = ages.stream() ;
Optional<Integer> max =
stream.max(Comparator.naturalOrder()) ;
145. @JosePaumard
#J8Stream
Optional
An Optional is a wrapping type, that can be empty
How can I use it?
Optional<String> opt = ... ;
if (opt.isPresent()) {
String s = opt.get() ;
} else {
...
}
146. @JosePaumard
#J8Stream
Optional
An Optional is a wrapping type, that can be empty
How can I use it?
String s = opt.orElse("") ; // this is a default value that
// is valid for our application
Optional<String> opt = ... ;
if (opt.isPresent()) {
String s = opt.get() ;
} else {
...
}
147. @JosePaumard
#J8Stream
Optional
An Optional is a wrapping type, that can be empty
How can I use it?
String s = opt.orElseThrow(MyException::new) ; // lazy initialization
148. @JosePaumard
#J8Stream
Optional can be built
One can explicitly build optionals
Optional<String> opt = Optional.<String>empty() ;
Optional<String> opt = Optional.of("one") ; // not null
Optional<String> opt = Optional.ofNullable(s) ; // may be null
149. @JosePaumard
#J8Stream
Optional: more patterns
An Optional can be seen as a special Stream with zero or one element
void ifPresent(Consumer<T> consumer) ;
150. @JosePaumard
#J8Stream
Optional: more patterns
An Optional can be seen as a special Stream with zero or one element
void ifPresent(Consumer<T> consumer) ;
Optional<T> filter(Predicate<T> mapper) ;
151. @JosePaumard
#J8Stream
Optional: more patterns
An Optional can be seen as a special Stream with zero or one element
void ifPresent(Consumer<T> consumer) ;
Optional<T> filter(Predicate<T> mapper) ;
Optional<U> map(Function<T, U> mapper) ;
152. @JosePaumard
#J8Stream
Optional: more patterns
An Optional can be seen as a special Stream with zero or one element
void ifPresent(Consumer<T> consumer) ;
Optional<T> filter(Predicate<T> mapper) ;
Optional<U> map(Function<T, U> mapper) ;
Optional<U> flatMap(Function<T, Optional<U>> mapper) ;
153. @JosePaumard
#J8Stream
Optional: new patterns sighted!
public class NewMath {
public static Optional<Double> inv(Double d) {
return d == 0.0d ? Optional.empty() :
Optional.of(1/d) ;
}
public static Optional<Double> sqrt(Double d) {
return d < 0.0d ? Optional.empty() :
Optional.of(Math.sqrt(d)) ;
}
}
164. @JosePaumard
#J8Stream
Back on the reduce() method
Two return types:
List<Integer> ages = ... ;
Stream<Integer> stream = ages.stream() ;
Integer sum =
stream.reduce(0, Integer::sum) ;
List<Integer> ages = ... ;
Stream<Integer> stream = ages.stream() ;
Optional<Integer> opt =
stream.reduce(Integer::sum) ;
165. @JosePaumard
#J8Stream
More on the reduction
A reduction never returns a Stream
-max(), min() [optionals]
-count()
Boolean reductions:
-allMatch(), noneMatch, anyMatch()
Return optionals:
-findFirst(), findAny() (parallel!)
166. @JosePaumard
#J8Stream
Note on the reduction
A reduction never returns a Stream
So it is not a lazy step / intermediate operation
A reduction always triggers the computation
They are terminal operations
169. @JosePaumard
#J8Stream
Terminal operation
Let us write a full map / filter / reduce
List<Person> persons = ... ;
Optional<Integer> age =
persons.map(person -> person.getAge()) // Stream<Integer>
.filter(age -> age > 20) // Stream<Integer>
.min(Comparator.naturalOrder()) ; // terminal operation
170. @JosePaumard
#J8Stream
Terminal operation
Let us write a full map / filter / reduce
List<Person> persons = ... ;
boolean b =
persons.map(person -> person.getLastName())
.allMatch(length < 20) ; // terminal operation
171. @JosePaumard
#J8Stream
Terminal operation
Let us write a full map / filter / reduce
List<Person> persons = ... ;
boolean b =
persons.map(Person::getAge)
.allMatch(length < 20) ; // terminal operation
172. @JosePaumard
#J8Stream
Terminal operation
Let us write a full map / filter / reduce
Much more efficient to compute this in one pass over the data: « short cutting methods »
List<Person> persons = ... ;
boolean b =
persons.map(Person::getAge)
.allMatch(length < 20) ; // terminal operation
173. @JosePaumard
#J8Stream
What is a Stream?
An object on which we can define operations on data
No a priori limit on the size of the data
Typical operations: map / filter / reduce
174. @JosePaumard
#J8Stream
What is a Stream?
Pipeline approach:
1)we define the operations
2)we trigger the computations by calling a terminal operation
175. @JosePaumard
#J8Stream
What is a Stream?
And bytheway:
We can only have one terminal operation for a Stream
In case, another Stream must be built
176. @JosePaumard
#J8Stream
How one can build a Stream?
Let us have a look at the stream() default method
List<Person> persons = new ArrayList<>() ;
Stream<Person> stream = persons.stream() ;
// Collection interface default Stream<E> stream() { return StreamSupport.stream(spliterator(), false); }
177. @JosePaumard
#J8Stream
How one can build a Stream?
Let us have a look at the stream() default method
// StreamSupport class
public static <T> Stream<T> stream(
Spliterator<T> spliterator, boolean parallel) {
Objects.requireNonNull(spliterator) ;
return new ReferencePipeline.Head<>(
spliterator,
StreamOpFlag.fromCharacteristics(spliterator),
parallel) ;
}
178. @JosePaumard
#J8Stream
How one can build a Stream?
The spliterator() is defined in ArrayList
// ArrayList class @Override public Spliterator<E> spliterator() { return new ArrayListSpliterator<>(this, 0, -1, 0); }
179. @JosePaumard
#J8Stream
How one can build a Stream?
The spliterator() is defined in ArrayList
The Spliterator defines how to access the data
ArrayList: it reads the array
// ArrayList class
@Override
public Spliterator<E> spliterator() {
return new ArrayListSpliterator<>(this, 0, -1, 0);
}
180. @JosePaumard
#J8Stream
Spliterator
Let us see the method we need to implement
Consumes the next element, if it exists
// Spliterator interface boolean tryAdvance(Consumer<? super T> action);
181. @JosePaumard
#J8Stream
Spliterator
Let us see the method we need to implement
Consumes the next element, if it exists
A Stream does not assume that all the elements are available at build time
// Spliterator interface
boolean tryAdvance(Consumer<? super T> action);
182. @JosePaumard
#J8Stream
Spliterator
Let us see the method we need to implement
Used in parallel computations: tries to split the data in two (fork / join)
// Spliterator interface Spliterator<T> trySplit();
183. @JosePaumard
#J8Stream
Spliterator
Let us see the method we need to implement
Returns an estimation of the size of this stream
// Spliterator interface
long estimateSize();
184. @JosePaumard
#J8Stream
Spliterator
And there are also default methods
// Spliterator interface default void forEachRemaining(Consumer<? super T> action) { do { } while (tryAdvance(action)); }
// Spliterator interface
default long getExactSizeIfKnown() {
return (characteristics() & SIZED) == 0 ? -1L : estimateSize();
}
185. @JosePaumard
#J8Stream
Spliterator
And there is a last method:
Implémentation for ArrayList
// interface Spliterator
int characteristics();
// pour ArrayList
public int characteristics() {
return Spliterator.ORDERED |
Spliterator.SIZED |
Spliterator.SUBSIZED;
}
186. @JosePaumard
#J8Stream
Spliterator
And there is a last method:
Implémentation for HashSet
// interface Spliterator
int characteristics();
// pour HashSet
public int characteristics() {
return (fence < 0 || est == map.size ? Spliterator.SIZED : 0) |
Spliterator.DISTINCT;
}
187. @JosePaumard
#J8Stream
Characteristics of a Stream
Bits defined in the characteristics word
Characteristic
ORDERED
The order matters
DISTINCT
No duplication
SORTED
Sorted
SIZED
The size is known
NONNULL
No null values
IMMUTABLE
Immutable
CONCURRENT
Parallelism is possible
SUBSIZED
The size is known
188. @JosePaumard
#J8Stream
Characteristics of a Stream
Some operations will switch some bits
Method
Set to 0
Set to 1
filter()
SIZED
-
map()
DISTINCT, SORTED
-
flatMap()
DISTINCT, SORTED, SIZED
-
sorted()
-
SORTED, ORDERED
distinct()
-
DISTINCT
limit()
SIZED
-
peek()
-
-
unordered()
ORDERED
-
189. @JosePaumard
#J8Stream
Characteristics of a Stream
Characteristics are taken into account when computing a result
// HashSet
HashSet<String> strings = ... ;
strings.stream()
.distinct() // no processing is triggered
.sorted()
.collect(Collectors.toList()) ;
190. @JosePaumard
#J8Stream
Characteristics of a Stream
Characteristics are taken into account when computing a result
// SortedSet
TreeSet<String> strings = ... ;
strings.stream()
.distinct()
.sorted() // no processing is triggered
.collect(Collectors.toList()) ;
191. @JosePaumard
#J8Stream
Stream implementation
Complex!
Two parts:
1)algorithms are in ReferencePipeline
2)data access: Spliterator, can be overriden
192. @JosePaumard
#J8Stream
A few words on Comparator
We wrote:
// Comparator interface
Comparator cmp = Comparator.naturalOrder() ;
193. @JosePaumard
#J8Stream
A few words on Comparator
We wrote:
// Comparator interface Comparator cmp = Comparator.naturalOrder() ;
// Comparator interface
@SuppressWarnings("unchecked")
public static <T extends Comparable<? super T>>
Comparator<T> naturalOrder() {
return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;
}
194. @JosePaumard
#J8Stream
A few words on Comparator
// Comparators class
enum NaturalOrderComparator
implements Comparator<Comparable<Object>> {
INSTANCE;
}
195. @JosePaumard
#J8Stream
A few words on Comparator
// Comparators class
enum NaturalOrderComparator
implements Comparator<Comparable<Object>> {
INSTANCE;
}
public class MySingleton { INSTANCE; private MySingleton() {} public static MySingleton getInstance() { // some buggy double-checked locking code return INSTANCE; } }
196. @JosePaumard
#J8Stream
A few words on Comparator
// Comparators class
enum NaturalOrderComparator
implements Comparator<Comparable<Object>> {
INSTANCE;
public int compare(Comparable<Object> c1, Comparable<Object> c2) {
return c1.compareTo(c2);
}
public Comparator<Comparable<Object>> reversed() {
return Comparator.reverseOrder();
}
}
197. @JosePaumard
#J8Stream
A few words on Comparator
So we can write:
// Comparator interface
Comparator<Person> cmp =
Comparator.comparing(Person::getLastName)
.thenComparing(Person::getFirstName)
.thenComparing(Person::getAge) ;
198. @JosePaumard
#J8Stream
A few words on Comparator
Method comparing()
// Comparator interface
public static
<T, U> Comparator<T>
comparing(Function<T, U> keyExtractor) {
Objects.requireNonNull(keyExtractor);
return
(c1, c2) ->
keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}
199. @JosePaumard
#J8Stream
A few words on Comparator
Method comparing()
// Comparator interface
public static
<T, U extends Comparable<U>> Comparator<T>
comparing(Function<T, U> keyExtractor) {
Objects.requireNonNull(keyExtractor);
return (Comparator<T>)
(c1, c2) ->
keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}
200. @JosePaumard
#J8Stream
A few words on Comparator
Method comparing()
// Comparator interface
public static
<T, U extends Comparable<? super U>> Comparator<T>
comparing(Function<? super T, ? extends U> keyExtractor) {
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable)
(c1, c2) ->
keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}
201. @JosePaumard
#J8Stream
A few words on Comparator
Method thenComparing()
// Comparator interface
default
<U> Comparator<T>
thenComparing(Function<T, U> keyExtractor) {
return thenComparing(comparing(keyExtractor));
}
202. @JosePaumard
#J8Stream
A few words on Comparator
Method thenComparing()
// Comparator interface
default
<U extends Comparable<? super U>> Comparator<T>
thenComparing(Function<? super T, ? extends U> keyExtractor) {
return thenComparing(comparing(keyExtractor));
}
203. @JosePaumard
#J8Stream
A few words on Comparator
Method thenComparing()
// Comparator interface
default Comparator<T> thenComparing(Comparator<? super T> other) {
Objects.requireNonNull(other);
return (Comparator<T> & Serializable) (c1, c2) -> {
int res = compare(c1, c2);
return (res != 0) ? res : other.compare(c1, c2);
};
}
204. @JosePaumard
#J8Stream
What do we have so far?
API Stream
-intermediate operations
-terminal operations
-implementation built on 2 classes
205. @JosePaumard
#J8Stream
Stateless / stateful operations
This code:
… selects the 1000 first people of the list
ArrayList<Person> persons = ... ;
Stream<Persons> stream = persons.limit(1_000) ;
206. @JosePaumard
#J8Stream
Stateless / stateful operations
This code:
… selects the 1000 first people of the list
This operations needs a counter
How will it work in parallel?
ArrayList<Person> persons = ... ; Stream<Persons> stream = persons.limit(1_000) ;
208. @JosePaumard
#J8Stream
Stateless / stateful operations
This code:
« the order of the names is the same as the order of the people »
ArrayList<Person> persons = ... ; List<String> names = persons.map(Person::getLastName) .collect(Collectors.toList()) ;
209. @JosePaumard
#J8Stream
Stateless / stateful operations
This code:
« the order of the names is the same as the order of the people »
How will it behave in parallel?
ArrayList<Person> persons = ... ;
List<String> names =
persons.map(Person::getLastName)
.collect(Collectors.toList()) ;
210. @JosePaumard
#J8Stream
Stateless / stateful operations
This code:
« the order of the names is the same as the order of the people »
We should relax this constraint!
ArrayList<Person> persons = ... ; List<String> names = persons.map(Person::getLastName) .unordered() .collect(Collectors.toList()) ;
211. @JosePaumard
#J8Stream
Wrap-up on Stream
One can define operations on a Stream:
-intermediate & terminal
-stateless & stateful
A Stream can be processed in parallel
A Stream has a state, used to optimize computations
212. @JosePaumard
#J8Stream
Stream & performance
Two elements:
-lazy processing, on one pass over the data
-parallel processing
213. @JosePaumard
#J8Stream
Stream & performance
Two elements:
-lazy processing, on one pass over the data
-parallel processing
Stream<T> versus IntStream, LongStream, DoubleStream
214. @JosePaumard
#J8Stream
Stream & performance
Let see this example again:
ArrayList<Person> persons = ... ;
persons.stream()
.map(Person::getAge)
.filter(age -> age > 20)
.sum() ;
215. @JosePaumard
#J8Stream
Stream & performance
Let see this example again:
ArrayList<Person> persons = ... ;
persons.stream() // Stream<Person>
.map(Person::getAge)
.filter(age -> age > 20)
.sum() ;
216. @JosePaumard
#J8Stream
Stream & performance
Let see this example again:
ArrayList<Person> persons = ... ;
persons.stream() // Stream<Person>
.map(Person::getAge) // Stream<Integer> boxing
.filter(age -> age > 20)
.sum() ;
217. @JosePaumard
#J8Stream
Stream & performance
Let see this example again:
ArrayList<Person> persons = ... ;
persons.stream() // Stream<Person>
.map(Person::getAge) // Stream<Integer> boxing
.filter(age -> age > 20) // Stream<Integer> re-boxing re-
.sum() ;
218. @JosePaumard
#J8Stream
Stream & performance
Let see this example again:
ArrayList<Person> persons = ... ;
persons.stream() // Stream<Person>
.map(Person::getAge) // Stream<Integer> boxing
.filter(age -> age > 20) // Stream<Integer> re-boxing re-
.sum() ; // no such sum() method on Stream<T>
219. @JosePaumard
#J8Stream
Stream & performance
Let see this example again
ArrayList<Person> persons = ... ;
persons.stream() // Stream<Person>
.map(Person::getAge) // Stream<Integer> boxing
.filter(age -> age > 20) // Stream<Integer> re-boxing re-
.mapToInt(age -> age.getValue()) // IntStream
.sum() ;
220. @JosePaumard
#J8Stream
Stream & performance
Let see this example again
ArrayList<Person> persons = ... ;
persons.stream() // Stream<Person>
.map(Person::getAge) // Stream<Integer> boxing
.filter(age -> age > 20) // Stream<Integer> re-boxing re-
.mapToInt(Integer::getValue) // IntStream
.sum() ;
221. @JosePaumard
#J8Stream
Stream & performance
Let see this example again
ArrayList<Person> persons = ... ;
persons.stream() // Stream<Person>
.mapToInt(Person::getAge) // IntStream
.filter(age -> age > 20) // IntStream
// .mapToInt(Integer::getValue)
.sum() ;
222. @JosePaumard
#J8Stream
Stream & performance
Let see this example again
ArrayList<Person> persons = ... ;
int sum =
persons.stream() // Stream<Person>
.mapToInt(Person::getAge) // IntStream
.filter(age -> age > 20) // IntStream
// .mapToInt(Integer::getValue)
.sum() ;
223. @JosePaumard
#J8Stream
Stream & performance
Let see this example again
ArrayList<Person> persons = ... ;
??? =
persons.stream() // Stream<Person>
.mapToInt(Person::getAge) // IntStream
.filter(age -> age > 20) // IntStream
// .mapToInt(Integer::getValue)
.max() ;
224. @JosePaumard
#J8Stream
Stream & performance
Let see this example again
ArrayList<Person> persons = ... ;
OptionalInt opt =
persons.stream() // Stream<Person>
.mapToInt(Person::getAge) // IntStream
.filter(age -> age > 20) // IntStream
// .mapToInt(Integer::getValue)
.max() ;
225. @JosePaumard
#J8Stream
Stream & performance
Let see this example again
ArrayList<Person> persons = ... ;
??? =
persons.stream() // Stream<Person>
.mapToInt(Person::getAge) // IntStream
.filter(age -> age > 20) // IntStream
// .mapToInt(Integer::getValue)
.average() ;
226. @JosePaumard
#J8Stream
Stream & performance
Let see this example again
ArrayList<Person> persons = ... ;
OptionalInt opt =
persons.stream() // Stream<Person>
.mapToInt(Person::getAge) // IntStream
.filter(age -> age > 20) // IntStream
// .mapToInt(Integer::getValue)
.average() ;
227. @JosePaumard
#J8Stream
Stream & performance
Let see this example again
sur l’exemple
In one pass we have: count, sum, min, max, average
ArrayList<Person> persons = ... ;
IntSummaryStatistics stats =
persons.stream()
.mapToInt(Person::getAge)
.filter(age -> age > 20)
.summaryStatistics() ;
228. @JosePaumard
#J8Stream
Parallel streams
How to build a parallel Stream?
Built on top of fork / join
ArrayList<Person> persons = ... ;
Stream<Person> stream1 = persons.parallelStream() ;
Stream<Person> stream2 = persons.stream().parallel() ;
229. @JosePaumard
#J8Stream
Parallel streams
By default, a parallel streams uses the default « fork join common pool », defined at the JVM level
The same pool is shared by all the streams
230. @JosePaumard
#J8Stream
Parallelism
By default, a parallel streams uses the default « fork join common pool », defined at the JVM level
By default, the parallelism level is the # of cores
We can set it with a sytem property:
System.setProperty(
"java.util.concurrent.ForkJoinPool.common.parallelism", 2) ;
231. @JosePaumard
#J8Stream
Parallelism
We can also decide the FJ pool for a given Stream
List<Person> persons = ... ;
ForkJoinPool fjp = new ForkJoinPool(2) ;
fjp.submit(
() -> //
persons.stream().parallel() // this is an implementation
.mapToInt(p -> p.getAge()) // of Callable<Integer>
.filter(age -> age > 20) //
.average() //
).get() ;
233. @JosePaumard
#J8Stream
Reduction
A reduction can be seen as a SQL agregation (sum, min, max, avg, etc…)
But it can be seen in a more general sense
236. @JosePaumard
#J8Stream
Reduction
Example: sum()
The result is an integer, its initial value being 0
Adding an element to the result is… adding
237. @JosePaumard
#J8Stream
Reduction
Example: sum()
The result is an integer, its initial value being 0
Adding an element to the result is… adding
Combining two partial results (think parallel) is also « adding »
240. @JosePaumard
#J8Stream
Reduction
So we have 3 operations:
-the definition of a container, which holds the result
-adding an element to that container
241. @JosePaumard
#J8Stream
Reduction
So we have 3 operations:
-the definition of a container, which holds the result
-adding an element to that container
-combining two partialy filled containers
242. @JosePaumard
#J8Stream
Reduction
So we have 3 operations:
-the definition of a container, which holds the result
-adding an element to that container
-combining two partialy filled containers
This is a much more broader vision than just an agregation
243. @JosePaumard
#J8Stream
Reduction
So a reduction is based on 3 operations:
-a constructor: Supplier
-an accumulator: Function
-a combiner: Function
244. @JosePaumard
#J8Stream
Reduction
So a reduction is based on 3 operations:
-a constructor: Supplier
-an accumulator: Function
-a combiner: Function
() -> new StringBuffer() ;
245. @JosePaumard
#J8Stream
Reduction
So a reduction is based on 3 operations:
-a constructor: Supplier
-an accumulator: Function
-a combiner: Function
() -> new StringBuffer() ;
(StringBuffer sb, String s) -> sb.append(s) ;
246. @JosePaumard
#J8Stream
Reduction
So a reduction is based on 3 operations:
-a constructor: Supplier
-an accumulator: Function
-a combiner: Function
() -> new StringBuffer() ;
(StringBuffer sb, String s) -> sb.append(s) ;
(StringBuffer sb1, StringBuffer sb2) -> sb1.append(sb2) ;
247. @JosePaumard
#J8Stream
Reduction
So a reduction is based on 3 operations:
-a constructor: Supplier
-an accumulator: Function
-a combiner: Function
StringBuffer::new ;
StringBuffer::append ;
StringBuffer::append ;
248. @JosePaumard
#J8Stream
Reduction: implementation
Example 1: reducing in a StringBuffer
List<Person> persons = ... ; StringBuffer result = persons.stream() .filter(person -> person.getAge() > 20) .map(Person::getLastName) .collect( StringBuffer::new, // constructor StringBuffer::append, // accumulator StringBuffer::append // combiner ) ;
249. @JosePaumard
#J8Stream
Reduction: collectors
Example 1: using a Collectors
List<Person> persons = ... ; String result = persons.stream() .filter(person -> person.getAge() > 20) .map(Person::getLastName) .collect( Collectors.joining() ) ;
250. @JosePaumard
#J8Stream
Reduction: collectors
Collecting in a String
List<Person> persons = ... ; String result = persons.stream() .filter(person -> person.getAge() > 20) .map(Person::getLastName) .collect( Collectors.joining(", ") ) ;
252. @JosePaumard
#J8Stream
Reduction
Example 2:
-a constructor: Supplier
-an accumulator: Function
-a combiner: Function
() -> new ArrayList() ;
(list, element) -> list.add(element) ;
(list1, list2) -> list1.addAll(list2) ;
253. @JosePaumard
#J8Stream
Reduction
Example 2:
-a constructor: Supplier
-an accumulator: Function
-a combiner: Function
ArrayList::new ;
Collection::add ;
Collection::allAll ;
254. @JosePaumard
#J8Stream
Reduction: implementation
Example 2: reduction in a List
List<Person> persons = ... ; ArrayList<String> names = persons.stream() .filter(person -> person.getAge() > 20) .map(Person::getLastName) .collect( ArrayList::new, // constructor Collection::add, // accumulator Collection::addAll // combiner ) ;
255. @JosePaumard
#J8Stream
Reduction: collectors
Example 2: reduction in a List
List<Person> persons = ... ; List<String> result = persons.stream() .filter(person -> person.getAge() > 20) .map(Person::getLastName) .collect( Collectors.toList() ) ;
256. @JosePaumard
#J8Stream
Reduction: implementation
Example 3: reduction in a Set
List<Person> persons = ... ; HashSet<String> names = persons.stream() .filter(person -> person.getAge() > 20) .map(Person::getLastName) .collect( HashSet::new, // constructor Collection::add, // accumulator Collection::addAll // combiner ) ;
257. @JosePaumard
#J8Stream
Reduction: collectors
Example 3: reduction in a Set
List<Person> persons = ... ; Set<String> result = persons.stream() .filter(person -> person.getAge() > 20) .map(Person::getLastName) .collect( Collectors.toSet() ) ;
258. @JosePaumard
#J8Stream
Reduction: collectors
Example 4: reduction in a given collection
List<Person> persons = ... ; TreeSet<String> result = persons.stream() .filter(person -> person.getAge() > 20) .map(Person::getLastName) .collect( Collectors.toCollection(TreeSet::new) ) ;
260. @JosePaumard
#J8Stream
Collectors: groupingBy
HashMap: age / list of the people
Map<Integer, List<Person>> result =
persons.stream()
.collect(
Collectors.groupingBy(Person::getAge)
) ;
261. @JosePaumard
#J8Stream
Collectors: groupingBy
HashMap: age / # of people
Map<Integer, Long> result =
persons.stream()
.collect(
Collectors.groupingBy(
Person::getAge,
Collectors.counting() // « downstream collector »
)
) ;
262. @JosePaumard
#J8Stream
Collectors: groupingBy
HashMap: age / list of the names
Map<Integer, List<String>> result =
persons.stream()
.collect(
Collectors.groupingBy(
Person::getAge,
Collectors.mapping( //
Person::getLastName // downstream collector
) //
)
) ;
263. @JosePaumard
#J8Stream
Collectors: groupingBy
HashMap: age / names joined in a single String
Map<Integer, String> result =
persons.stream()
.collect(
Collectors.groupingBy(
Person::getAge,
Collectors.mapping( // 1st downstream collector
Person::getLastName
Collectors.joining(", ") // 2nd downstream collector
)
)
) ;
265. @JosePaumard
#J8Stream
Collectors: groupingBy
HashMap: the same, sorted by age
TreeMap<Integer, TreeSet<String>> result =
persons.stream()
.collect(
Collectors.groupingBy(
Person::getAge,
TreeMap::new,
Collectors.mapping(
Person::getLastName
Collectors.toCollection(TreeSet::new)
)
)
) ;
266. @JosePaumard
#J8Stream
Wrap-up
Stream + Collectors =
New tools for data processing (map / filter / reduce)
1)lazy execution
2)parallelism
Live coding to come!
271. « movies and actors »
https://github.com/JosePaumard/jdk8-lambda-tour
http://introcs.cs.princeton.edu/java/data/
272. @JosePaumard
#J8Stream
Movies and actors
File: « movies-mpaa.txt »
With 14k movies from 1916 to 2004
With:
-the title of the movie
-the release year
-the list of the actors (170k)
274. @JosePaumard
#J8Stream
Greatest release year
1st question: which year saw the most movies?
1st step: we can build a hashmap
-the keys are the release year
-the values the # of movies in that year
275. @JosePaumard
#J8Stream
Greatest release year
1st question: which year saw the most movies?
1st step: we can build a hashmap
-the keys are the release year
-the values the # of movies in that year
2nd step: get the key value pair with the greatest value
279. @JosePaumard
#J8Stream
Most seen actor
2nd question: most seen actor?
Once again, we can build a hashmap:
-the keys are the actors
-the values are the # of movies
280. @JosePaumard
#J8Stream
Most seen actor
2nd question: most seen actor?
Let us build the set of all the actors
Set<Actor> actors =
movies.stream()
.flatMap(movie -> movie.actors().stream())
.collect(Collector.toSet()) ;
281. @JosePaumard
#J8Stream
Most seen actor
2nd question: most seen actor?
actors.stream() .collect( ) .entrySet().stream() .max(Map.Entry.comparingByValue()).get() ;
282. @JosePaumard
#J8Stream
Most seen actor
2nd question: most seen actor?
actors.stream()
.collect(
Collectors.toMap(
)
)
.entrySet().stream()
.max(Map.Entry.comparingByValue()).get() ;
283. @JosePaumard
#J8Stream
Most seen actor
2nd question: most seen actor?
actors.stream() .collect( Collectors.toMap( actor -> actor, ) ) .entrySet().stream() .max(Map.Entry.comparingByValue()).get() ;
284. @JosePaumard
#J8Stream
Most seen actor
2nd question: most seen actor?
actors.stream()
.collect(
Collectors.toMap(
Function.identity(),
)
)
.entrySet().stream()
.max(Map.Entry.comparingByValue()).get() ;
285. @JosePaumard
#J8Stream
Most seen actor
2nd question: most seen actor?
actors.stream() .collect( Collectors.toMap( Function.identity(), actor -> movies.stream() .filter(movie -> movie.actors().contains(actor)) .count() ) ) .entrySet().stream() .max(Map.Entry.comparingByValue()).get() ;
286. @JosePaumard
#J8Stream
Most seen actor
2nd question: most seen actor?
actors.stream().parallel() // T = 40s
.collect(
Collectors.toMap(
Function.identity(),
actor -> movies.stream()
.filter(movie -> movie.actors().contains(actor))
.count()
)
)
.entrySet().stream()
.max(Map.Entry.comparingByValue()).get() ;
287. @JosePaumard
#J8Stream
Most seen actor
2nd question: most seen actor?
actors.stream().parallel() // 170k .collect( Collectors.toMap( Function.identity(), actor -> movies.stream() // 14k 2,4G!! .filter(movie -> movie.actors().contains(actor)) .count() ) ) .entrySet().stream() .max(Map.Entry.comparingByValue()).get() ;
288. @JosePaumard
#J8Stream
Most seen actor
2nd question: most seen actor?
Set<Actor> actors =
movies.stream()
.flatMap(movie -> movie.actors().stream()) // stream of actors
.collect(Collector.toSet()) ;
289. @JosePaumard
#J8Stream
Most seen actor
2nd question: most seen actor?
And in this stream, if an actor played in 2 movies, she appears twice
Set<Actor> actors = movies.stream() .flatMap(movie -> movie.actors().stream()) // stream of actors .collect(Collector.toSet()) ;
296. @JosePaumard
#J8Stream
Most seen actor in a year
3rd question: most seen actor in a given year?
So it is a hashmap in which:
-the keys are the actors
-the values are other hashmaps
297. @JosePaumard
#J8Stream
Most seen actor in a year
3rd question: most seen actor in a given year?
So it is a hashmap in which:
-the keys are the actors
-the values are other hashmaps
-in which keys are the release years
-and the values the # of movies → AtomicLong
298. @JosePaumard
#J8Stream
Most seen actor in a year
3rd question: most seen actor in a given year?
movies.stream()
.flatMap(movie -> movie.actors().stream())
.collect(
Collectors.groupingBy( // build a Map<year, ...>
movie -> movie.releaserYear(),
// build a Map<Actor, # of movies>
)
)
.entrySet().stream()
.max(Map.Entry.comparingByValue()).get() ;
299. @JosePaumard
#J8Stream
Most seen actor in a year
3rd question: most seen actor in a given year?
movies.stream() .flatMap(movie -> movie.actors().stream()) .collect( Collectors.groupingBy( // build a Map<year, ...> movie -> movie.releaserYear(), // build a Map<Actor, # of movies> -> custom DS Collector ) ) .entrySet().stream() .max(Map.Entry.comparingByValue()).get() ;
300. @JosePaumard
#J8Stream
Most seen actor in a year
3rd question: most seen actor in a given year?
So it is a hashmap in which:
-the keys are the actors
-the values are other hashmaps
-in which keys are the release years
-and the values the # of movies → AtomicLong
And we want the max by the # of movies
301. @JosePaumard
#J8Stream
Most seen actor in a year
3rd question: most seen actor in a given year?
We need 3 things to build a collector
-a constructor for the resulting container
-an accumulator to add an element to the container
-a combiner that merges two partially filled containers
308. @JosePaumard
#J8Stream
Scrabble
Two files:
-OSPD = official personnal Scrabble dictionary
-The words used by Shakespeare
-And some documentation (Wikipedia)
private static final int [] scrabbleENScore = {
// a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10} ;
309. @JosePaumard
#J8Stream
Scrabble: score of a word
1st question: how to compute the score of a word
H E L L O 4 1 1 1 1 // from the scrabbleENScore array
310. @JosePaumard
#J8Stream
Scrabble: score of a word
1st question: how to compute the score of a word
H E L L O
4 1 1 1 1 // from the scrabbleENScore array
SUM
= 8
311. @JosePaumard
#J8Stream
Scrabble: score of a word
1st question: how to compute the score of a word
H E L L O // this is a stream of the letters of the word HELLO 4 1 1 1 1 SUM = 8
312. @JosePaumard
#J8Stream
Scrabble: score of a word
1st question: how to compute the score of a word
H E L L O // this is a stream of the letters of the word HELLO
4 1 1 1 1 // mapping : letter -> score of the letter
SUM
= 8
313. @JosePaumard
#J8Stream
Scrabble: score of a word
1st question: how to compute the score of a word
H E L L O // this is a stream of the letters of the word HELLO 4 1 1 1 1 // mapping : letter -> score of the letter SUM // reduction : sum = 8
317. @JosePaumard
#J8Stream
Scrabble: score of Shakespeare
2nd question: compute the best word of Shakespeare
1)Histogram: score of the words / list of the words
318. @JosePaumard
#J8Stream
Scrabble: score of Shakespeare
2nd question: compute the best word of Shakespeare
1)Histogram: score of the words / list of the words
2)Max by key value
319. @JosePaumard
#J8Stream
Scrabble: score of Shakespeare
2nd question: compute the best word of Shakespeare
1)Histogram: score of the words / list of the words
HashMap, Collectors.groupingBy()
2)Max by key value
320. @JosePaumard
#J8Stream
Scrabble: score of Shakespeare
2nd question: compute the best word of Shakespeare
1)Histogram: score of the words / list of the words
HashMap, Collectors.groupingBy()
2)Max by key value
Shouldnt be too hard
326. @JosePaumard
#J8Stream
Scrabble: score of Shakespeare
Question: can one really write this word?
private static final int [] scrabbleENDistribution = {
// a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
9, 2, 2, 1, 12, 2, 3, 2, 9, 1, 1, 4, 2, 6, 8, 2, 1, 6, 4, 6, 4, 2, 2, 1, 2, 1} ;
327. @JosePaumard
#J8Stream
Scrabble: score of Shakespeare
Answer: no…
private static final int [] scrabbleENDistribution = {
// a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
9, 2, 2, 1, 12, 2, 3, 2, 9, 1, 1, 4, 2, 6, 8, 2, 1, 6, 4, 6, 4, 2, 2, 1, 2, 1} ;
328. @JosePaumard
#J8Stream
Filtering V2
4th question: how to check if I have the available letters?
private static final int [] scrabbleENDistribution = {
// a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
9, 2, 2, 1, 12, 2, 3, 2, 9, 1, 1, 4, 2, 6, 8, 2, 1, 6, 4, 6, 4, 2, 2, 1, 2, 1} ;
330. @JosePaumard
#J8Stream
Filtering V2
4th question: how to check if I have the available letters?
1
1
2
2
1
1
1
4
9
1
6
3
needed letters
available letters
331. @JosePaumard
#J8Stream
Filtering V2
4th question: how to check if I have the available letters?
I need a allMatch() reducer!
1
1
2
2
1
1
1
4
9
1
6
3
needed letters
available letters
336. @JosePaumard
#J8Stream
Scrabble: use of blanks
5th question: and what about using blanks?
private static final int [] scrabbleENDistribution = {
// a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
9, 2, 2, 1, 12, 2, 3, 2, 9, 1, 1, 4, 2, 6, 8, 2, 1, 6, 4, 6, 4, 2, 2, 1, 2, 1} ;
337. @JosePaumard
#J8Stream
Scrabble: use of blanks
5th question: and what about using blanks?
private static final int [] scrabbleENDistribution = {
// a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
9, 2, 2, 1, 12, 2, 3, 2, 9, 1, 1, 4, 2, 6, 8, 2, 1, 6, 4, 6, 4, 2, 2, 1, 2, 1} ;
338. @JosePaumard
#J8Stream
Scrabble: use of blanks
It has 2 impacts:
-on the filtering of the words
-on the computation of the score
355. @JosePaumard
#J8Stream
Scrabble: and what about the board?
7th question: what about the Double letter score?
6 solutions to put the word:
-right square = 3 last letters
-left square= 3 first letters
356. @JosePaumard
#J8Stream
Scrabble: and what about the board?
7th question: what about the Double letter score?
6 solutions to put the word:
-right square = 3 last letters
-left square= 3 first letters
If the word is long enough (7 letters)!
357. @JosePaumard
#J8Stream
Scrabble: and what about the board?
7th question: what about the Double letter score?
So we need to take a max, on which set?
word.chars().skip(4) // 1st stream
word.chars().limit(Integer.max(0, word.length() - 4)) // 2nd stream
358. @JosePaumard
#J8Stream
Scrabble: and what about the board?
7th question: what about the Double letter score?
IntStream.concat(
word.chars().skip(4),
word.chars().limit(Integer.max(0, word.length() - 4))
)
.map(scrabbleENScore)
.max()
359. @JosePaumard
#J8Stream
Scrabble: and what about the board?
7th question: what about the Double letter score?
Problem: concat does not parallel well
IntStream.concat(
word.chars().skip(4),
word.chars().limit(Integer.max(0, word.length() - 4))
)
.map(scrabbleENScore)
.max()
360. @JosePaumard
#J8Stream
Scrabble: and what about the board?
7th question: what about the Double letter score?
Stream.of(
word.chars().skip(4),
word.chars().limit(Integer.max(0, word.length() - 4))
) // returns a Stream of Stream!
361. @JosePaumard
#J8Stream
Scrabble: and what about the board?
7th question: what about the Double letter score?
Stream.of(
word.chars().skip(4),
word.chars().limit(Integer.max(0, word.length() - 4))
)
.flatMapToInt(Function.identity()) // chars() is an IntStream
.map(scrabbleENScore)
.max() // we have an IntStream!
362. @JosePaumard
#J8Stream
Scrabble: and what about the board?
7th question: what about the Double letter score?
What should we do with this Optional?
Stream.of(
word.chars().skip(4),
word.chars().limit(Integer.max(0, word.length() - 4))
)
.flatMapToInt(Function.identity()) // chars() is an IntStream
.map(scrabbleENScore)
.max() // we have an IntStream!
363. @JosePaumard
#J8Stream
Scrabble: and what about the board?
7th question: what about the Double letter score?
… that can be empty!
Stream.of(
word.chars().skip(4),
word.chars().limit(Integer.max(0, word.length() - 4))
)
.flatMapToInt(Function.identity()) // chars() is an IntStream
.map(scrabbleENScore)
.max() // we have an IntStream!
364. @JosePaumard
#J8Stream
Scrabble: and what about the board?
7th question: what about the Double letter score?
… that can be empty!
Stream.of(
word.chars().skip(4),
word.chars().limit(Integer.max(0, word.length() - 4))
)
.flatMapToInt(Function.identity()) // chars() is an IntStream
.map(scrabbleENScore)
.max() // we have an IntStream!
.orElse(0) ;
369. @JosePaumard
#J8Stream
Conclusion
Streams + Collectors = no need to use the Iterator pattern any more
Combined with lambdas = new way of writing data processing and applications in Java
370. @JosePaumard
#J8Stream
Conclusion
Streams + Collectors = no need to use the Iterator pattern any more
Combined with lambdas = new way of writing data processing in Java
-writing code
-architecture