SlideShare a Scribd company logo
JAVA 8 STREAMS
Zameer Ahmed Shaik.
Senior Full Stack Java Engineer.
• Introduction
• Processing Collections - Java7 Vs Java8
• Introducing Java8 Stream APIs.
• Basic operations using Streams
• Advanced operations.
• Parallel stream.
• Read Stream of Lines from a File.
In This Tutorial ..
• Java Stream is an abstraction that lets you process data in a
declarative way.
• Perform SQL like operations on Collections.
• process really large collections efficiently By leverage Multi core
architectures.
What is Stream ?
Processing Collections - Java7 Vs Java8
• Find the list of employee ids sorted based on their Salary in a given
city.
List<Employee> employeeList =
StreamDemoHelper.getEmployeeList();
EMP ID City Salary
1 MEL 250
3 MEL 150
2 SYD 230
6 BRS 400
5 SYD 350
7 SYD 100
4 MEL 200
Each row in the above table represents Employee
Object.
List<Employee> employeeList = StreamDemoHelper.getEmployeeList(
List<Employee> melboureEmployees = new ArrayList<>();
for(Employee emp : employeeList){
if(emp.getCity().equals("MEL")){
melboureEmployees.add(emp);
}
}
Collections.sort(melboureEmployees, new Comparator<Employee>(){
@Override
public int compare(Employee o1, Employee o2) {
return o2.getSalary().compareTo(o1.getSalary());
}
});
List<Long> melEmpIdList = new ArrayList<>();
for(Employee emp : melboureEmployees){
melEmpIdList.add(emp.getEmployeeId());
}
Processing Collections - Java7
1. Iterate the list of Employees
and check each employees
city and add it to a separate
list.
2. Sort the list of Employees in
Melbourne based on salary.
3. Iterate Melbourne
employees and then add it
to separate list of ids.
Output: [1, 4, 3]
List<Long> empIds =
employeeList.stream()
.filter(emp -> emp.getCity().equals("MEL"))
.sorted(comparing(Employee::getSalary)
.reversed())
.map(emp -> emp.getEmployeeId())
.collect(toList());
Processing Collections – Java8
Only Declare what need to
be performed using Steam
APIs.
This code will produce the
same result as that of
previous code.
Don’t worry if you don’t
understand, we will see all the
Stream APIs in the next slides.
stream() filter() sorted() collect()
toList() toMap() toSet() sum()
count() avaragingInt() map()
averagingLong()
averagingDouble() groupingBy()
reduce() minBy() maxBy() limit()
skip() allMatch() findAll() findAny()
partitioningBy() flatMap() joining()
mapping() collecting()
Java8 Stream APIs
1. Filter Employees based on city.
2. Total number of people whose salary greater than $230
3. Find List of Employee ids whose salary is less than $250 of a given
city.
4. Distinct Cities in which employees has salaries less than $250
5. Find total amount of money spent on Salaries Every Month.
6. Other operations..
Basic operations using Streams
Filter Employees based on city.
EMP ID City Salary
1 MEL 250
3 MEL 150
2 SYD 230
6 BRS 400
5 SYD 350
7 SYD 100
4 MEL 200
EMP ID City Salary
1 MEL 250
3 MEL 150
4 MEL 200
List<Employee> melEmpList = employeeList.stream()
.filter(emp -> emp.getCity().equals("MEL"))
.collect(Collectors.toList());
filter() method takes lamda expression of
Predicate type and filters the stream based on
the condition defined.
collect() method collects the filtered Steam objects
and converts it to List of Employee objects using
Collectors.toList() method defined inside it.
Collectors class has toSet(), toMap(), toConcurrentMap(), toCollection() methods to convert
the stream of objects to a particular type of collection.
Total number of people whose salary greater than $230
EMP ID City Salary
1 MEL 250
3 MEL 150
2 SYD 230
6 BRS 400
5 SYD 350
7 SYD 100
4 MEL 200
Long count = employeeList.stream()
.filter(emp -> emp.getSalary() > 230)
.count();
Filter employees whose salary is greater than
$250
count() will return the total of the filtered items.
count = 3
Find List of Employee ids whose salary is less than $250 of a
given city.
List<Long> melEmpIds = employeeList.stream()
.filter(emp -> emp.getCity().equals("MEL")
&& emp.getSalary() < 250)
.map(emp -> emp.getEmployeeId())
.collect(toList());
filter method actually return stream of employee
objects which is Stream<Employee>.
map() functions comes to our rescue to create a
stream of whatever we want based on the
employee object. map() function returns stream
of whatever that is returned in the lamda
expression that is passed to it. In our case map()
function returns Stream of employee ids.
EMP ID City Salary
1 MEL 250
3 MEL 150
2 SYD 230
6 BRS 400
5 SYD 350
7 SYD 100
4 MEL 200
EMP ID City Salary
1 MEL 250
3 MEL 150
4 MEL 200
[3, 4]
filter()
map()
some more examples of map() function…
List<Bonus> bonusList = employeeList.stream()
.map(emp -> new Bonus(emp.getEmployeeId(),
emp.getSalary() * 1.5))
.collect(toList());
The Lamda expression of map() function
returns Bonus object based on Employee
object and hence we get Stream of Bonus
objects which is Stream<Bonus>
whoAmI = employeeList.stream()
.map(emp -> {
Integer tax =calculateTaxes(emp);
//Date date = get payroll date.
return new Payroll(emp.getEmpId,
emp.geSalary,
date,
tax);
})
.collect(toList());
Guess what is the type of whoAmI ?
It is List<Payroll>
Find total amount of money spent on Salaries Every Month.
EMP ID City Salary
1 MEL 250
3 MEL 150
2 SYD 230
6 BRS 400
5 SYD 350
7 SYD 100
4 MEL 200
Long sumOfSalaries = employeeList.stream()
.mapToLong(emp -> emp.getSalary())
.sum();
sum() will return the total of all the salaries.
}Total = 1680
mapToLong() is similar to map() function except
map() returns Stream<Object> whereas
maptoLong returns LongStream object and helps
us perform sum() of all the Longs. Similarly, we have mapToInt() &
mapToDouble() to be used with
Integer and Double.
Distinct Cities in which employees has salaries less than $250
EMP ID City Salary
1 MEL 250
3 MEL 150
2 SYD 230
6 BRS 400
5 SYD 350
7 SYD 100
4 MEL 200
List<String> distinctCities =
employeeList.stream()
.filter(emp -> emp.getSalary() < 250)
.map(emp -> emp.getCity())
.distinct()
.collect(toList());
First filtering employees whose salary is less
than $300
distinct() method basically removes all the
duplicates.
MEL
MEL
SYD
SYD
filter()
[MEL,
SYD]
distinct()
Other Operations..
Check whether all the employees have salary
greater than $75. In this case it will return true.
Boolean allMatch = employeeList.stream()
.allMatch(emp -> emp.getSalary() > 75);
Double averageLong = employeeList.stream()
.collect(averagingLong(Employee::getSalary));
Highest & Lowest salaried employees.
Average salary in the company
Optional<Employee> minSalariedEmployee =
employeeList.stream()
.collect(minBy(comparing(Employee::getSalary)));
For maximum salaried employee use maxBy() function of Collectors class.
Please check Collectors method for other functions like reducing(), joining(), mapping() etc.
1. Group employees based on whether salary greater than $250
2. Group employees based on City and order by Salary
3. Group employees based on city and then group each city by the
role of the employee and order by salary.
Advance operations using Streams
1. Group employees based on whether salary greater than
$250
Map<Boolean , List<Employee> > partitionByMap =
employeeList.stream()
.collect(Collectors.partitioningBy(emp ->
emp.getSalary() > 250));
partitioningBy() method groups the collection
based on the codition passed to it. In this case
employees are grouped based on whether their
salary is greater than $250.
EMP ID City Salary
1 MEL 250
3 MEL 150
2 SYD 230
6 BRS 400
5 SYD 350
7 SYD 100
4 MEL 200
true [emp6, emp5]
false [emp1, emp3, emp2, emp7, emp4]
Map<Boolean, List<Employee>>
List<Employee>
Group employees based on City whose salary > 150 and order
by Salary
Map<String, List<Employee>> groupByCity =
employeeList.stream()
.filter(emp -> emp.getSalary() > 150)
.sorted(comparing(Employee::getSalary).reversed())
.collect(Collectors.groupingBy(emp -> emp.getCity()));
Collectors.groupingBy() is used to group the
collection based on the return type of the lamda
defined in it. In this case we are grouping based
on the City.
Just Note that in this case , grouping happens on
the filtered and sorted collection which we passed
to the collect method.
EMP ID City Salary
1 MEL 250
3 MEL 150
2 SYD 230
6 BRS 400
5 SYD 350
7 SYD 100
4 MEL 200
BRS [emp6]
MEL [emp1, emp4]
SYD [emp5, emp2]
Map<String, List<Employee>>
List<Employee>
Id=1
$250, MEL
Id=3
$150,MEL
Id=2
$230,SYD
Id=6
$400,BRS
Id=5
$350,SYD
Id=7
$100,SYD
Id=4
$200,MEL
Id=1
$250, MEL
Id=2
$230,SYD
Id=6
$400,BRS
Id=5
$350,SYD
Id=4
$200,MEL
Id=6 Id=2
$230, SYD
Id=4
$200,MEL
Java 8 Streams – Filter, Sort on Salary & Group by City
.filter(e ->
e.getsalary >
150)
empList.stream()
.sorted(
comparing(
e -> e.getPrice))
$400,BRS
Id=5
$350,SYD
Id=1
$250, MEL
groupingBy(
emp -> emp.getCity)
Id=6
$400,BRS
Id=5
$350,SYD
Id=2
$230, SYD
Id=1
$250, MEL
Id=4
$200,MEL
BRS SYD MEL
..continued
Group employees based on city and then group each city by
the role of the employee and order by salary.
Map<String, Map<String, List<Employee>>>
groupByCityAndRole = employeeList.stream()
.sorted(comparing(Employee::getSalary).reversed())
.collect(groupingBy(emp -> emp.getCity(),
groupingBy(emp -> emp.getRole())));
Collectors.groupingBy() overloaded method
first takes initial criteria and second
parameter is Collectors object.
And hence we can use any method which
returns collectors object as second
parameter.. So, we passed another
groupingBy() method to further classify
employees based on the role in each city.
EMP ID City Salary Role
1 MEL 250 Developer
3 MEL 150 Developer
2 SYD 230 Developer
6 BRS 400 Director
5 SYD 350 Developer
7 SYD 100 Manager
4 MEL 200 Manager
List<Employee>
BRS MEL
DeveloperDirector Manager
[Emp6] [emp1, emp3] [Emp4]
SYD
Developer Manager
[emp5, emp2] [Emp7]
.. Continued
Parallel stream.
Note, that parallelism is not automatically faster than performing operations serially, although it can be if you have
enough data and processor cores.
List<Long> melEmpIds = employeeList.parallelStream()
.filter(emp -> emp.getCity().equals("MEL")
&& emp.getSalary() < 250)
.map(emp -> emp.getEmployeeId())
.collect(toList());
Aggregate operations and parallel streams enable
you to implement parallelism with non-thread-safe
collections provided that you do not modify the
collection while you are operating on it.
Read Stream of Lines from a File
Stream<String> streamOfLines = Files.lines(Paths.get(”/tmp/transaction.csv”));
The above code reads the file from path specified and creates stream of
Line. Each line is represented in the String format.
Happy Learning!
1. http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.html
2. http://www.oracle.com/technetwork/articles/java/architect-streams-pt2-2227132.html
3. https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html
4. https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collector.html
5. https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html
References

