let if flow: java 8 streams puzzles and more
TRANSCRIPT
Let it flow Java 8 stream puzzles
and more Bhakti Mehta
@bhakti_mehta
Introduction O Senior Software Engineer at Blue Jeans
Network O Worked at Sun Microsystems/Oracle for 13
years O Committer to numerous open source projects
including GlassFish Application Server
My recent book
Previous book
Blue Jeans Network
Evolution of Java O Java 8 has myriad of features O Most prominent are lamdas and streams API O Functional style to Java
Streams O Abstraction not a datastructure O Can transform data O Value in motion O Functional style will affect all collections O Automatic parallelism
Collections in Java 8
Contains whole data structure Eager computation
Streams in Java 8
Computed on demand Just in time Lazily constructed collection
Stream or loop GET the shortest list of cities of people Instead of List people = … Set shortCities = new HashSet<>(); for (Person p : people) { City c = p.getCity(); if (c.getName().length() < 5 ) { shortCities.add(c); }
Stream or loop We write List people = … Set shortCities = people.stream() .map(Person::getCity) .filter(c -> c.getName().length() < 5) .collect(toSet());
Stream or loop We write List people = … Set shortCities = people.stream() .map(Person::getCity) .filter(c -> c.getName().length() < 5) .collect(toSet());
More concise
More readable Composable
operations Can be made parallel
Power of Stream O Streams provide the power to write compose
functions and data flows through the functions
Components when working with streams
Intermediate operations
filter map
limit sorted
distinct
Terminal operations
forEach
collect
reduce
Map
function
FlatMap
FlatMap sample public class Teammate { private Set<String> languages; Set<String> getLanguages() { return languages; } List<Teammate> team = new ArrayList<>(); Teammate dev1 = new Teammate(); dev1.addLanguage("scala"); dev1.addLanguage(“go”); Teammate dev2 = new Teammate(); dev2.addLanguage("java"); team.add(dev1); team.add(dev2);
FlatMap sample List<String> teamLanguages = team.stream(). map(d -> d.getLanguages()). flatMap(l -> l.stream()). collect(Collectors.toList()); returns [“scala”,”go”,”java”]
Quiz
Given a list of numbers return the Squares
Given [1,2,3,4] return [1,4,9,16]
Quiz Given a list of numbers return the Squares
Given [1,2,3,4] return [1,4,9,16]
List<Integer>numbers = Arrays.asList(1,2,3,4);
List<Integer> squares = numbers.stream().map
(n->n*n).collect(toList());
Filter
Shape:: isSquare()
Group Grouping
map
Fish Reptiles Mammals
Group Grouping
map
Fish Reptiles Mammals
Stream
Dolphin
Classify
Grouping Map<Animal.Category, List<Animal>> animalsByCategory = animals.stream(). collect(groupingBy(Animal::getCategory)); {Mammals=[Dolphin, Cat, Dog], Fish=[Ray, Shark], Reptiles=[Alligator, Crocodile]}
Getting a count Map<Animal.Category, List<Animal>> animalsByCategory = animals.stream(). collect(groupingBy(Animal::getCategory, counting())); {Mammals=2, Fish=2, Reptiles=2}
I
Imperative style Iterate through the animals Classify in various categories Get counts of each
cumbersome
Verbose
Partitioning
Map<Boolean, List<Item>> partitionedMenu = menu.stream().collect (partitioningBy(Item::isSeaFood)); { false= [brocolli chicken, orange chicken], true=[spicy shrimp, catfish]}
Getting seafood from the menu
Via Filtering List<Item> seafood = menu.stream().filter (Item::isSeaFood).collect(toList()); gives [spicy shrimp, catfish]
Multilevel partitioning partitioningBy collector can be used in combination with other partioningBy collections to get multi level partitioning
Quiz Is this valid sample?
menu.stream().collect
(partitioningBy
(Item::isSeaFood()
,partitioningBy
(d->d.getCalories()>500)));
Quiz Is this valid sample?
menu.stream().collect
(partitioningBy
(Item::isSeaFood()
,partitioningBy
(d->d.getCalories()>500)));
Composability O Get the unique surnames in uppercase of the
first 15 book authors that are 50 years old or older
O library.stream() .map(book -> book.getAuthor()) .filter(author -> author.getAge() >= 50) .limit(15) .map(Author::getSurname) .map(String::toUpperCase) .distinct() .collect(toList()));
Infinite stream O Stream<Integer> evenNumbers =
Stream.iterate(0, n -> n + 2);
Parallel streams O Parallel streams = simple concurrency O Parallel stream splits its elements in multiple
chunks processing each chunk on a different thread
O Potentially can use N cores => Nx speedup
Parallel Streams O Check the benchmark using sequential and
parallel streams O Limit and findFirst may be expensive in
parallel stream as they rely on the odrder of the elements. Use findAny if you are not constrained by the order
Summary O Great step by Java 8 towards supporting FP O Use FP and OoP together
Use Streams and prosper
Resources O http://blog.fileburst.com/wp-content/
uploads/2012/10/Online-Streaming-Movies.png
O http://zeroturnaround.com/rebellabs/java-8-streams-cheat-sheet/
Questions O Twitter: @bhakti_mehta