SlideShare una empresa de Scribd logo
1 de 66
Descargar para leer sin conexión
Functional Java 8 
in everyday life 
The code is available on: 
https://github.com/andreaiacono/Java8
Functional Java8 in everyday life 
What's new in Java 8 
•Default methods 
•Lambda expressions 
•Streams 
•Optionals 
•Date/Time API 
Biggest update since Generics in Java 1.5
Functional Java8 in everyday life 
Background 
Anonymous inner classes let define a functional 
behaviour, but with a lot of code: 
JButton testButton = new JButton("Test Button"); 
testButton.addActionListener(new ActionListener() { 
@Override 
public void actionPerformed(ActionEvent ae) { 
System.out.println("Click!"); 
} 
}); 
All we need is a way to write only the code 
in the method.
Functional Java8 in everyday life 
Lambda expressions 
provide a clear and concise way to represent a ”one abstract method 
interface” (a so-called functional interface) using an expression: 
JButton testButton = new JButton("Test Button"); 
testButton.addActionListener(event -> System.out.println("Click!")); 
A lambda is composed of three parts: 
Argument list Arrow token Body of the method 
event → System.out.println("Click!") 
It works because the listener has only one abstract method and the 
compiler can infer what to do from the interface: 
package java.awt.event; 
import java.util.EventListener; 
public interface ActionListener extends EventListener { 
/** 
* Invoked when an action occurs. 
*/ 
public void actionPerformed(ActionEvent e); 
}
Functional Java8 in everyday life 
Lambda expressions 
Variations in signatures: 
Signature Argument 
list 
Arrow 
token Body of the method 
void execute() () → System.out.println("foo!") 
String getString() () → "foo" 
Integer increment(Integer value) (value) → new Integer(value +1) 
String concatenate(String a, String b) (a, b) → a.toString() + b.toString() 
void process(T t) (t) → {}
Data setup 
public class Book { 
private List<Author> authors; 
private String title; 
private int pages; 
private Genre genre; 
private int year; 
private String Isbn; 
} 
public class Author { 
private String name; 
private String lastName; 
private String country; 
} 
public enum Genre { 
NOVEL, SHORT_NOVEL, NON_FICTION; 
} 
Functional Java8 in everyday life
Functional Java8 in everyday life 
Lambda sample 
We need to find the books with more than 400 pages. 
public List getLongBooks(List books) { 
List accumulator = new ArrayList<>(); 
for (Book book : books) { 
if (book.getPages() > 400) { 
accumulator.add(book); 
} 
} 
return accumulator; 
} 
Now the requirements has changed and we also need to filter for 
genre of the book: 
public List getLongNonFictionBooks(List books) { 
List accumulator = new ArrayList<>(); 
for (Book book : books) { 
if (book.getPages() > 400 && Genre.NON_FICTION.equals(book.getGenre())) { 
accumulator.add(book); 
} 
} 
return accumulator; 
} 
We need a different method for every filter, 
while the only change is the if condition!
Functional Java8 in everyday life 
Lambda sample 
We can use a lambda. First we define a functional interface, 
which is an interface with only one abstract method: 
@FunctionalInterface 
public interface BookFilter { 
public boolean test(Book book); 
} 
Then we can define a generic filter and write as many 
implementation we want in just one line: 
public static List lambdaFilter(List books, BookFilter bookFilter) { 
List accumulator = new ArrayList<>(); 
for (Book book : books) { 
if (bookFilter.test(book)) { 
accumulator.add(book); 
} 
} 
return accumulator; 
} 
// one line filters 
List longBooks = lambdaFilter(Setup.books, b -> b.getPages() > 400); 
BookFilter nflbFilter = b -> b.getPages() > 400 && Genre.NON_FICTION == b.getGenre(); 
List longNonFictionBooks = lambdaFilter(Setup.books, nflbFilter);
Functional Java8 in everyday life 
Functional interfaces 
We don't need to write all the functional interfaces because 
Java 8 API defines the basic ones in java.util.function package: 
Functional interface Descriptor Method name 
Predicate<T> T → boolean test() 
BiPredicate<T, U> (T, U) → boolean test() 
Consumer<T> T → void accept() 
BiConsumer<T, U> (T, U) → void accept() 
Supplier<T> () → T get() 
Function<T, R> T → R apply() 
BiFunction<T, U, R> (T, U) → R apply() 
UnaryOperator<T> T → T identity() 
BinaryOperator<T> (T, T) → T apply() 
So we did not need to write the BookFilter interface, because 
the Predicate interface has exactly the same descriptor.
Functional Java8 in everyday life 
Lambda sample 
So we can rewrite our code as: 
public static List lambdaFilter(List books, Predicate bookFilter) { 
List accumulator = new ArrayList<>(); 
for (Book book : books) { 
if (bookFilter.test(book)) { 
accumulator.add(book); 
} 
} 
return accumulator; 
} 
// one line filters 
List longBooks = lambdaFilter(Setup.books, b -> b.getPages() > 400); 
Predicate nflbFilter = b -> b.getPages() > 400 && Genre.NON_FICTION == b.getGenre(); 
List longNonFictionBooks = lambdaFilter(Setup.books, nflbFilter);
Functional Java8 in everyday life 
Lambdas and existing interfaces 
Since in JDK there are a lot of interfaces with only one 
abstract method, we can use lambdas also for them: 
// Runnable interface defines void run() method 
Runnable r = () -> System.out.println("I'm running!"); 
r.run(); 
// Callable defines T call() method 
Callable callable = () -> "This is a callable object"; 
String result = callable.call(); 
// Comparator defines the int compare(T t1, T t2) method 
Comparator bookLengthComparator = (b1, b2) -> b1.getPages() - b2.getPages(); 
Comparator bookAgeComparator = (b1, b2) -> b1.getYear() - b2.getYear();
Functional Java8 in everyday life 
Method reference 
Sometimes code is more readable if we refer just to the method 
name instead of a lambda 
Kind of method reference Example 
To a static method Integer::parseInt 
To an instance method of a class Integer::intValue 
To an instance method of an object n::intValue 
To a constructor Integer::new 
So we can rewrite this lambda 
Function<String, Integer> lengthCalculator = (String s) -> s.length(); 
with a method reference: 
Function<String, Integer> lengthCalculator = String::length;
Functional Java8 in everyday life 
Comparators 
In former versions of Java, we had to write an anonymous 
inner class to speficy the behaviour of a Comparator: 
Collections.sort(users, new Comparator<Author>() { 
public int compare(Author a1, Author a2) { 
return a1.compareTo(a2.id); 
} 
}); 
We can use lambda for making code more readable: 
// now sort is a oneliner! 
Collections.sort(authors, (Author a1, Author a2) -> a1.compareTo(a2));
Functional Java8 in everyday life 
Imagine we want to cache 
results from DB queries. 
This is a first rough version 
(too duplicated logic) 
class DbCache { 
public static enum QueryType { 
BOOKS_COUNT, PUBLISHERS_COUNT, COUNTRIES_COUNT; 
} 
private static Map cache = new HashMap<>(); 
public static Integer getValue(QueryType queryType) { 
Integer count; 
switch (queryType) { 
case BOOKS_COUNT: 
if (cache.containsKey(queryType)) { 
return cache.get(queryType); 
} 
count = countBooks(); 
cache.put(queryType, count); 
return count; 
case PUBLISHERS_COUNT: 
if (cache.containsKey(queryType)) { 
return cache.get(queryType); 
} 
count = countPublishers(); 
cache.put(queryType, count); 
return count; 
case COUNTRIES_COUNT: 
if (cache.containsKey(queryType)) { 
return cache.get(queryType); 
} 
count = countCountries(); 
cache.put(queryType, count); 
return count; 
} 
} 
private static Integer countBooks() { 
return 4; // returns a value got from DB query 
} 
} 
// cache call: 
Integer booksCount = DbCache.getValue(QueryType.BOOKS_COUNT);
Functional Java8 in everyday life 
A bit more polished, but still an ”execute around” pattern: 
class DbCache { 
private static Map cache = new HashMap<>(); 
public static enum QueryType { 
BOOKS_COUNT, PUBLISHERS_COUNT, COUNTRIES_COUNT; 
} 
public static Integer getValue(QueryType queryType) { 
Integer count = cache.get(queryType); 
if (count == null) { 
switch (queryType) { 
case BOOKS_COUNT: 
count = countBooks(); 
break; 
case PUBLISHERS_COUNT: 
count = countPublishers(); 
break; 
case COUNTRIES_COUNT: 
count = countCountries(); 
break; 
} 
} 
cache.put(queryType, count); 
} 
return count; 
} 
private static Integer countBooks() { 
// returns a value got from DB query 
return 4; 
} 
} 
// cache call: 
Integer booksCount = DbCache.getValue(QueryType.BOOKS_COUNT);
Functional Java8 in everyday life 
Using interfaces the result is better, but still verbose: 
class InterfaceCache { 
private static Map cache = new HashMap<>(); 
public static enum QueryType { 
BOOKS_COUNT, PUBLISHERS_COUNT, COUNTRIES_COUNT; 
} 
public static Integer getValue(QueryType queryType, Counter counter) { 
Integer count = cache.get(queryType); 
if (count == null) { 
count = counter.count(); 
cache.put(queryType, count); 
} 
return count; 
} 
} 
interface Counter { 
public Integer count(); 
} 
class BooksCounter implements Counter { 
@Override 
public Integer count() { 
// returns a value got from DB query 
return 4; 
} 
} 
// other Counter implementations 
// cache call: 
BooksCounter bookCounter = new BooksCounter(); 
Integer booksCount = getValue(QueryType.BOOKS_COUNT, bookCounter);
Functional Java8 in everyday life 
We can rewrite the cache with lambdas: 
class FunctionalCache { 
private static Map cache = new HashMap<>(); 
public static enum QueryType { 
BOOKS_COUNT, PUBLISHERS_COUNT, COUNTRIES_COUNT; 
} 
public static Integer getValue(QueryType queryType, Function counter) { 
Integer count = cache.get(queryType); 
if (count == null) { 
count = counter.apply(queryType); 
cache.put(queryType, count); 
} 
return count; 
} 
private static Integer countBooks() { 
// returns a value got from DB query 
return 4; 
} 
// other counts from DB.. 
} 
// cache call: 
Integer booksCount = FunctionalCache.getValue(QueryType.BOOKS_COUNT, f -> countBooks());
Functional Java8 in everyday life 
Or we can put the DB queries inside the cache: 
class FunctionalMapCache { 
private static enum QueryType { 
BOOKS_COUNT(() -> countBooks()), 
PUBLISHERS_COUNT(() -> countPublishers()), 
COUNTRIES_COUNT(() -> countCountries()); 
private Supplier counter; 
QueryType(Supplier counter) { 
this.counter = counter; 
} 
public Supplier getCounter() { 
return counter; 
} 
} 
private static Map cache = new HashMap<>(); 
public static Integer getValue(QueryType queryType) { 
Integer count = cache.get(queryType); 
if (count == null) { 
count = queryType.getCounter().get(); 
cache.put(queryType, count); 
} 
return count; 
} 
private static Integer countBooks() { 
// returns a value got from DB query 
return 4; 
} 
// other counts from DB.. 
} 
// cache call: 
Integer booksCount = getValue(QueryType.BOOKS_COUNT);
Functional Java8 in everyday life 
Streams 
The Java Collections framework relies on the concept of 
external iteration, as in the example below: 
for (Book book: books) { 
book.setYear = 1900; 
} 
compared to internal iteration, like the example below: 
Books.forEach(b -> book.setYear(1900)); 
The difference is not only in code readabilty and 
maintainability, is also related to performance: the runtime 
can optimize the internal iteration for parallelism, lazyness or 
reordering the data.
Functional Java8 in everyday life 
Streams 
Let's see again the book filter we wrote with lambdas: 
public static List lambdaFilter(List books, Predicate bookFilter) { 
List accumulator = new ArrayList<>(); 
for (Book book : books) { 
if (bookFilter.test(book)) { 
accumulator.add(book); 
} 
} 
return accumulator; 
} 
// one line filters 
List longBooks = lambdaFilter(Setup.books, b -> b.getPages() > 400); 
Predicate nflbFilter = b -> b.getPages() > 400 && Genre.NON_FICTION == b.getGenre(); 
List longNonFictionBooks = lambdaFilter(Setup.books, nflbFilter); 
We can rewrite it using streams: 
// stream based filters 
List longBooks = books.stream().filter(b -> b.getPages() > 400).collect(toList()); 
List longNonFictionBooks = 
books.stream().filter(b -> b.getPages() > 400 && Genre.NON_FICTION == b.getGenre()) 
.collect(toList()); 
The code is much cleaner now, because we don't need the 
lambdaFilter() method anymore. Let's see how it works.
Functional Java8 in everyday life 
Streams 
List longBooks = books.stream().filter(b -> b.getPages() > 400).collect(toList()); 
What we've done is: 
• calling the stream() method on the collection, for trasforming it 
into a stream 
• calling the filter() method passing a Predicate, for filtering 
the elements of the stream dropping any/some of them 
• calling the collect() method with the static import toList() 
for collecting the filtered elements and put them into a List 
object
Functional Java8 in everyday life 
Stream operations 
Operation Operation type Return type 
filter(Predicate<T>) intermediate Stream<T> 
map(Function <T, R>) intermediate Stream<R> 
flatMap(Function <T, R>) intermediate Stream<R> 
distinct() intermediate Stream<T> 
sorted(Comparator<T>) intermediate Stream<T> 
peek(Consumer<T>) intermediate Stream<T> 
limit(int n) intermediate Stream<T> 
skip(int n) intermediate Stream<T> 
reduce(BinaryOperator<T>) terminal Optional<T> 
collect(Collector<T, A, R>) terminal R 
forEach(Consumer<T>) terminal void 
min(Comparator<T>) terminal Optional<T> 
max(Comparator<T>) terminal Optional<T> 
count() terminal long 
anyMatch(Predicate<T>) terminal boolean 
allMatch(Predicate<T>) terminal boolean 
noneMatch(Predicate<T>) terminal boolean 
findFirst() terminal Optional<T> 
findAny() terminal Optional<T>
Functional Java8 in everyday life 
Streams samples 
We need all the books with more than 400 pages.
Functional Java8 in everyday life 
Streams samples 
We need all the books with more than 400 pages. Here's how: 
List<Book> longBooks = 
books.stream().filter(b -> b.getPages() > 400).collect(toList());
Functional Java8 in everyday life 
Streams samples 
We need all the books with more than 400 pages. Here's how: 
List<Book> longBooks = 
books.stream().filter(b -> b.getPages() > 400).collect(toList()); 
We need the top three longest books.
Functional Java8 in everyday life 
Streams samples 
We need all the books with more than 400 pages. Here's how: 
List<Book> longBooks = 
books.stream().filter(b -> b.getPages() > 400).collect(toList()); 
We need the top three longest books. Here's how: 
List<Book> top3LongestBooks = 
books.stream().sorted((b1,b2) -> b2.getPages()-b1.getPages()).limit(3).Collect( toList());
Functional Java8 in everyday life 
Streams samples 
We need all the books with more than 400 pages. Here's how: 
List<Book> longBooks = 
books.stream().filter(b -> b.getPages() > 400).collect(toList()); 
We need the top three longest books. Here's how: 
List<Book> top3LongestBooks = 
books.stream().sorted((b1,b2) -> b2.getPages()-b1.getPages()).limit(3).Collect( toList()); 
We need from the fourth to the last longest books.
Functional Java8 in everyday life 
Streams samples 
We need all the books with more than 400 pages. Here's how: 
List<Book> longBooks = 
books.stream().filter(b -> b.getPages() > 400).collect(toList()); 
We need the top three longest books. Here's how: 
List<Book> top3LongestBooks = 
books.stream().sorted((b1,b2) -> b2.getPages()-b1.getPages()).limit(3).Collect( toList()); 
We need from the fourth to the last longest books. Here's how: 
List<Book> fromFourthLongestBooks = 
books.stream().sorted((b1,b2) -> b2.getPages()-b1.getPages()).skip(3).collect(toList());
Functional Java8 in everyday life 
Streams samples 
We need to get all the publishing years.
Functional Java8 in everyday life 
Streams samples 
We need to get all the publishing years. Here's how: 
List<Integer> publishingYears = 
books.stream().map(b -> b.getYear()).distinct().collect(toList());
Functional Java8 in everyday life 
Streams samples 
We need to get all the publishing years. Here's how: 
List<Integer> publishingYears = 
books.stream().map(b -> b.getYear()).distinct().collect(toList()); 
We need all the authors.
Functional Java8 in everyday life 
Streams samples 
We need to get all the publishing years. Here's how: 
List<Integer> publishingYears = 
books.stream().map(b -> b.getYear()).distinct().collect(toList()); 
We need all the authors. Here's how: 
Set<Author> authors = 
books.stream().flatMap(b -> b.getAuthors().stream()).distinct().collect(toSet());
Functional Java8 in everyday life 
Streams samples 
We need to get all the publishing years. Here's how: 
List<Integer> publishingYears = 
books.stream().map(b -> b.getYear()).distinct().collect(toList()); 
We need all the authors. Here's how: 
Set<Author> authors = 
books.stream().flatMap(b -> b.getAuthors().stream()).distinct().collect(toSet()); 
We need all the origin countries of the authors.
Functional Java8 in everyday life 
Streams samples 
We need to get all the publishing years. Here's how: 
List<Integer> publishingYears = 
books.stream().map(b -> b.getYear()).distinct().collect(toList()); 
We need all the authors. Here's how: 
Set<Author> authors = 
books.stream().flatMap(b -> b.getAuthors().stream()).distinct().collect(toSet()); 
We need all the origin countries of the authors. Here's how: 
Set<String> countries = 
books.stream().flatMap(b -> b.getAuthors().stream()) 
.map(author -> author.getCountry()).distinct().collect(toSet());
Functional Java8 in everyday life 
Optionals 
Let's start with an example: ISBN in 2007 has changed from 
10 to 13 characters. To check which version of ISBN a book 
has we have to write: 
boolean isPre2007 = book.getIsbn().length() > 10; 
What if a book was published before 1970, when ISBN did not 
exist and the property ISBN is null? Without a proper check, 
NullPointerException will be thrown at runtime! 
Java 8 has introduced the java.util.Optional class. The 
code of our Book class can be now written as: 
public class Book { 
private List<Author> authors; 
private String title; 
private int pages; 
private Optional<String> Isbn; 
private Genre genre; 
private int year; 
}
Functional Java8 in everyday life 
Optionals 
We can set the value with: 
book.setIsbn(Optional.of("978000000")); 
Or, if the book was published before 1970: 
book.setIsbn(Optional.empty()); 
Or, if we don't know the value in advance: 
book.setIsbn(Optional.ofNullable(value)); 
(in case value is null an empty Optional will be set) 
We can now get the value with: 
Optional<String> isbn = book.getIsbn(); 
System.out.println("Isbn: " + isbn.orElse("NOT PRESENT"); 
If the Optional contains an ISBN it will be returned, 
otherwise the string "NOT PRESENT" will be returned.
Functional Java8 in everyday life 
Other streams samples 
We want the most recent published book.
Functional Java8 in everyday life 
Other streams samples 
We want the most recent published book. Here's how: 
Optional<Book> lastPublishedBook = 
books.stream().min(Comparator.comparingInt(Book::getYear));
Functional Java8 in everyday life 
Other streams samples 
We want the most recent published book. Here's how: 
Optional<Book> lastPublishedBook = 
books.stream().min(Comparator.comparingInt(Book::getYear)); 
We want to know if all the books are written by more 
than one author.
Functional Java8 in everyday life 
Other streams samples 
We want the most recent published book. Here's how: 
Optional<Book> lastPublishedBook = 
books.stream().min(Comparator.comparingInt(Book::getYear)); 
We want to know if all the books are written by more 
than one author. Here's how: 
boolean onlyShortBooks = 
books.stream().allMatch(b -> b.getAuthors().size() > 1);
Functional Java8 in everyday life 
Other streams samples 
We want the most recent published book. Here's how: 
Optional<Book> lastPublishedBook = 
books.stream().min(Comparator.comparingInt(Book::getYear)); 
We want to know if all the books are written by more 
than one author. Here's how: 
boolean onlyShortBooks = 
books.stream().allMatch(b -> b.getAuthors().size() > 1); 
We want one of the books written by more than one 
author.
Functional Java8 in everyday life 
Other streams samples 
We want the most recent published book. Here's how: 
Optional<Book> lastPublishedBook = 
books.stream().min(Comparator.comparingInt(Book::getYear)); 
We want to know if all the books are written by more 
than one author. Here's how: 
boolean onlyShortBooks = 
books.stream().allMatch(b -> b.getAuthors().size() > 1); 
We want one of the books written by more than one 
author. Here's how: 
Optional<Book> multiAuthorBook = 
books.stream().filter((b -> b.getAuthors().size() > 1)).findAny();
Functional Java8 in everyday life 
Streams samples 
We want the total number of pages published.
Functional Java8 in everyday life 
Streams samples 
We want the total number of pages published. Here's how: 
Integer totalPages = 
books.stream().map(Book::getPages).reduce(0, (b1, b2) -> b1 + b2); 
Optional<Integer> totalPages = 
or: 
books.stream().map(Book::getPages).reduce(Integer::sum);
Functional Java8 in everyday life 
Streams samples 
We want the total number of pages published. Here's how: 
Integer totalPages = 
books.stream().map(Book::getPages).reduce(0, (b1, b2) -> b1 + b2); 
Optional<Integer> totalPages = 
or: 
books.stream().map(Book::getPages).reduce(Integer::sum); 
We want to know how many pages the longest book has.
Functional Java8 in everyday life 
Streams samples 
We want the total number of pages published. Here's how: 
Integer totalPages = 
books.stream().map(Book::getPages).reduce(0, (b1, b2) -> b1 + b2); 
Optional<Integer> totalPages = 
or: 
books.stream().map(Book::getPages).reduce(Integer::sum); 
We want to know how many pages the longest book has. 
Here's how: 
Optional<Integer> longestBook = 
books.stream().map(Book::getPages).reduce(Integer::max);
Functional Java8 in everyday life 
The Collector interface 
The Collector interface was introduce to give developers a set of 
methods for reduction operations. 
Method Return type 
toList() List<T> 
toSet() Set<t> 
toCollection() Collection<T> 
counting() Long 
summingInt() Long 
averagingInt() Double 
joining() String 
maxBy() Optional<T> 
minBy() Optional<T> 
reducing() ... 
groupingBy() Map<K, List<T>> 
partioningBy() Map<Boolean, List<T>>
Functional Java8 in everyday life 
Collector samples 
We want the average number of pages of the books.
Functional Java8 in everyday life 
Collector samples 
We want the average number of pages of the books. Here's how: 
Double averagePages = 
books.stream().collect(averagingInt(Book::getPages));
Functional Java8 in everyday life 
Collector samples 
We want the average number of pages of the books. Here's how: 
Double averagePages = 
books.stream().collect(averagingInt(Book::getPages)); 
We want all the titles of the books.
Functional Java8 in everyday life 
Collector samples 
We want the average number of pages of the books. Here's how: 
Double averagePages = 
books.stream().collect(averagingInt(Book::getPages)); 
We want all the titles of the books. Here's how: 
String allTitles = 
books.stream().map(Book::getTitle).collect(joining(", "));
Functional Java8 in everyday life 
Collector samples 
We want the average number of pages of the books. Here's how: 
Double averagePages = 
books.stream().collect(averagingInt(Book::getPages)); 
We want all the titles of the books. Here's how: 
String allTitles = 
books.stream().map(Book::getTitle).collect(joining(", ")); 
We want the book with the higher number of authors. Here's how: 
Optional<Book> higherNumberOfAuthorsBook = 
books.stream().collect(maxBy(comparing(b -> b.getAuthors().size())));
Functional Java8 in everyday life 
Stream grouping 
We want a Map of book per year.
Functional Java8 in everyday life 
Stream grouping 
We want a Map of book per year. Here's how: 
Map<Integer, List<Book>> booksPerYear = 
Setup.books.stream().collect(groupingBy(Book::getYear));
Functional Java8 in everyday life 
Stream grouping 
We want a Map of book per year. Here's how: 
Map<Integer, List<Book>> booksPerYear = 
Setup.books.stream().collect(groupingBy(Book::getYear)); 
We want a Map of how many books are published per year per 
genre.
Functional Java8 in everyday life 
Stream grouping 
We want a Map of book per year. Here's how: 
Map<Integer, List<Book>> booksPerYear = 
Setup.books.stream().collect(groupingBy(Book::getYear)); 
We want a Map of how many books are published per year per 
genre. Here's how: 
Map<Integer, Map<Genre, List<Book>>> booksPerYearPerGenre = 
Setup.books.stream().collect(groupingBy(Book::getYear, groupingBy(Book::getGenre)));
Functional Java8 in everyday life 
Stream grouping 
We want a Map of book per year. Here's how: 
Map<Integer, List<Book>> booksPerYear = 
Setup.books.stream().collect(groupingBy(Book::getYear)); 
We want a Map of how many books are published per year per 
genre. Here's how: 
Map<Integer, Map<Genre, List<Book>>> booksPerYearPerGenre = 
Setup.books.stream().collect(groupingBy(Book::getYear, groupingBy(Book::getGenre))); 
We want to count how many books are published per year.
Functional Java8 in everyday life 
Stream grouping 
We want a Map of book per year. Here's how: 
Map<Integer, List<Book>> booksPerYear = 
Setup.books.stream().collect(groupingBy(Book::getYear)); 
We want a Map of how many books are published per year per 
genre. Here's how: 
Map<Integer, Map<Genre, List<Book>>> booksPerYearPerGenre = 
Setup.books.stream().collect(groupingBy(Book::getYear, groupingBy(Book::getGenre))); 
We want to count how many books are published per year. 
Here's how: 
Map<Integer, Long> bookCountPerYear = 
Setup.books.stream().collect(groupingBy(Book::getYear, counting()));
Functional Java8 in everyday life 
Stream partitioning 
We want to classify book by hardcover.
Functional Java8 in everyday life 
Stream partitioning 
We want to classify book by hardcover. Here's how: 
Map<Boolean, List<Book>> hardCoverBooks = 
books.stream().collect(partitioningBy(Book::hasHardCover));
Functional Java8 in everyday life 
Stream partitioning 
We want to classify book by hardcover. Here's how: 
Map<Boolean, List<Book>> hardCoverBooks = 
books.stream().collect(partitioningBy(Book::hasHardCover)); 
We want to further classify book by genre.
Functional Java8 in everyday life 
Stream partitioning 
We want to classify book by hardcover. Here's how: 
Map<Boolean, List<Book>> hardCoverBooks = 
books.stream().collect(partitioningBy(Book::hasHardCover)); 
We want to further classify book by genre. Here's how: 
Map<Boolean, Map<Genre, List<Book>>> hardCoverBooksByGenre = 
books.stream().collect(partitioningBy(Book::hasHardCover,groupingBy(Book::getGenre)));
Functional Java8 in everyday life 
Stream partitioning 
We want to classify book by hardcover. Here's how: 
Map<Boolean, List<Book>> hardCoverBooks = 
books.stream().collect(partitioningBy(Book::hasHardCover)); 
We want to further classify book by genre. Here's how: 
Map<Boolean, Map<Genre, List<Book>>> hardCoverBooksByGenre = 
books.stream().collect(partitioningBy(Book::hasHardCover,groupingBy(Book::getGenre))); 
We want to count books with/without hardcover.
Functional Java8 in everyday life 
Stream partitioning 
We want to classify book by hardcover. Here's how: 
Map<Boolean, List<Book>> hardCoverBooks = 
books.stream().collect(partitioningBy(Book::hasHardCover)); 
We want to further classify book by genre. Here's how: 
Map<Boolean, Map<Genre, List<Book>>> hardCoverBooksByGenre = 
books.stream().collect(partitioningBy(Book::hasHardCover,groupingBy(Book::getGenre))); 
We want to count books with/without hardcover. Here's how: 
Map<Boolean, Long> count = 
books.stream().collect(partitioningBy(Book::hasHardCover, counting()));
Functional Java8 in everyday life 
What we did not see: 
• Parallel streams 
• Streams methods for primitive types
Functional Java8 in everyday life 
Thanks! 
The code is available on: 
https://github.com/andreaiacono/Java8

Más contenido relacionado

La actualidad más candente

La actualidad más candente (20)

Multithreading In Java
Multithreading In JavaMultithreading In Java
Multithreading In Java
 
Java Input Output and File Handling
Java Input Output and File HandlingJava Input Output and File Handling
Java Input Output and File Handling
 
Data types in python
Data types in pythonData types in python
Data types in python
 
Bst(Binary Search Tree)
Bst(Binary Search Tree)Bst(Binary Search Tree)
Bst(Binary Search Tree)
 
Java Thread Synchronization
Java Thread SynchronizationJava Thread Synchronization
Java Thread Synchronization
 
Conditional and control statement
Conditional and control statementConditional and control statement
Conditional and control statement
 
Monoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and CatsMonoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and Cats
 
Numpy Talk at SIAM
Numpy Talk at SIAMNumpy Talk at SIAM
Numpy Talk at SIAM
 
Java 8 - Features Overview
Java 8 - Features OverviewJava 8 - Features Overview
Java 8 - Features Overview
 
Core java Essentials
Core java EssentialsCore java Essentials
Core java Essentials
 
Java interface
Java interfaceJava interface
Java interface
 
Static and Dynamic polymorphism in C++
Static and Dynamic polymorphism in C++Static and Dynamic polymorphism in C++
Static and Dynamic polymorphism in C++
 
Threads concept in java
Threads concept in javaThreads concept in java
Threads concept in java
 
07 java collection
07 java collection07 java collection
07 java collection
 
Java 8 - An Overview
Java 8 - An OverviewJava 8 - An Overview
Java 8 - An Overview
 
Java String class
Java String classJava String class
Java String class
 
Java I/O
Java I/OJava I/O
Java I/O
 
Data structures and algorithms made easy
Data structures and algorithms made easyData structures and algorithms made easy
Data structures and algorithms made easy
 
Lambda Expressions in Java 8
Lambda Expressions in Java 8Lambda Expressions in Java 8
Lambda Expressions in Java 8
 
Generics
GenericsGenerics
Generics
 

Destacado

Java 8 Lambda Built-in Functional Interfaces
Java 8 Lambda Built-in Functional InterfacesJava 8 Lambda Built-in Functional Interfaces
Java 8 Lambda Built-in Functional InterfacesGanesh Samarthyam
 
Introduction to functional programming with java 8
Introduction to functional programming with java 8Introduction to functional programming with java 8
Introduction to functional programming with java 8JavaBrahman
 
Functional programming principles and Java 8
Functional programming principles and Java 8Functional programming principles and Java 8
Functional programming principles and Java 8Dragos Balan
 
Clean Lambdas & Streams in Java8
Clean Lambdas & Streams in Java8Clean Lambdas & Streams in Java8
Clean Lambdas & Streams in Java8Victor Rentea
 
Functional programming with Java 8
Functional programming with Java 8Functional programming with Java 8
Functional programming with Java 8LivePerson
 
Java8 and Functional Programming
Java8 and Functional ProgrammingJava8 and Functional Programming
Java8 and Functional ProgrammingYiguang Hu
 
Java8 javatime-api
Java8 javatime-apiJava8 javatime-api
Java8 javatime-apiJini Lee
 
Eclipse Day India 2015 - Java 8 Overview
Eclipse Day India 2015 - Java 8 OverviewEclipse Day India 2015 - Java 8 Overview
Eclipse Day India 2015 - Java 8 OverviewEclipse Day India
 
Concurrency with java
Concurrency with javaConcurrency with java
Concurrency with javaHoang Nguyen
 
Understanding java streams
Understanding java streamsUnderstanding java streams
Understanding java streamsShahjahan Samoon
 
Working With Concurrency In Java 8
Working With Concurrency In Java 8Working With Concurrency In Java 8
Working With Concurrency In Java 8Heartin Jacob
 

Destacado (20)

Java 8 Lambda Built-in Functional Interfaces
Java 8 Lambda Built-in Functional InterfacesJava 8 Lambda Built-in Functional Interfaces
Java 8 Lambda Built-in Functional Interfaces
 
Introduction to functional programming with java 8
Introduction to functional programming with java 8Introduction to functional programming with java 8
Introduction to functional programming with java 8
 
Functional Programming in Java
Functional Programming in JavaFunctional Programming in Java
Functional Programming in Java
 
Functional programming principles and Java 8
Functional programming principles and Java 8Functional programming principles and Java 8
Functional programming principles and Java 8
 
Clean Lambdas & Streams in Java8
Clean Lambdas & Streams in Java8Clean Lambdas & Streams in Java8
Clean Lambdas & Streams in Java8
 
Functional programming with Java 8
Functional programming with Java 8Functional programming with Java 8
Functional programming with Java 8
 
Java8 and Functional Programming
Java8 and Functional ProgrammingJava8 and Functional Programming
Java8 and Functional Programming
 
Java8 javatime-api
Java8 javatime-apiJava8 javatime-api
Java8 javatime-api
 
Java8
Java8Java8
Java8
 
Streams in Java 8
Streams in Java 8Streams in Java 8
Streams in Java 8
 
Java 8 Date and Time API
Java 8 Date and Time APIJava 8 Date and Time API
Java 8 Date and Time API
 
Functional Programming in JAVA 8
Functional Programming in JAVA 8Functional Programming in JAVA 8
Functional Programming in JAVA 8
 
Eclipse Day India 2015 - Java 8 Overview
Eclipse Day India 2015 - Java 8 OverviewEclipse Day India 2015 - Java 8 Overview
Eclipse Day India 2015 - Java 8 Overview
 
Major Java 8 features
Major Java 8 featuresMajor Java 8 features
Major Java 8 features
 
Concurrency with java
Concurrency with javaConcurrency with java
Concurrency with java
 
Java8
Java8Java8
Java8
 
Understanding java streams
Understanding java streamsUnderstanding java streams
Understanding java streams
 
Working With Concurrency In Java 8
Working With Concurrency In Java 8Working With Concurrency In Java 8
Working With Concurrency In Java 8
 
AngularJS2
AngularJS2AngularJS2
AngularJS2
 
Java 8 Lambda Expressions
Java 8 Lambda ExpressionsJava 8 Lambda Expressions
Java 8 Lambda Expressions
 

Similar a Functional Java 8 in everyday life

Scala is java8.next()
Scala is java8.next()Scala is java8.next()
Scala is java8.next()daewon jeong
 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondMario Fusco
 
What is new in java 8 concurrency
What is new in java 8 concurrencyWhat is new in java 8 concurrency
What is new in java 8 concurrencykshanth2101
 
Effective Java. By materials of Josch Bloch's book
Effective Java. By materials of Josch Bloch's bookEffective Java. By materials of Josch Bloch's book
Effective Java. By materials of Josch Bloch's bookRoman Tsypuk
 
Lambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive CodeLambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive CodeIan Robertson
 
What's new in Java 8
What's new in Java 8What's new in Java 8
What's new in Java 8Kyle Smith
 
New Features in JDK 8
New Features in JDK 8New Features in JDK 8
New Features in JDK 8Martin Toshev
 
Arquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackArquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackNelson Glauber Leal
 
Cocoaheads Meetup / Alex Zimin / Swift magic
Cocoaheads Meetup / Alex Zimin / Swift magicCocoaheads Meetup / Alex Zimin / Swift magic
Cocoaheads Meetup / Alex Zimin / Swift magicBadoo Development
 
Александр Зимин (Alexander Zimin) — Магия Swift
Александр Зимин (Alexander Zimin) — Магия SwiftАлександр Зимин (Alexander Zimin) — Магия Swift
Александр Зимин (Alexander Zimin) — Магия SwiftCocoaHeads
 
Introduction of Java 8 with emphasis on Lambda Expressions and Streams
Introduction of Java 8 with emphasis on Lambda Expressions and StreamsIntroduction of Java 8 with emphasis on Lambda Expressions and Streams
Introduction of Java 8 with emphasis on Lambda Expressions and StreamsEmiel Paasschens
 
Java 8 presentation
Java 8 presentationJava 8 presentation
Java 8 presentationVan Huong
 
Xebicon2013 scala vsjava_final
Xebicon2013 scala vsjava_finalXebicon2013 scala vsjava_final
Xebicon2013 scala vsjava_finalUrs Peter
 

Similar a Functional Java 8 in everyday life (20)

Scala is java8.next()
Scala is java8.next()Scala is java8.next()
Scala is java8.next()
 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
 
Java 8 Lambda and Streams
Java 8 Lambda and StreamsJava 8 Lambda and Streams
Java 8 Lambda and Streams
 
Java 8
Java 8Java 8
Java 8
 
Java 8 Intro - Core Features
Java 8 Intro - Core FeaturesJava 8 Intro - Core Features
Java 8 Intro - Core Features
 
Java gets a closure
Java gets a closureJava gets a closure
Java gets a closure
 
What is new in java 8 concurrency
What is new in java 8 concurrencyWhat is new in java 8 concurrency
What is new in java 8 concurrency
 
Java 8 Lambda Expressions
Java 8 Lambda ExpressionsJava 8 Lambda Expressions
Java 8 Lambda Expressions
 
Java 8
Java 8Java 8
Java 8
 
Effective Java. By materials of Josch Bloch's book
Effective Java. By materials of Josch Bloch's bookEffective Java. By materials of Josch Bloch's book
Effective Java. By materials of Josch Bloch's book
 
Lambdas and Laughs
Lambdas and LaughsLambdas and Laughs
Lambdas and Laughs
 
Lambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive CodeLambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive Code
 
What's new in Java 8
What's new in Java 8What's new in Java 8
What's new in Java 8
 
New Features in JDK 8
New Features in JDK 8New Features in JDK 8
New Features in JDK 8
 
Arquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackArquitetando seu app Android com Jetpack
Arquitetando seu app Android com Jetpack
 
Cocoaheads Meetup / Alex Zimin / Swift magic
Cocoaheads Meetup / Alex Zimin / Swift magicCocoaheads Meetup / Alex Zimin / Swift magic
Cocoaheads Meetup / Alex Zimin / Swift magic
 
Александр Зимин (Alexander Zimin) — Магия Swift
Александр Зимин (Alexander Zimin) — Магия SwiftАлександр Зимин (Alexander Zimin) — Магия Swift
Александр Зимин (Alexander Zimin) — Магия Swift
 
Introduction of Java 8 with emphasis on Lambda Expressions and Streams
Introduction of Java 8 with emphasis on Lambda Expressions and StreamsIntroduction of Java 8 with emphasis on Lambda Expressions and Streams
Introduction of Java 8 with emphasis on Lambda Expressions and Streams
 
Java 8 presentation
Java 8 presentationJava 8 presentation
Java 8 presentation
 
Xebicon2013 scala vsjava_final
Xebicon2013 scala vsjava_finalXebicon2013 scala vsjava_final
Xebicon2013 scala vsjava_final
 

Más de Andrea Iacono

Mapreduce by examples
Mapreduce by examplesMapreduce by examples
Mapreduce by examplesAndrea Iacono
 
The Pregel Programming Model with Spark GraphX
The Pregel Programming Model with Spark GraphXThe Pregel Programming Model with Spark GraphX
The Pregel Programming Model with Spark GraphXAndrea Iacono
 
Graphs are everywhere! Distributed graph computing with Spark GraphX
Graphs are everywhere! Distributed graph computing with Spark GraphXGraphs are everywhere! Distributed graph computing with Spark GraphX
Graphs are everywhere! Distributed graph computing with Spark GraphXAndrea Iacono
 
Real time and reliable processing with Apache Storm
Real time and reliable processing with Apache StormReal time and reliable processing with Apache Storm
Real time and reliable processing with Apache StormAndrea Iacono
 
How to build_a_search_engine
How to build_a_search_engineHow to build_a_search_engine
How to build_a_search_engineAndrea Iacono
 

Más de Andrea Iacono (6)

Mapreduce by examples
Mapreduce by examplesMapreduce by examples
Mapreduce by examples
 
The Pregel Programming Model with Spark GraphX
The Pregel Programming Model with Spark GraphXThe Pregel Programming Model with Spark GraphX
The Pregel Programming Model with Spark GraphX
 
Graphs are everywhere! Distributed graph computing with Spark GraphX
Graphs are everywhere! Distributed graph computing with Spark GraphXGraphs are everywhere! Distributed graph computing with Spark GraphX
Graphs are everywhere! Distributed graph computing with Spark GraphX
 
Real time and reliable processing with Apache Storm
Real time and reliable processing with Apache StormReal time and reliable processing with Apache Storm
Real time and reliable processing with Apache Storm
 
How to build_a_search_engine
How to build_a_search_engineHow to build_a_search_engine
How to build_a_search_engine
 
Machine learning
Machine learningMachine learning
Machine learning
 

Último

5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Intelisync
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfkalichargn70th171
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationkaushalgiri8080
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyFrank van der Linden
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 

Último (20)

5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanation
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The Ugly
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 

Functional Java 8 in everyday life

  • 1. Functional Java 8 in everyday life The code is available on: https://github.com/andreaiacono/Java8
  • 2. Functional Java8 in everyday life What's new in Java 8 •Default methods •Lambda expressions •Streams •Optionals •Date/Time API Biggest update since Generics in Java 1.5
  • 3. Functional Java8 in everyday life Background Anonymous inner classes let define a functional behaviour, but with a lot of code: JButton testButton = new JButton("Test Button"); testButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { System.out.println("Click!"); } }); All we need is a way to write only the code in the method.
  • 4. Functional Java8 in everyday life Lambda expressions provide a clear and concise way to represent a ”one abstract method interface” (a so-called functional interface) using an expression: JButton testButton = new JButton("Test Button"); testButton.addActionListener(event -> System.out.println("Click!")); A lambda is composed of three parts: Argument list Arrow token Body of the method event → System.out.println("Click!") It works because the listener has only one abstract method and the compiler can infer what to do from the interface: package java.awt.event; import java.util.EventListener; public interface ActionListener extends EventListener { /** * Invoked when an action occurs. */ public void actionPerformed(ActionEvent e); }
  • 5. Functional Java8 in everyday life Lambda expressions Variations in signatures: Signature Argument list Arrow token Body of the method void execute() () → System.out.println("foo!") String getString() () → "foo" Integer increment(Integer value) (value) → new Integer(value +1) String concatenate(String a, String b) (a, b) → a.toString() + b.toString() void process(T t) (t) → {}
  • 6. Data setup public class Book { private List<Author> authors; private String title; private int pages; private Genre genre; private int year; private String Isbn; } public class Author { private String name; private String lastName; private String country; } public enum Genre { NOVEL, SHORT_NOVEL, NON_FICTION; } Functional Java8 in everyday life
  • 7. Functional Java8 in everyday life Lambda sample We need to find the books with more than 400 pages. public List getLongBooks(List books) { List accumulator = new ArrayList<>(); for (Book book : books) { if (book.getPages() > 400) { accumulator.add(book); } } return accumulator; } Now the requirements has changed and we also need to filter for genre of the book: public List getLongNonFictionBooks(List books) { List accumulator = new ArrayList<>(); for (Book book : books) { if (book.getPages() > 400 && Genre.NON_FICTION.equals(book.getGenre())) { accumulator.add(book); } } return accumulator; } We need a different method for every filter, while the only change is the if condition!
  • 8. Functional Java8 in everyday life Lambda sample We can use a lambda. First we define a functional interface, which is an interface with only one abstract method: @FunctionalInterface public interface BookFilter { public boolean test(Book book); } Then we can define a generic filter and write as many implementation we want in just one line: public static List lambdaFilter(List books, BookFilter bookFilter) { List accumulator = new ArrayList<>(); for (Book book : books) { if (bookFilter.test(book)) { accumulator.add(book); } } return accumulator; } // one line filters List longBooks = lambdaFilter(Setup.books, b -> b.getPages() > 400); BookFilter nflbFilter = b -> b.getPages() > 400 && Genre.NON_FICTION == b.getGenre(); List longNonFictionBooks = lambdaFilter(Setup.books, nflbFilter);
  • 9. Functional Java8 in everyday life Functional interfaces We don't need to write all the functional interfaces because Java 8 API defines the basic ones in java.util.function package: Functional interface Descriptor Method name Predicate<T> T → boolean test() BiPredicate<T, U> (T, U) → boolean test() Consumer<T> T → void accept() BiConsumer<T, U> (T, U) → void accept() Supplier<T> () → T get() Function<T, R> T → R apply() BiFunction<T, U, R> (T, U) → R apply() UnaryOperator<T> T → T identity() BinaryOperator<T> (T, T) → T apply() So we did not need to write the BookFilter interface, because the Predicate interface has exactly the same descriptor.
  • 10. Functional Java8 in everyday life Lambda sample So we can rewrite our code as: public static List lambdaFilter(List books, Predicate bookFilter) { List accumulator = new ArrayList<>(); for (Book book : books) { if (bookFilter.test(book)) { accumulator.add(book); } } return accumulator; } // one line filters List longBooks = lambdaFilter(Setup.books, b -> b.getPages() > 400); Predicate nflbFilter = b -> b.getPages() > 400 && Genre.NON_FICTION == b.getGenre(); List longNonFictionBooks = lambdaFilter(Setup.books, nflbFilter);
  • 11. Functional Java8 in everyday life Lambdas and existing interfaces Since in JDK there are a lot of interfaces with only one abstract method, we can use lambdas also for them: // Runnable interface defines void run() method Runnable r = () -> System.out.println("I'm running!"); r.run(); // Callable defines T call() method Callable callable = () -> "This is a callable object"; String result = callable.call(); // Comparator defines the int compare(T t1, T t2) method Comparator bookLengthComparator = (b1, b2) -> b1.getPages() - b2.getPages(); Comparator bookAgeComparator = (b1, b2) -> b1.getYear() - b2.getYear();
  • 12. Functional Java8 in everyday life Method reference Sometimes code is more readable if we refer just to the method name instead of a lambda Kind of method reference Example To a static method Integer::parseInt To an instance method of a class Integer::intValue To an instance method of an object n::intValue To a constructor Integer::new So we can rewrite this lambda Function<String, Integer> lengthCalculator = (String s) -> s.length(); with a method reference: Function<String, Integer> lengthCalculator = String::length;
  • 13. Functional Java8 in everyday life Comparators In former versions of Java, we had to write an anonymous inner class to speficy the behaviour of a Comparator: Collections.sort(users, new Comparator<Author>() { public int compare(Author a1, Author a2) { return a1.compareTo(a2.id); } }); We can use lambda for making code more readable: // now sort is a oneliner! Collections.sort(authors, (Author a1, Author a2) -> a1.compareTo(a2));
  • 14. Functional Java8 in everyday life Imagine we want to cache results from DB queries. This is a first rough version (too duplicated logic) class DbCache { public static enum QueryType { BOOKS_COUNT, PUBLISHERS_COUNT, COUNTRIES_COUNT; } private static Map cache = new HashMap<>(); public static Integer getValue(QueryType queryType) { Integer count; switch (queryType) { case BOOKS_COUNT: if (cache.containsKey(queryType)) { return cache.get(queryType); } count = countBooks(); cache.put(queryType, count); return count; case PUBLISHERS_COUNT: if (cache.containsKey(queryType)) { return cache.get(queryType); } count = countPublishers(); cache.put(queryType, count); return count; case COUNTRIES_COUNT: if (cache.containsKey(queryType)) { return cache.get(queryType); } count = countCountries(); cache.put(queryType, count); return count; } } private static Integer countBooks() { return 4; // returns a value got from DB query } } // cache call: Integer booksCount = DbCache.getValue(QueryType.BOOKS_COUNT);
  • 15. Functional Java8 in everyday life A bit more polished, but still an ”execute around” pattern: class DbCache { private static Map cache = new HashMap<>(); public static enum QueryType { BOOKS_COUNT, PUBLISHERS_COUNT, COUNTRIES_COUNT; } public static Integer getValue(QueryType queryType) { Integer count = cache.get(queryType); if (count == null) { switch (queryType) { case BOOKS_COUNT: count = countBooks(); break; case PUBLISHERS_COUNT: count = countPublishers(); break; case COUNTRIES_COUNT: count = countCountries(); break; } } cache.put(queryType, count); } return count; } private static Integer countBooks() { // returns a value got from DB query return 4; } } // cache call: Integer booksCount = DbCache.getValue(QueryType.BOOKS_COUNT);
  • 16. Functional Java8 in everyday life Using interfaces the result is better, but still verbose: class InterfaceCache { private static Map cache = new HashMap<>(); public static enum QueryType { BOOKS_COUNT, PUBLISHERS_COUNT, COUNTRIES_COUNT; } public static Integer getValue(QueryType queryType, Counter counter) { Integer count = cache.get(queryType); if (count == null) { count = counter.count(); cache.put(queryType, count); } return count; } } interface Counter { public Integer count(); } class BooksCounter implements Counter { @Override public Integer count() { // returns a value got from DB query return 4; } } // other Counter implementations // cache call: BooksCounter bookCounter = new BooksCounter(); Integer booksCount = getValue(QueryType.BOOKS_COUNT, bookCounter);
  • 17. Functional Java8 in everyday life We can rewrite the cache with lambdas: class FunctionalCache { private static Map cache = new HashMap<>(); public static enum QueryType { BOOKS_COUNT, PUBLISHERS_COUNT, COUNTRIES_COUNT; } public static Integer getValue(QueryType queryType, Function counter) { Integer count = cache.get(queryType); if (count == null) { count = counter.apply(queryType); cache.put(queryType, count); } return count; } private static Integer countBooks() { // returns a value got from DB query return 4; } // other counts from DB.. } // cache call: Integer booksCount = FunctionalCache.getValue(QueryType.BOOKS_COUNT, f -> countBooks());
  • 18. Functional Java8 in everyday life Or we can put the DB queries inside the cache: class FunctionalMapCache { private static enum QueryType { BOOKS_COUNT(() -> countBooks()), PUBLISHERS_COUNT(() -> countPublishers()), COUNTRIES_COUNT(() -> countCountries()); private Supplier counter; QueryType(Supplier counter) { this.counter = counter; } public Supplier getCounter() { return counter; } } private static Map cache = new HashMap<>(); public static Integer getValue(QueryType queryType) { Integer count = cache.get(queryType); if (count == null) { count = queryType.getCounter().get(); cache.put(queryType, count); } return count; } private static Integer countBooks() { // returns a value got from DB query return 4; } // other counts from DB.. } // cache call: Integer booksCount = getValue(QueryType.BOOKS_COUNT);
  • 19. Functional Java8 in everyday life Streams The Java Collections framework relies on the concept of external iteration, as in the example below: for (Book book: books) { book.setYear = 1900; } compared to internal iteration, like the example below: Books.forEach(b -> book.setYear(1900)); The difference is not only in code readabilty and maintainability, is also related to performance: the runtime can optimize the internal iteration for parallelism, lazyness or reordering the data.
  • 20. Functional Java8 in everyday life Streams Let's see again the book filter we wrote with lambdas: public static List lambdaFilter(List books, Predicate bookFilter) { List accumulator = new ArrayList<>(); for (Book book : books) { if (bookFilter.test(book)) { accumulator.add(book); } } return accumulator; } // one line filters List longBooks = lambdaFilter(Setup.books, b -> b.getPages() > 400); Predicate nflbFilter = b -> b.getPages() > 400 && Genre.NON_FICTION == b.getGenre(); List longNonFictionBooks = lambdaFilter(Setup.books, nflbFilter); We can rewrite it using streams: // stream based filters List longBooks = books.stream().filter(b -> b.getPages() > 400).collect(toList()); List longNonFictionBooks = books.stream().filter(b -> b.getPages() > 400 && Genre.NON_FICTION == b.getGenre()) .collect(toList()); The code is much cleaner now, because we don't need the lambdaFilter() method anymore. Let's see how it works.
  • 21. Functional Java8 in everyday life Streams List longBooks = books.stream().filter(b -> b.getPages() > 400).collect(toList()); What we've done is: • calling the stream() method on the collection, for trasforming it into a stream • calling the filter() method passing a Predicate, for filtering the elements of the stream dropping any/some of them • calling the collect() method with the static import toList() for collecting the filtered elements and put them into a List object
  • 22. Functional Java8 in everyday life Stream operations Operation Operation type Return type filter(Predicate<T>) intermediate Stream<T> map(Function <T, R>) intermediate Stream<R> flatMap(Function <T, R>) intermediate Stream<R> distinct() intermediate Stream<T> sorted(Comparator<T>) intermediate Stream<T> peek(Consumer<T>) intermediate Stream<T> limit(int n) intermediate Stream<T> skip(int n) intermediate Stream<T> reduce(BinaryOperator<T>) terminal Optional<T> collect(Collector<T, A, R>) terminal R forEach(Consumer<T>) terminal void min(Comparator<T>) terminal Optional<T> max(Comparator<T>) terminal Optional<T> count() terminal long anyMatch(Predicate<T>) terminal boolean allMatch(Predicate<T>) terminal boolean noneMatch(Predicate<T>) terminal boolean findFirst() terminal Optional<T> findAny() terminal Optional<T>
  • 23. Functional Java8 in everyday life Streams samples We need all the books with more than 400 pages.
  • 24. Functional Java8 in everyday life Streams samples We need all the books with more than 400 pages. Here's how: List<Book> longBooks = books.stream().filter(b -> b.getPages() > 400).collect(toList());
  • 25. Functional Java8 in everyday life Streams samples We need all the books with more than 400 pages. Here's how: List<Book> longBooks = books.stream().filter(b -> b.getPages() > 400).collect(toList()); We need the top three longest books.
  • 26. Functional Java8 in everyday life Streams samples We need all the books with more than 400 pages. Here's how: List<Book> longBooks = books.stream().filter(b -> b.getPages() > 400).collect(toList()); We need the top three longest books. Here's how: List<Book> top3LongestBooks = books.stream().sorted((b1,b2) -> b2.getPages()-b1.getPages()).limit(3).Collect( toList());
  • 27. Functional Java8 in everyday life Streams samples We need all the books with more than 400 pages. Here's how: List<Book> longBooks = books.stream().filter(b -> b.getPages() > 400).collect(toList()); We need the top three longest books. Here's how: List<Book> top3LongestBooks = books.stream().sorted((b1,b2) -> b2.getPages()-b1.getPages()).limit(3).Collect( toList()); We need from the fourth to the last longest books.
  • 28. Functional Java8 in everyday life Streams samples We need all the books with more than 400 pages. Here's how: List<Book> longBooks = books.stream().filter(b -> b.getPages() > 400).collect(toList()); We need the top three longest books. Here's how: List<Book> top3LongestBooks = books.stream().sorted((b1,b2) -> b2.getPages()-b1.getPages()).limit(3).Collect( toList()); We need from the fourth to the last longest books. Here's how: List<Book> fromFourthLongestBooks = books.stream().sorted((b1,b2) -> b2.getPages()-b1.getPages()).skip(3).collect(toList());
  • 29. Functional Java8 in everyday life Streams samples We need to get all the publishing years.
  • 30. Functional Java8 in everyday life Streams samples We need to get all the publishing years. Here's how: List<Integer> publishingYears = books.stream().map(b -> b.getYear()).distinct().collect(toList());
  • 31. Functional Java8 in everyday life Streams samples We need to get all the publishing years. Here's how: List<Integer> publishingYears = books.stream().map(b -> b.getYear()).distinct().collect(toList()); We need all the authors.
  • 32. Functional Java8 in everyday life Streams samples We need to get all the publishing years. Here's how: List<Integer> publishingYears = books.stream().map(b -> b.getYear()).distinct().collect(toList()); We need all the authors. Here's how: Set<Author> authors = books.stream().flatMap(b -> b.getAuthors().stream()).distinct().collect(toSet());
  • 33. Functional Java8 in everyday life Streams samples We need to get all the publishing years. Here's how: List<Integer> publishingYears = books.stream().map(b -> b.getYear()).distinct().collect(toList()); We need all the authors. Here's how: Set<Author> authors = books.stream().flatMap(b -> b.getAuthors().stream()).distinct().collect(toSet()); We need all the origin countries of the authors.
  • 34. Functional Java8 in everyday life Streams samples We need to get all the publishing years. Here's how: List<Integer> publishingYears = books.stream().map(b -> b.getYear()).distinct().collect(toList()); We need all the authors. Here's how: Set<Author> authors = books.stream().flatMap(b -> b.getAuthors().stream()).distinct().collect(toSet()); We need all the origin countries of the authors. Here's how: Set<String> countries = books.stream().flatMap(b -> b.getAuthors().stream()) .map(author -> author.getCountry()).distinct().collect(toSet());
  • 35. Functional Java8 in everyday life Optionals Let's start with an example: ISBN in 2007 has changed from 10 to 13 characters. To check which version of ISBN a book has we have to write: boolean isPre2007 = book.getIsbn().length() > 10; What if a book was published before 1970, when ISBN did not exist and the property ISBN is null? Without a proper check, NullPointerException will be thrown at runtime! Java 8 has introduced the java.util.Optional class. The code of our Book class can be now written as: public class Book { private List<Author> authors; private String title; private int pages; private Optional<String> Isbn; private Genre genre; private int year; }
  • 36. Functional Java8 in everyday life Optionals We can set the value with: book.setIsbn(Optional.of("978000000")); Or, if the book was published before 1970: book.setIsbn(Optional.empty()); Or, if we don't know the value in advance: book.setIsbn(Optional.ofNullable(value)); (in case value is null an empty Optional will be set) We can now get the value with: Optional<String> isbn = book.getIsbn(); System.out.println("Isbn: " + isbn.orElse("NOT PRESENT"); If the Optional contains an ISBN it will be returned, otherwise the string "NOT PRESENT" will be returned.
  • 37. Functional Java8 in everyday life Other streams samples We want the most recent published book.
  • 38. Functional Java8 in everyday life Other streams samples We want the most recent published book. Here's how: Optional<Book> lastPublishedBook = books.stream().min(Comparator.comparingInt(Book::getYear));
  • 39. Functional Java8 in everyday life Other streams samples We want the most recent published book. Here's how: Optional<Book> lastPublishedBook = books.stream().min(Comparator.comparingInt(Book::getYear)); We want to know if all the books are written by more than one author.
  • 40. Functional Java8 in everyday life Other streams samples We want the most recent published book. Here's how: Optional<Book> lastPublishedBook = books.stream().min(Comparator.comparingInt(Book::getYear)); We want to know if all the books are written by more than one author. Here's how: boolean onlyShortBooks = books.stream().allMatch(b -> b.getAuthors().size() > 1);
  • 41. Functional Java8 in everyday life Other streams samples We want the most recent published book. Here's how: Optional<Book> lastPublishedBook = books.stream().min(Comparator.comparingInt(Book::getYear)); We want to know if all the books are written by more than one author. Here's how: boolean onlyShortBooks = books.stream().allMatch(b -> b.getAuthors().size() > 1); We want one of the books written by more than one author.
  • 42. Functional Java8 in everyday life Other streams samples We want the most recent published book. Here's how: Optional<Book> lastPublishedBook = books.stream().min(Comparator.comparingInt(Book::getYear)); We want to know if all the books are written by more than one author. Here's how: boolean onlyShortBooks = books.stream().allMatch(b -> b.getAuthors().size() > 1); We want one of the books written by more than one author. Here's how: Optional<Book> multiAuthorBook = books.stream().filter((b -> b.getAuthors().size() > 1)).findAny();
  • 43. Functional Java8 in everyday life Streams samples We want the total number of pages published.
  • 44. Functional Java8 in everyday life Streams samples We want the total number of pages published. Here's how: Integer totalPages = books.stream().map(Book::getPages).reduce(0, (b1, b2) -> b1 + b2); Optional<Integer> totalPages = or: books.stream().map(Book::getPages).reduce(Integer::sum);
  • 45. Functional Java8 in everyday life Streams samples We want the total number of pages published. Here's how: Integer totalPages = books.stream().map(Book::getPages).reduce(0, (b1, b2) -> b1 + b2); Optional<Integer> totalPages = or: books.stream().map(Book::getPages).reduce(Integer::sum); We want to know how many pages the longest book has.
  • 46. Functional Java8 in everyday life Streams samples We want the total number of pages published. Here's how: Integer totalPages = books.stream().map(Book::getPages).reduce(0, (b1, b2) -> b1 + b2); Optional<Integer> totalPages = or: books.stream().map(Book::getPages).reduce(Integer::sum); We want to know how many pages the longest book has. Here's how: Optional<Integer> longestBook = books.stream().map(Book::getPages).reduce(Integer::max);
  • 47. Functional Java8 in everyday life The Collector interface The Collector interface was introduce to give developers a set of methods for reduction operations. Method Return type toList() List<T> toSet() Set<t> toCollection() Collection<T> counting() Long summingInt() Long averagingInt() Double joining() String maxBy() Optional<T> minBy() Optional<T> reducing() ... groupingBy() Map<K, List<T>> partioningBy() Map<Boolean, List<T>>
  • 48. Functional Java8 in everyday life Collector samples We want the average number of pages of the books.
  • 49. Functional Java8 in everyday life Collector samples We want the average number of pages of the books. Here's how: Double averagePages = books.stream().collect(averagingInt(Book::getPages));
  • 50. Functional Java8 in everyday life Collector samples We want the average number of pages of the books. Here's how: Double averagePages = books.stream().collect(averagingInt(Book::getPages)); We want all the titles of the books.
  • 51. Functional Java8 in everyday life Collector samples We want the average number of pages of the books. Here's how: Double averagePages = books.stream().collect(averagingInt(Book::getPages)); We want all the titles of the books. Here's how: String allTitles = books.stream().map(Book::getTitle).collect(joining(", "));
  • 52. Functional Java8 in everyday life Collector samples We want the average number of pages of the books. Here's how: Double averagePages = books.stream().collect(averagingInt(Book::getPages)); We want all the titles of the books. Here's how: String allTitles = books.stream().map(Book::getTitle).collect(joining(", ")); We want the book with the higher number of authors. Here's how: Optional<Book> higherNumberOfAuthorsBook = books.stream().collect(maxBy(comparing(b -> b.getAuthors().size())));
  • 53. Functional Java8 in everyday life Stream grouping We want a Map of book per year.
  • 54. Functional Java8 in everyday life Stream grouping We want a Map of book per year. Here's how: Map<Integer, List<Book>> booksPerYear = Setup.books.stream().collect(groupingBy(Book::getYear));
  • 55. Functional Java8 in everyday life Stream grouping We want a Map of book per year. Here's how: Map<Integer, List<Book>> booksPerYear = Setup.books.stream().collect(groupingBy(Book::getYear)); We want a Map of how many books are published per year per genre.
  • 56. Functional Java8 in everyday life Stream grouping We want a Map of book per year. Here's how: Map<Integer, List<Book>> booksPerYear = Setup.books.stream().collect(groupingBy(Book::getYear)); We want a Map of how many books are published per year per genre. Here's how: Map<Integer, Map<Genre, List<Book>>> booksPerYearPerGenre = Setup.books.stream().collect(groupingBy(Book::getYear, groupingBy(Book::getGenre)));
  • 57. Functional Java8 in everyday life Stream grouping We want a Map of book per year. Here's how: Map<Integer, List<Book>> booksPerYear = Setup.books.stream().collect(groupingBy(Book::getYear)); We want a Map of how many books are published per year per genre. Here's how: Map<Integer, Map<Genre, List<Book>>> booksPerYearPerGenre = Setup.books.stream().collect(groupingBy(Book::getYear, groupingBy(Book::getGenre))); We want to count how many books are published per year.
  • 58. Functional Java8 in everyday life Stream grouping We want a Map of book per year. Here's how: Map<Integer, List<Book>> booksPerYear = Setup.books.stream().collect(groupingBy(Book::getYear)); We want a Map of how many books are published per year per genre. Here's how: Map<Integer, Map<Genre, List<Book>>> booksPerYearPerGenre = Setup.books.stream().collect(groupingBy(Book::getYear, groupingBy(Book::getGenre))); We want to count how many books are published per year. Here's how: Map<Integer, Long> bookCountPerYear = Setup.books.stream().collect(groupingBy(Book::getYear, counting()));
  • 59. Functional Java8 in everyday life Stream partitioning We want to classify book by hardcover.
  • 60. Functional Java8 in everyday life Stream partitioning We want to classify book by hardcover. Here's how: Map<Boolean, List<Book>> hardCoverBooks = books.stream().collect(partitioningBy(Book::hasHardCover));
  • 61. Functional Java8 in everyday life Stream partitioning We want to classify book by hardcover. Here's how: Map<Boolean, List<Book>> hardCoverBooks = books.stream().collect(partitioningBy(Book::hasHardCover)); We want to further classify book by genre.
  • 62. Functional Java8 in everyday life Stream partitioning We want to classify book by hardcover. Here's how: Map<Boolean, List<Book>> hardCoverBooks = books.stream().collect(partitioningBy(Book::hasHardCover)); We want to further classify book by genre. Here's how: Map<Boolean, Map<Genre, List<Book>>> hardCoverBooksByGenre = books.stream().collect(partitioningBy(Book::hasHardCover,groupingBy(Book::getGenre)));
  • 63. Functional Java8 in everyday life Stream partitioning We want to classify book by hardcover. Here's how: Map<Boolean, List<Book>> hardCoverBooks = books.stream().collect(partitioningBy(Book::hasHardCover)); We want to further classify book by genre. Here's how: Map<Boolean, Map<Genre, List<Book>>> hardCoverBooksByGenre = books.stream().collect(partitioningBy(Book::hasHardCover,groupingBy(Book::getGenre))); We want to count books with/without hardcover.
  • 64. Functional Java8 in everyday life Stream partitioning We want to classify book by hardcover. Here's how: Map<Boolean, List<Book>> hardCoverBooks = books.stream().collect(partitioningBy(Book::hasHardCover)); We want to further classify book by genre. Here's how: Map<Boolean, Map<Genre, List<Book>>> hardCoverBooksByGenre = books.stream().collect(partitioningBy(Book::hasHardCover,groupingBy(Book::getGenre))); We want to count books with/without hardcover. Here's how: Map<Boolean, Long> count = books.stream().collect(partitioningBy(Book::hasHardCover, counting()));
  • 65. Functional Java8 in everyday life What we did not see: • Parallel streams • Streams methods for primitive types
  • 66. Functional Java8 in everyday life Thanks! The code is available on: https://github.com/andreaiacono/Java8