More Related Content

What's hot

Ruby on Rails ステップアップ講座 - 大場寧子
Ruby on Rails ステップアップ講座 - 大場寧子Ruby on Rails ステップアップ講座 - 大場寧子
Ruby on Rails ステップアップ講座 - 大場寧子
Yasuko Ohba
 
Closure, Higher-order function in Swift
Closure, Higher-order function in SwiftClosure, Higher-order function in Swift
Closure, Higher-order function in Swift
SeongGyu Jo
 
Grails: a quick tutorial (1)
Grails: a quick tutorial (1)Grails: a quick tutorial (1)
Grails: a quick tutorial (1)
Davide Rossi
 
Everything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to askEverything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to ask
Andrea Giuliano
 
Leveraging Symfony2 Forms
Leveraging Symfony2 FormsLeveraging Symfony2 Forms
Leveraging Symfony2 Forms
Bernhard Schussek
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
James Titcumb
 
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
Wanbok Choi
 
레진코믹스가 코틀린으로 간 까닭은?
레진코믹스가 코틀린으로 간 까닭은?레진코믹스가 코틀린으로 간 까닭은?
레진코믹스가 코틀린으로 간 까닭은?
Taeho Kim
 
Writing Your App Swiftly
Writing Your App SwiftlyWriting Your App Swiftly
Writing Your App Swiftly
Sommer Panage
 
