Let if flow: Java 8 Streams puzzles and more

Preview:

Citation preview

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

Recommended