Slide 1

Slide 1 text

Java 8: Lambdas and Collection Handling Lukasz Wrobel

Slide 2

Slide 2 text

About me • Software architect, team leader • Recruiter, teacher • High-traffic, scalable systems • lukaszwrobel.pl / @lukaszwrobel • eBook: „Memoirs of a Software Team Leader”

Slide 3

Slide 3 text

New features • To me—the first breakthrough since generics. • Lambdas • @FunctionalInterface • default methods

Slide 4

Slide 4 text

Implications • Readable collection operations • other languages:
 Ruby (→ Groovy), Scala, Clojure • DSLs • Parallelism

Slide 5

Slide 5 text

Collections
 +
 lambdas A matter of personal importance to me

Slide 6

Slide 6 text

Event handling

Slide 7

Slide 7 text

At best—anonymous inner class final Button button = (Button) findViewById(R.id.button_id); button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // Perform action on click } });

Slide 8

Slide 8 text

How about a cleaner syntax? final Button button = (Button) findViewById(R.id.button_id); button.setOnClickListener((View v) -> { // Perform action on click });

Slide 9

Slide 9 text

Collection manipulation

Slide 10

Slide 10 text

Old approach private static int sumOfSquaresGreaterThan50(List numbers) { Iterator it = numbers.iterator(); int sum = 0; while (it.hasNext()) { int number = it.next(); int square = Math.pow(number, 2); if (square > 50) { sum += square; } } return sum; }

Slide 11

Slide 11 text

Stream API private static int sumOfSquaresGreaterThan50(List numbers) { return numbers .stream() .mapToInt(number -> Math.pow(number, 2)) .filter(square -> square > 50) .sum(); }

Slide 12

Slide 12 text

Intermediate vs. terminal Finish right now or add another operations the chain?

Slide 13

Slide 13 text

Terminal operations • forEach[Ordered] • toArray • sorted • reduce • collect • min, max, sum • count • [any|all|none]Match • find[First|Any]

Slide 14

Slide 14 text

Domain: cars

Slide 15

Slide 15 text

Common use cases

Slide 16

Slide 16 text

Filter public static List getInsurancedCars(ArrayList cars) { return cars .stream() .filter(car -> car.isInsuranced()) .collect(Collectors.toList()); }

Slide 17

Slide 17 text

Method reference public static List getInsurancedCars(ArrayList cars) { return cars .stream() .filter(Car::isInsuranced) .collect(Collectors.toList()); }

Slide 18

Slide 18 text

Map public static List getPlates(ArrayList cars) { return cars .stream() .map(Car::getPlates) .collect(Collectors.toList()); }

Slide 19

Slide 19 text

Max public static int getTheBiggestPrice(ArrayList cars) { return cars .stream() .max(Car::getPrice); // Terminal operation }

Slide 20

Slide 20 text

Primitives → Performance public static int getAverageNumberOfSeats(ArrayList cars) { return cars .stream() .mapToInt(Car::getNumberOfSeats) .average(); } getAverageNumberOfSeats(allCarsInTheEntireUniverse);

Slide 21

Slide 21 text

Variable capturing Either final or effectively final

Slide 22

Slide 22 text

Final final Car car = new AMG("WQ 42684"); button.setOnClickListener((View v) -> { displayMessage("Plates: " + car.getPlates()); });

Slide 23

Slide 23 text

Effectively final Car car = new AMG("WQ 42684"); car = new Fiat126P("DFB 93453"); button.setOnClickListener((View v) -> { displayMessage("Plates: " + car.getPlates()); });

Slide 24

Slide 24 text

Lambda type

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

Inline? public class Scrapyard { public List scrap( List cars, (Car -> ScrapMetal) scrapper) { // Scrap all the given cars } }

Slide 27

Slide 27 text

What about type reuse?

Slide 28

Slide 28 text

@FunctionalInterface @FunctionalInterface public interface Scrapper { ScrapMetal scrap(Car car); }

Slide 29

Slide 29 text

Functional interface applied public class Scrapyard { public List scrap( List cars, Scrapper scrapper) { // Scrap all the given cars } }

Slide 30

Slide 30 text

Useful functional interfaces Name Arguments Return type Function T R Predicate T boolean UnaryOperator T T BinaryOperator T, T T Supplier - T Consumer T void

Slide 31

Slide 31 text

Default methods Binary compatibility Java 8 → 7 → … 1

Slide 32

Slide 32 text

„default” keyword public interface AirConditioned { default void coolTheInterior() { // Perform the cooling process } } public class Fiat126P implements AirConditioned { // Thanks to the "default" keyword, Fiat 126p // is now being air-conditioned. }

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

„default” precedence class > interface subtype > supertype (interfaces extending other interfaces)

Slide 35

Slide 35 text

Parallelism

Slide 36

Slide 36 text

Effortless public static int getAverageNumberOfSeats(ArrayList cars) { return cars .parallelStream() .mapToInt(Car::getNumberOfSeats) .average(); } getAverageNumberOfSeats(allCarsInTheEntireUniverse);

Slide 37

Slide 37 text

However…

Slide 38

Slide 38 text

Amdahl’s law The speedup of a program using multiple processors in parallel computing is limited by the time needed for the sequential fraction of the program. http://en.wikipedia.org/wiki/Amdahl%27s_law

Slide 39

Slide 39 text

Is it worth it? • Number of elements:
 large enough? • Time spent processing each element:
 substantial? • Performance tests.

Slide 40

Slide 40 text

Data structure splitting Performance Access type Example Good random ArrayList Bad sequential LinkedList

Slide 41

Slide 41 text

State Performance State Example Good stateless filter Bad stateful sorted

Slide 42

Slide 42 text

How is your life going to change?

Slide 43

Slide 43 text

DSLs public class HelloWorld { public static void main(String[] args) { get("/hello", (req, res) -> „Hello, World!”); } }

Slide 44

Slide 44 text

Caching— the old way public Car getCarCached(Plate plate) { Map cache = this.getCarCache(); Car car = cache.get(plate); if (car == null) { car = this.getCarFromDatabase(plate); cache.put(plate, car); } return car; }

Slide 45

Slide 45 text

Convenience public Car getCarCached(Plate plate) { return this.getCarCache() .computeIfAbsent(plate, this::getCarFromDatabase); }

Slide 46

Slide 46 text

Thanks for listening!