Kotlin: Let's Make Android Great Again
Kotlin: Let's Make Android Great AgainKotlin: Let's Make Android Great Again
Kotlin: Let's Make Android Great Again
Taeho Kim
 
Error Management: Future vs ZIO
Error Management: Future vs ZIOError Management: Future vs ZIO
Error Management: Future vs ZIO
John De Goes
 
Rust ⇋ JavaScript
Rust ⇋ JavaScriptRust ⇋ JavaScript
Rust ⇋ JavaScript
Ingvar Stepanyan
 
Rails on Oracle 2011
Rails on Oracle 2011Rails on Oracle 2011
Rails on Oracle 2011
Raimonds Simanovskis
 
Ruby on rails tips
Ruby  on rails tipsRuby  on rails tips
Ruby on rails tips
BinBin He
 
GORM
GORMGORM
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Raimonds Simanovskis
 
Learn JavaScript by modeling Rubik Cube
Learn JavaScript by modeling Rubik CubeLearn JavaScript by modeling Rubik Cube
Learn JavaScript by modeling Rubik Cube
Manoj Kumar
 
Emerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the HorizonEmerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the Horizon
Alex Payne
 
Apache spark
Apache sparkApache spark
Apache spark
Arnon Rotem-Gal-Oz
 
Gorm
GormGorm

What's hot (20)

Ruby on Rails ステップアップ講座 - 大場寧子
Ruby on Rails ステップアップ講座 - 大場寧子Ruby on Rails ステップアップ講座 - 大場寧子
Ruby on Rails ステップアップ講座 - 大場寧子
 
Closure, Higher-order function in Swift
Closure, Higher-order function in SwiftClosure, Higher-order function in Swift
Closure, Higher-order function in Swift
 
Grails: a quick tutorial (1)
Grails: a quick tutorial (1)Grails: a quick tutorial (1)
Grails: a quick tutorial (1)
 
Everything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to askEverything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to ask
 
Leveraging Symfony2 Forms
Leveraging Symfony2 FormsLeveraging Symfony2 Forms
Leveraging Symfony2 Forms
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
 
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
 
레진코믹스가 코틀린으로 간 까닭은?
레진코믹스가 코틀린으로 간 까닭은?레진코믹스가 코틀린으로 간 까닭은?
레진코믹스가 코틀린으로 간 까닭은?
 
Writing Your App Swiftly
Writing Your App SwiftlyWriting Your App Swiftly
Writing Your App Swiftly
 
Kotlin: Let's Make Android Great Again
Kotlin: Let's Make Android Great AgainKotlin: Let's Make Android Great Again
Kotlin: Let's Make Android Great Again
 
Error Management: Future vs ZIO
Error Management: Future vs ZIOError Management: Future vs ZIO
Error Management: Future vs ZIO
 
Rust ⇋ JavaScript
Rust ⇋ JavaScriptRust ⇋ JavaScript
Rust ⇋ JavaScript
 
Rails on Oracle 2011
Rails on Oracle 2011Rails on Oracle 2011
Rails on Oracle 2011
 
Ruby on rails tips
Ruby  on rails tipsRuby  on rails tips
Ruby on rails tips
 
GORM
GORMGORM
GORM
 
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
 
Learn JavaScript by modeling Rubik Cube
Learn JavaScript by modeling Rubik CubeLearn JavaScript by modeling Rubik Cube
Learn JavaScript by modeling Rubik Cube
 
Emerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the HorizonEmerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the Horizon
 
Apache spark
Apache sparkApache spark
Apache spark
 
Gorm
GormGorm
Gorm
 

Similar to Processing Collections with Java8 Stream APIs

Comparing 30 MongoDB operations with Oracle SQL statements
Comparing 30 MongoDB operations with Oracle SQL statementsComparing 30 MongoDB operations with Oracle SQL statements
Comparing 30 MongoDB operations with Oracle SQL statements
Lucas Jellema
 
Les03
Les03Les03
Sq lite functions
Sq lite functionsSq lite functions
Sq lite functions
punu_82
 
12. Basic SQL Queries (2).pptx
12. Basic SQL Queries  (2).pptx12. Basic SQL Queries  (2).pptx
12. Basic SQL Queries (2).pptx
SabrinaShanta2
 
Sql abstract from_query
Sql abstract from_querySql abstract from_query
Sql abstract from_query
Laurent Dami
 
Aggregate Functions,Final
Aggregate Functions,FinalAggregate Functions,Final
Aggregate Functions,Final
mukesh24pandey
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
Dmitry Buzdin
 
Class 8 - Database Programming
Class 8 - Database ProgrammingClass 8 - Database Programming
Class 8 - Database Programming
Ahmed Swilam
 
Clauses
ClausesClauses
PHP record- with all programs and output
PHP record- with all programs and outputPHP record- with all programs and output
PHP record- with all programs and output
KavithaK23
 
Database Query Using SQL_ip.docx
Database Query Using SQL_ip.docxDatabase Query Using SQL_ip.docx
Database Query Using SQL_ip.docx
VandanaGoyal21
 
ScalikeJDBC Tutorial for Beginners
ScalikeJDBC Tutorial for BeginnersScalikeJDBC Tutorial for Beginners
ScalikeJDBC Tutorial for Beginners
Kazuhiro Sera
 
DBIx-DataModel v2.0 in detail
DBIx-DataModel v2.0 in detail DBIx-DataModel v2.0 in detail
DBIx-DataModel v2.0 in detail
Laurent Dami
 
Database management system file
Database management system fileDatabase management system file
Database management system file
Ankit Dixit
 
Oracle (SQL), Sulieman Khudruj
Oracle (SQL), Sulieman KhudrujOracle (SQL), Sulieman Khudruj
Oracle (SQL), Sulieman Khudruj
Sulieman Khudruj
 
ORACLE NOTES
ORACLE NOTESORACLE NOTES
ORACLE NOTES
Sachin Shukla
 
Ruby on Rails: Tasty Burgers
Ruby on Rails: Tasty BurgersRuby on Rails: Tasty Burgers
Ruby on Rails: Tasty Burgers
Aaron Patterson
 
Patterns for slick database applications
Patterns for slick database applicationsPatterns for slick database applications
Patterns for slick database applications
Skills Matter
 
MS SQLSERVER:Doing Calculations With Functions
MS SQLSERVER:Doing Calculations With FunctionsMS SQLSERVER:Doing Calculations With Functions
MS SQLSERVER:Doing Calculations With Functions
sqlserver content
 
MS SQL SERVER: Doing Calculations With Functions
MS SQL SERVER: Doing Calculations With FunctionsMS SQL SERVER: Doing Calculations With Functions
MS SQL SERVER: Doing Calculations With Functions
sqlserver content
 

Similar to Processing Collections with Java8 Stream APIs (20)

Comparing 30 MongoDB operations with Oracle SQL statements
Comparing 30 MongoDB operations with Oracle SQL statementsComparing 30 MongoDB operations with Oracle SQL statements
Comparing 30 MongoDB operations with Oracle SQL statements
 
Les03
Les03Les03
Les03
 
Sq lite functions
Sq lite functionsSq lite functions
Sq lite functions
 
12. Basic SQL Queries (2).pptx
12. Basic SQL Queries  (2).pptx12. Basic SQL Queries  (2).pptx
12. Basic SQL Queries (2).pptx
 
Sql abstract from_query
Sql abstract from_querySql abstract from_query
Sql abstract from_query
 
Aggregate Functions,Final
Aggregate Functions,FinalAggregate Functions,Final
Aggregate Functions,Final
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
Class 8 - Database Programming
Class 8 - Database ProgrammingClass 8 - Database Programming
Class 8 - Database Programming
 
Clauses
ClausesClauses
Clauses
 
PHP record- with all programs and output
PHP record- with all programs and outputPHP record- with all programs and output
PHP record- with all programs and output
 
Database Query Using SQL_ip.docx
Database Query Using SQL_ip.docxDatabase Query Using SQL_ip.docx
Database Query Using SQL_ip.docx
 
ScalikeJDBC Tutorial for Beginners
ScalikeJDBC Tutorial for BeginnersScalikeJDBC Tutorial for Beginners
ScalikeJDBC Tutorial for Beginners
 
DBIx-DataModel v2.0 in detail
DBIx-DataModel v2.0 in detail DBIx-DataModel v2.0 in detail
DBIx-DataModel v2.0 in detail
 
Database management system file
Database management system fileDatabase management system file
Database management system file
 
Oracle (SQL), Sulieman Khudruj
Oracle (SQL), Sulieman KhudrujOracle (SQL), Sulieman Khudruj
Oracle (SQL), Sulieman Khudruj
 
ORACLE NOTES
ORACLE NOTESORACLE NOTES
ORACLE NOTES
 
Ruby on Rails: Tasty Burgers
Ruby on Rails: Tasty BurgersRuby on Rails: Tasty Burgers
Ruby on Rails: Tasty Burgers
 
Patterns for slick database applications
Patterns for slick database applicationsPatterns for slick database applications
Patterns for slick database applications
 
MS SQLSERVER:Doing Calculations With Functions
MS SQLSERVER:Doing Calculations With FunctionsMS SQLSERVER:Doing Calculations With Functions
MS SQLSERVER:Doing Calculations With Functions
 
MS SQL SERVER: Doing Calculations With Functions
MS SQL SERVER: Doing Calculations With FunctionsMS SQL SERVER: Doing Calculations With Functions
MS SQL SERVER: Doing Calculations With Functions
 

Recently uploaded

How Barcodes Can Be Leveraged Within Odoo 17
How Barcodes Can Be Leveraged Within Odoo 17How Barcodes Can Be Leveraged Within Odoo 17
How Barcodes Can Be Leveraged Within Odoo 17
Celine George
 
C1 Rubenstein AP HuG xxxxxxxxxxxxxx.pptx
C1 Rubenstein AP HuG xxxxxxxxxxxxxx.pptxC1 Rubenstein AP HuG xxxxxxxxxxxxxx.pptx
C1 Rubenstein AP HuG xxxxxxxxxxxxxx.pptx
mulvey2
 
Level 3 NCEA - NZ: A Nation In the Making 1872 - 1900 SML.ppt
Level 3 NCEA - NZ: A  Nation In the Making 1872 - 1900 SML.pptLevel 3 NCEA - NZ: A  Nation In the Making 1872 - 1900 SML.ppt
Level 3 NCEA - NZ: A Nation In the Making 1872 - 1900 SML.ppt
Henry Hollis
 
Andreas Schleicher presents PISA 2022 Volume III - Creative Thinking - 18 Jun...
Andreas Schleicher presents PISA 2022 Volume III - Creative Thinking - 18 Jun...Andreas Schleicher presents PISA 2022 Volume III - Creative Thinking - 18 Jun...
Andreas Schleicher presents PISA 2022 Volume III - Creative Thinking - 18 Jun...
EduSkills OECD
 
Pharmaceutics Pharmaceuticals best of brub
Pharmaceutics Pharmaceuticals best of brubPharmaceutics Pharmaceuticals best of brub
Pharmaceutics Pharmaceuticals best of brub
danielkiash986
 
HYPERTENSION - SLIDE SHARE PRESENTATION.
HYPERTENSION - SLIDE SHARE PRESENTATION.HYPERTENSION - SLIDE SHARE PRESENTATION.
HYPERTENSION - SLIDE SHARE PRESENTATION.
deepaannamalai16
 
The basics of sentences session 7pptx.pptx
The basics of sentences session 7pptx.pptxThe basics of sentences session 7pptx.pptx
The basics of sentences session 7pptx.pptx
heathfieldcps1
 
RESULTS OF THE EVALUATION QUESTIONNAIRE.pptx
RESULTS OF THE EVALUATION QUESTIONNAIRE.pptxRESULTS OF THE EVALUATION QUESTIONNAIRE.pptx
RESULTS OF THE EVALUATION QUESTIONNAIRE.pptx
zuzanka
 
math operations ued in python and all used
math operations ued in python and all usedmath operations ued in python and all used
math operations ued in python and all used
ssuser13ffe4
 
Mule event processing models | MuleSoft Mysore Meetup #47
Mule event processing models | MuleSoft Mysore Meetup #47Mule event processing models | MuleSoft Mysore Meetup #47
Mule event processing models | MuleSoft Mysore Meetup #47
MysoreMuleSoftMeetup
 
Gender and Mental Health - Counselling and Family Therapy Applications and In...
Gender and Mental Health - Counselling and Family Therapy Applications and In...Gender and Mental Health - Counselling and Family Therapy Applications and In...
Gender and Mental Health - Counselling and Family Therapy Applications and In...
PsychoTech Services
 
BÀI TẬP DẠY THÊM TIẾNG ANH LỚP 7 CẢ NĂM FRIENDS PLUS SÁCH CHÂN TRỜI SÁNG TẠO ...
BÀI TẬP DẠY THÊM TIẾNG ANH LỚP 7 CẢ NĂM FRIENDS PLUS SÁCH CHÂN TRỜI SÁNG TẠO ...BÀI TẬP DẠY THÊM TIẾNG ANH LỚP 7 CẢ NĂM FRIENDS PLUS SÁCH CHÂN TRỜI SÁNG TẠO ...
BÀI TẬP DẠY THÊM TIẾNG ANH LỚP 7 CẢ NĂM FRIENDS PLUS SÁCH CHÂN TRỜI SÁNG TẠO ...
Nguyen Thanh Tu Collection
 
Stack Memory Organization of 8086 Microprocessor
Stack Memory Organization of 8086 MicroprocessorStack Memory Organization of 8086 Microprocessor
Stack Memory Organization of 8086 Microprocessor
JomonJoseph58
 
BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...
BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...
BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...
Nguyen Thanh Tu Collection
 
Bonku-Babus-Friend by Sathyajith Ray (9)
Bonku-Babus-Friend by Sathyajith Ray  (9)Bonku-Babus-Friend by Sathyajith Ray  (9)
Bonku-Babus-Friend by Sathyajith Ray (9)
nitinpv4ai
 
Educational Technology in the Health Sciences
Educational Technology in the Health SciencesEducational Technology in the Health Sciences
Educational Technology in the Health Sciences
Iris Thiele Isip-Tan
 
Jemison, MacLaughlin, and Majumder "Broadening Pathways for Editors and Authors"
Jemison, MacLaughlin, and Majumder "Broadening Pathways for Editors and Authors"Jemison, MacLaughlin, and Majumder "Broadening Pathways for Editors and Authors"
Jemison, MacLaughlin, and Majumder "Broadening Pathways for Editors and Authors"
National Information Standards Organization (NISO)
 
Lifelines of National Economy chapter for Class 10 STUDY MATERIAL PDF
Lifelines of National Economy chapter for Class 10 STUDY MATERIAL PDFLifelines of National Economy chapter for Class 10 STUDY MATERIAL PDF
Lifelines of National Economy chapter for Class 10 STUDY MATERIAL PDF
Vivekanand Anglo Vedic Academy
 
ISO/IEC 27001, ISO/IEC 42001, and GDPR: Best Practices for Implementation and...
ISO/IEC 27001, ISO/IEC 42001, and GDPR: Best Practices for Implementation and...ISO/IEC 27001, ISO/IEC 42001, and GDPR: Best Practices for Implementation and...
ISO/IEC 27001, ISO/IEC 42001, and GDPR: Best Practices for Implementation and...
PECB
 
Leveraging Generative AI to Drive Nonprofit Innovation
Leveraging Generative AI to Drive Nonprofit InnovationLeveraging Generative AI to Drive Nonprofit Innovation
Leveraging Generative AI to Drive Nonprofit Innovation
TechSoup
 

Recently uploaded (20)

How Barcodes Can Be Leveraged Within Odoo 17
How Barcodes Can Be Leveraged Within Odoo 17How Barcodes Can Be Leveraged Within Odoo 17
How Barcodes Can Be Leveraged Within Odoo 17
 
C1 Rubenstein AP HuG xxxxxxxxxxxxxx.pptx
C1 Rubenstein AP HuG xxxxxxxxxxxxxx.pptxC1 Rubenstein AP HuG xxxxxxxxxxxxxx.pptx
C1 Rubenstein AP HuG xxxxxxxxxxxxxx.pptx
 
Level 3 NCEA - NZ: A Nation In the Making 1872 - 1900 SML.ppt
Level 3 NCEA - NZ: A  Nation In the Making 1872 - 1900 SML.pptLevel 3 NCEA - NZ: A  Nation In the Making 1872 - 1900 SML.ppt
Level 3 NCEA - NZ: A Nation In the Making 1872 - 1900 SML.ppt
 
Andreas Schleicher presents PISA 2022 Volume III - Creative Thinking - 18 Jun...
Andreas Schleicher presents PISA 2022 Volume III - Creative Thinking - 18 Jun...Andreas Schleicher presents PISA 2022 Volume III - Creative Thinking - 18 Jun...
Andreas Schleicher presents PISA 2022 Volume III - Creative Thinking - 18 Jun...
 
Pharmaceutics Pharmaceuticals best of brub
Pharmaceutics Pharmaceuticals best of brubPharmaceutics Pharmaceuticals best of brub
Pharmaceutics Pharmaceuticals best of brub
 
HYPERTENSION - SLIDE SHARE PRESENTATION.
HYPERTENSION - SLIDE SHARE PRESENTATION.HYPERTENSION - SLIDE SHARE PRESENTATION.
HYPERTENSION - SLIDE SHARE PRESENTATION.
 
The basics of sentences session 7pptx.pptx
The basics of sentences session 7pptx.pptxThe basics of sentences session 7pptx.pptx
The basics of sentences session 7pptx.pptx
 
RESULTS OF THE EVALUATION QUESTIONNAIRE.pptx
RESULTS OF THE EVALUATION QUESTIONNAIRE.pptxRESULTS OF THE EVALUATION QUESTIONNAIRE.pptx
RESULTS OF THE EVALUATION QUESTIONNAIRE.pptx
 
math operations ued in python and all used
math operations ued in python and all usedmath operations ued in python and all used
math operations ued in python and all used
 
Mule event processing models | MuleSoft Mysore Meetup #47
Mule event processing models | MuleSoft Mysore Meetup #47Mule event processing models | MuleSoft Mysore Meetup #47
Mule event processing models | MuleSoft Mysore Meetup #47
 
Gender and Mental Health - Counselling and Family Therapy Applications and In...
Gender and Mental Health - Counselling and Family Therapy Applications and In...Gender and Mental Health - Counselling and Family Therapy Applications and In...
Gender and Mental Health - Counselling and Family Therapy Applications and In...
 
BÀI TẬP DẠY THÊM TIẾNG ANH LỚP 7 CẢ NĂM FRIENDS PLUS SÁCH CHÂN TRỜI SÁNG TẠO ...
BÀI TẬP DẠY THÊM TIẾNG ANH LỚP 7 CẢ NĂM FRIENDS PLUS SÁCH CHÂN TRỜI SÁNG TẠO ...BÀI TẬP DẠY THÊM TIẾNG ANH LỚP 7 CẢ NĂM FRIENDS PLUS SÁCH CHÂN TRỜI SÁNG TẠO ...
BÀI TẬP DẠY THÊM TIẾNG ANH LỚP 7 CẢ NĂM FRIENDS PLUS SÁCH CHÂN TRỜI SÁNG TẠO ...
 
Stack Memory Organization of 8086 Microprocessor
Stack Memory Organization of 8086 MicroprocessorStack Memory Organization of 8086 Microprocessor
Stack Memory Organization of 8086 Microprocessor
 
BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...
BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...
BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...
 
Bonku-Babus-Friend by Sathyajith Ray (9)
Bonku-Babus-Friend by Sathyajith Ray  (9)Bonku-Babus-Friend by Sathyajith Ray  (9)
Bonku-Babus-Friend by Sathyajith Ray (9)
 
Educational Technology in the Health Sciences
Educational Technology in the Health SciencesEducational Technology in the Health Sciences
Educational Technology in the Health Sciences
 
Jemison, MacLaughlin, and Majumder "Broadening Pathways for Editors and Authors"
Jemison, MacLaughlin, and Majumder "Broadening Pathways for Editors and Authors"Jemison, MacLaughlin, and Majumder "Broadening Pathways for Editors and Authors"
Jemison, MacLaughlin, and Majumder "Broadening Pathways for Editors and Authors"
 
Lifelines of National Economy chapter for Class 10 STUDY MATERIAL PDF
Lifelines of National Economy chapter for Class 10 STUDY MATERIAL PDFLifelines of National Economy chapter for Class 10 STUDY MATERIAL PDF
Lifelines of National Economy chapter for Class 10 STUDY MATERIAL PDF
 
ISO/IEC 27001, ISO/IEC 42001, and GDPR: Best Practices for Implementation and...
ISO/IEC 27001, ISO/IEC 42001, and GDPR: Best Practices for Implementation and...ISO/IEC 27001, ISO/IEC 42001, and GDPR: Best Practices for Implementation and...
ISO/IEC 27001, ISO/IEC 42001, and GDPR: Best Practices for Implementation and...
 
Leveraging Generative AI to Drive Nonprofit Innovation
Leveraging Generative AI to Drive Nonprofit InnovationLeveraging Generative AI to Drive Nonprofit Innovation
Leveraging Generative AI to Drive Nonprofit Innovation
 

Processing Collections with Java8 Stream APIs

  • 1. JAVA 8 STREAMS Zameer Ahmed Shaik. Senior Full Stack Java Engineer.
  • 2. • Introduction • Processing Collections - Java7 Vs Java8 • Introducing Java8 Stream APIs. • Basic operations using Streams • Advanced operations. • Parallel stream. • Read Stream of Lines from a File. In This Tutorial ..
  • 3. • Java Stream is an abstraction that lets you process data in a declarative way. • Perform SQL like operations on Collections. • process really large collections efficiently By leverage Multi core architectures. What is Stream ?
  • 4. Processing Collections - Java7 Vs Java8 • Find the list of employee ids sorted based on their Salary in a given city. List<Employee> employeeList = StreamDemoHelper.getEmployeeList(); EMP ID City Salary 1 MEL 250 3 MEL 150 2 SYD 230 6 BRS 400 5 SYD 350 7 SYD 100 4 MEL 200 Each row in the above table represents Employee Object.
  • 5. List<Employee> employeeList = StreamDemoHelper.getEmployeeList( List<Employee> melboureEmployees = new ArrayList<>(); for(Employee emp : employeeList){ if(emp.getCity().equals("MEL")){ melboureEmployees.add(emp); } } Collections.sort(melboureEmployees, new Comparator<Employee>(){ @Override public int compare(Employee o1, Employee o2) { return o2.getSalary().compareTo(o1.getSalary()); } }); List<Long> melEmpIdList = new ArrayList<>(); for(Employee emp : melboureEmployees){ melEmpIdList.add(emp.getEmployeeId()); } Processing Collections - Java7 1. Iterate the list of Employees and check each employees city and add it to a separate list. 2. Sort the list of Employees in Melbourne based on salary. 3. Iterate Melbourne employees and then add it to separate list of ids. Output: [1, 4, 3]
  • 6. List<Long> empIds = employeeList.stream() .filter(emp -> emp.getCity().equals("MEL")) .sorted(comparing(Employee::getSalary) .reversed()) .map(emp -> emp.getEmployeeId()) .collect(toList()); Processing Collections – Java8 Only Declare what need to be performed using Steam APIs. This code will produce the same result as that of previous code. Don’t worry if you don’t understand, we will see all the Stream APIs in the next slides.
  • 7. stream() filter() sorted() collect() toList() toMap() toSet() sum() count() avaragingInt() map() averagingLong() averagingDouble() groupingBy() reduce() minBy() maxBy() limit() skip() allMatch() findAll() findAny() partitioningBy() flatMap() joining() mapping() collecting() Java8 Stream APIs
  • 8. 1. Filter Employees based on city. 2. Total number of people whose salary greater than $230 3. Find List of Employee ids whose salary is less than $250 of a given city. 4. Distinct Cities in which employees has salaries less than $250 5. Find total amount of money spent on Salaries Every Month. 6. Other operations.. Basic operations using Streams
  • 9. Filter Employees based on city. EMP ID City Salary 1 MEL 250 3 MEL 150 2 SYD 230 6 BRS 400 5 SYD 350 7 SYD 100 4 MEL 200 EMP ID City Salary 1 MEL 250 3 MEL 150 4 MEL 200 List<Employee> melEmpList = employeeList.stream() .filter(emp -> emp.getCity().equals("MEL")) .collect(Collectors.toList()); filter() method takes lamda expression of Predicate type and filters the stream based on the condition defined. collect() method collects the filtered Steam objects and converts it to List of Employee objects using Collectors.toList() method defined inside it. Collectors class has toSet(), toMap(), toConcurrentMap(), toCollection() methods to convert the stream of objects to a particular type of collection.
  • 10. Total number of people whose salary greater than $230 EMP ID City Salary 1 MEL 250 3 MEL 150 2 SYD 230 6 BRS 400 5 SYD 350 7 SYD 100 4 MEL 200 Long count = employeeList.stream() .filter(emp -> emp.getSalary() > 230) .count(); Filter employees whose salary is greater than $250 count() will return the total of the filtered items. count = 3
  • 11. Find List of Employee ids whose salary is less than $250 of a given city. List<Long> melEmpIds = employeeList.stream() .filter(emp -> emp.getCity().equals("MEL") && emp.getSalary() < 250) .map(emp -> emp.getEmployeeId()) .collect(toList()); filter method actually return stream of employee objects which is Stream<Employee>. map() functions comes to our rescue to create a stream of whatever we want based on the employee object. map() function returns stream of whatever that is returned in the lamda expression that is passed to it. In our case map() function returns Stream of employee ids. EMP ID City Salary 1 MEL 250 3 MEL 150 2 SYD 230 6 BRS 400 5 SYD 350 7 SYD 100 4 MEL 200 EMP ID City Salary 1 MEL 250 3 MEL 150 4 MEL 200 [3, 4] filter() map()
  • 12. some more examples of map() function… List<Bonus> bonusList = employeeList.stream() .map(emp -> new Bonus(emp.getEmployeeId(), emp.getSalary() * 1.5)) .collect(toList()); The Lamda expression of map() function returns Bonus object based on Employee object and hence we get Stream of Bonus objects which is Stream<Bonus> whoAmI = employeeList.stream() .map(emp -> { Integer tax =calculateTaxes(emp); //Date date = get payroll date. return new Payroll(emp.getEmpId, emp.geSalary, date, tax); }) .collect(toList()); Guess what is the type of whoAmI ? It is List<Payroll>
  • 13. Find total amount of money spent on Salaries Every Month. EMP ID City Salary 1 MEL 250 3 MEL 150 2 SYD 230 6 BRS 400 5 SYD 350 7 SYD 100 4 MEL 200 Long sumOfSalaries = employeeList.stream() .mapToLong(emp -> emp.getSalary()) .sum(); sum() will return the total of all the salaries. }Total = 1680 mapToLong() is similar to map() function except map() returns Stream<Object> whereas maptoLong returns LongStream object and helps us perform sum() of all the Longs. Similarly, we have mapToInt() & mapToDouble() to be used with Integer and Double.
  • 14. Distinct Cities in which employees has salaries less than $250 EMP ID City Salary 1 MEL 250 3 MEL 150 2 SYD 230 6 BRS 400 5 SYD 350 7 SYD 100 4 MEL 200 List<String> distinctCities = employeeList.stream() .filter(emp -> emp.getSalary() < 250) .map(emp -> emp.getCity()) .distinct() .collect(toList()); First filtering employees whose salary is less than $300 distinct() method basically removes all the duplicates. MEL MEL SYD SYD filter() [MEL, SYD] distinct()
  • 15. Other Operations.. Check whether all the employees have salary greater than $75. In this case it will return true. Boolean allMatch = employeeList.stream() .allMatch(emp -> emp.getSalary() > 75); Double averageLong = employeeList.stream() .collect(averagingLong(Employee::getSalary)); Highest & Lowest salaried employees. Average salary in the company Optional<Employee> minSalariedEmployee = employeeList.stream() .collect(minBy(comparing(Employee::getSalary))); For maximum salaried employee use maxBy() function of Collectors class. Please check Collectors method for other functions like reducing(), joining(), mapping() etc.
  • 16. 1. Group employees based on whether salary greater than $250 2. Group employees based on City and order by Salary 3. Group employees based on city and then group each city by the role of the employee and order by salary. Advance operations using Streams
  • 17. 1. Group employees based on whether salary greater than $250 Map<Boolean , List<Employee> > partitionByMap = employeeList.stream() .collect(Collectors.partitioningBy(emp -> emp.getSalary() > 250)); partitioningBy() method groups the collection based on the codition passed to it. In this case employees are grouped based on whether their salary is greater than $250. EMP ID City Salary 1 MEL 250 3 MEL 150 2 SYD 230 6 BRS 400 5 SYD 350 7 SYD 100 4 MEL 200 true [emp6, emp5] false [emp1, emp3, emp2, emp7, emp4] Map<Boolean, List<Employee>> List<Employee>
  • 18. Group employees based on City whose salary > 150 and order by Salary Map<String, List<Employee>> groupByCity = employeeList.stream() .filter(emp -> emp.getSalary() > 150) .sorted(comparing(Employee::getSalary).reversed()) .collect(Collectors.groupingBy(emp -> emp.getCity())); Collectors.groupingBy() is used to group the collection based on the return type of the lamda defined in it. In this case we are grouping based on the City. Just Note that in this case , grouping happens on the filtered and sorted collection which we passed to the collect method. EMP ID City Salary 1 MEL 250 3 MEL 150 2 SYD 230 6 BRS 400 5 SYD 350 7 SYD 100 4 MEL 200 BRS [emp6] MEL [emp1, emp4] SYD [emp5, emp2] Map<String, List<Employee>> List<Employee>
  • 19. Id=1 $250, MEL Id=3 $150,MEL Id=2 $230,SYD Id=6 $400,BRS Id=5 $350,SYD Id=7 $100,SYD Id=4 $200,MEL Id=1 $250, MEL Id=2 $230,SYD Id=6 $400,BRS Id=5 $350,SYD Id=4 $200,MEL Id=6 Id=2 $230, SYD Id=4 $200,MEL Java 8 Streams – Filter, Sort on Salary & Group by City .filter(e -> e.getsalary > 150) empList.stream() .sorted( comparing( e -> e.getPrice)) $400,BRS Id=5 $350,SYD Id=1 $250, MEL groupingBy( emp -> emp.getCity) Id=6 $400,BRS Id=5 $350,SYD Id=2 $230, SYD Id=1 $250, MEL Id=4 $200,MEL BRS SYD MEL ..continued
  • 20. Group employees based on city and then group each city by the role of the employee and order by salary. Map<String, Map<String, List<Employee>>> groupByCityAndRole = employeeList.stream() .sorted(comparing(Employee::getSalary).reversed()) .collect(groupingBy(emp -> emp.getCity(), groupingBy(emp -> emp.getRole()))); Collectors.groupingBy() overloaded method first takes initial criteria and second parameter is Collectors object. And hence we can use any method which returns collectors object as second parameter.. So, we passed another groupingBy() method to further classify employees based on the role in each city.
  • 21. EMP ID City Salary Role 1 MEL 250 Developer 3 MEL 150 Developer 2 SYD 230 Developer 6 BRS 400 Director 5 SYD 350 Developer 7 SYD 100 Manager 4 MEL 200 Manager List<Employee> BRS MEL DeveloperDirector Manager [Emp6] [emp1, emp3] [Emp4] SYD Developer Manager [emp5, emp2] [Emp7] .. Continued
  • 22. Parallel stream. Note, that parallelism is not automatically faster than performing operations serially, although it can be if you have enough data and processor cores. List<Long> melEmpIds = employeeList.parallelStream() .filter(emp -> emp.getCity().equals("MEL") && emp.getSalary() < 250) .map(emp -> emp.getEmployeeId()) .collect(toList()); Aggregate operations and parallel streams enable you to implement parallelism with non-thread-safe collections provided that you do not modify the collection while you are operating on it.
  • 23. Read Stream of Lines from a File Stream<String> streamOfLines = Files.lines(Paths.get(”/tmp/transaction.csv”)); The above code reads the file from path specified and creates stream of Line. Each line is represented in the String format.
  • 24. Happy Learning! 1. http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.html 2. http://www.oracle.com/technetwork/articles/java/architect-streams-pt2-2227132.html 3. https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html 4. https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collector.html 5. https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html References