java lambdas and (parallel) streamssamples.leanpub.com/lambdas-sample.pdf ·...

23

Upload: others

Post on 16-Jul-2020

7 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Java Lambdas and (parallel) Streamssamples.leanpub.com/lambdas-sample.pdf · Firstanalysis-fromnaivetoflexible 8 ImplementationoftheconditionaccordingtointerfaceCondition 1 class
Page 2: Java Lambdas and (parallel) Streamssamples.leanpub.com/lambdas-sample.pdf · Firstanalysis-fromnaivetoflexible 8 ImplementationoftheconditionaccordingtointerfaceCondition 1 class

Java Lambdas and (parallel) StreamsThe compact starter: Foundation, supporting structures,parallel processing

Michael Müller

This book is for sale at http://leanpub.com/lambdas

This version was published on 2016-08-09

This is a Leanpub book. Leanpub empowers authors and publishers with the LeanPublishing process. Lean Publishing is the act of publishing an in-progress ebook usinglightweight tools and many iterations to get reader feedback, pivot until you have the rightbook and build traction once you do.

© 2015 - 2016 Michael Müller

Page 3: Java Lambdas and (parallel) Streamssamples.leanpub.com/lambdas-sample.pdf · Firstanalysis-fromnaivetoflexible 8 ImplementationoftheconditionaccordingtointerfaceCondition 1 class

Tweet This Book!Please help Michael Müller by spreading the word about this book on Twitter!

The suggested tweet for this book is:

I just purchased ”Lambdas and (parallel) Streams” by @muellermi.https://leanpub.com/lambdas

The suggested hashtag for this book is #LambdasAndStreams.

Find out what other people are saying about the book by clicking on this link to search forthis hashtag on Twitter:

https://twitter.com/search?q=#LambdasAndStreams

Page 4: Java Lambdas and (parallel) Streamssamples.leanpub.com/lambdas-sample.pdf · Firstanalysis-fromnaivetoflexible 8 ImplementationoftheconditionaccordingtointerfaceCondition 1 class

Also By Michael MüllerWeb Development with Java and JSF

Java Lambdas und (parallel) Streams

Page 5: Java Lambdas and (parallel) Streamssamples.leanpub.com/lambdas-sample.pdf · Firstanalysis-fromnaivetoflexible 8 ImplementationoftheconditionaccordingtointerfaceCondition 1 class

Contents

Preliminary note . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i

Cover image . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ii

Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii

About the Author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv

About this book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . viConventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . viLinks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . viiErrors and typos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . viiCopyright . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii

1. Inroduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.1 Lambdas and (Parallel) Streams . . . . . . . . . . . . . . . . . . . . . . . . 11.2 The challenge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.3 The solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.4 A first explanation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

2. The data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

3. First analysis - from naive to flexible . . . . . . . . . . . . . . . . . . . . . . . 53.1 Fix filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53.2 Simple parameterization . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53.3 Behavior parameterization . . . . . . . . . . . . . . . . . . . . . . . . . . . 73.4 Anonymous classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

4. Lambda expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

5. Additional chapters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

Page 6: Java Lambdas and (parallel) Streamssamples.leanpub.com/lambdas-sample.pdf · Firstanalysis-fromnaivetoflexible 8 ImplementationoftheconditionaccordingtointerfaceCondition 1 class

Preliminary noteWhenever I have spoken about Java Lambdas and Streams at conferences and round tableevents there has been strong interest and lively discussions with the attendees. Typicallythe unfamiliar syntax forms a significant hurdle even (or especially?) for experiencedprogrammers. However, once a developer masters the syntax, he / she usually doesn’t wantto revert to the pre-lambda style.

Realising that the new syntax is an impediment for many developers I decided to share myexperience and insights in a format that can be used as a reference. The aim of this concisebook is to help you to overcome the learning curve and to master the new world of Lambdasand Streams.

Following Leanpub’s motto “Publish early, publish often” I published this first edition inan early but complete state. Purchasers may look forward to downloading all updates orsupplements that may become available in the future.

I hope that you enjoy reading it and achieve sustained success with Java Lambdas and ParallelStreams.

Michael Müller

Brühl, Germany, December 2015

i

Page 7: Java Lambdas and (parallel) Streamssamples.leanpub.com/lambdas-sample.pdf · Firstanalysis-fromnaivetoflexible 8 ImplementationoftheconditionaccordingtointerfaceCondition 1 class

Cover imageEvery line of red elements represents a stream of objects. The multitude of lines stands forthe parallelizm of these streams.

In this respect, the title page symbolizes a central topic of this book: The parallel processingusing streams. And without lambda statements, this is unimaginable.

ii

Page 8: Java Lambdas and (parallel) Streamssamples.leanpub.com/lambdas-sample.pdf · Firstanalysis-fromnaivetoflexible 8 ImplementationoftheconditionaccordingtointerfaceCondition 1 class

Acknowledgements

To my wife Claudia and my kids:

Thank you for your patience during night-writing and other long sessions.

I love you.

To the may people I conversed at conferences as well as attendees of my talks:

Thank you for the informative and interesting conversations. Thereby I recognized, howimportant the matter of Java Lambdas and Streams is for you and how much information

demand exists. Without you, this book would not be written.

To you, my dear reader:

Thank you for interest in this book. I hope, I could write an understandable and valuablebook, which helps you to success.

iii

Page 9: Java Lambdas and (parallel) Streamssamples.leanpub.com/lambdas-sample.pdf · Firstanalysis-fromnaivetoflexible 8 ImplementationoftheconditionaccordingtointerfaceCondition 1 class

About the AuthorMichael Müller is an IT professional with more than 30 years of experience including about25 years in the healthcare sector. During this time, he has worked in different areas, especiallyproject and product management, consulting, and software development. During a couple ofSoftware development project, he also could gain intensive international experience.

Michael Müller

Currently, he is the head of software development at the German DRG institute inek.org¹. Inthis role, he is responsible for Web applications as well as other Java and .NET projects. Webprojects are preferably built with Java technologies such as JSF with the help of supportinglanguages like JavaScript.

Michael has a strong experience using lambda statements the .Net environment (LINQ withC#). Beginning with Java 8, he finally can use similar powerful features with Java.

Michael is a JSF professional user and a member of the JSR 344 and JSR 372 (JSF) expertgroups. His first book Web Development with Java and JSF² consequential deals with thisJava web technology.

He frequently reads books and writes reviews as well as technical papers, which are mostly

¹http://inek.org²https://leanpub.com/jsf

iv

Page 10: Java Lambdas and (parallel) Streamssamples.leanpub.com/lambdas-sample.pdf · Firstanalysis-fromnaivetoflexible 8 ImplementationoftheconditionaccordingtointerfaceCondition 1 class

About the Author v

published in German-printed magazines and on his website at it-rezension.de³. Besides that,he irregular blogs about software development at blog.mueller-bruehl.de⁴.

³http://it-rezension.de⁴http://blog.mueller-bruehl.de

Page 11: Java Lambdas and (parallel) Streamssamples.leanpub.com/lambdas-sample.pdf · Firstanalysis-fromnaivetoflexible 8 ImplementationoftheconditionaccordingtointerfaceCondition 1 class

About this bookLambdas and Streams are language elements that have been found their way into the Javaworld with version 8. This book wants to introduce in their concepts in a concise form.

For this purpose it is necessary to introduce a couple of new supporting features like func-tional interfaces, default methods and more. Once introduced, streams can be parallelizedin a very simple way - within certain limits, no knowledge about the thread managementis needed. This will be handled transparently behind the scenes. Nevertheless, some basicthings in the context of parallelism need to be considered. Here, the book provides a varietyof information from practice.

The aim of the book is therefore, to provide all relevant information around the topic JavaLambdas and (parallel) Streams. With this book, you should be able to use this technologyin your own projects. You are invited to report how well this has been possible and to sendfeedback to the author!

Conventions

Information boxThis symbol is used to indicate important information.

This is a WarningCommon pitfalls or other mentionable warnings will be marked by this symbol.

ExerciseThis symbol indicates a short exercise, you might perform to get some morepractice.

vi

Page 12: Java Lambdas and (parallel) Streamssamples.leanpub.com/lambdas-sample.pdf · Firstanalysis-fromnaivetoflexible 8 ImplementationoftheconditionaccordingtointerfaceCondition 1 class

About this book vii

Links

During this book you’ll find a lot of useful links, pointing to further or additional information.All these links have been checked by the author at the time of writing. Since these links pointto external resources that might be changed at any time by the appropriate content owner,a link might not be valid any more or does not point to the expected information. If youdiscover such an invalid link, please contact the author of this book to enable a correction.

Errors and typos

All information for this book have been faithful researched or developed. However, therecan’t be any guarantee of being be error-free. If you discover errors or typos, please informthe author.

Copyright

This book is written by Michael Müller and protected by copyright.

For your private, non-commercial usage, feel free to use your copy of this book and thedownloadable source code.

For commercial or educational usage, please contact the author.

Page 13: Java Lambdas and (parallel) Streamssamples.leanpub.com/lambdas-sample.pdf · Firstanalysis-fromnaivetoflexible 8 ImplementationoftheconditionaccordingtointerfaceCondition 1 class

1. Inroduction

1.1 Lambdas and (Parallel) Streams

Some of the new features introduced in Java 8, like the new Date and Time API, feel quitefamiliar and can be used immediately by an experienced Java developer. But some of themost important enhancements, including Lambdas and Streams, require the developer tolearn some new concepts. Lambda statements in particular introduce a syntax which is quiteunusual for object oriented programmers. These language constructs are known only todevelopers who used functional programming languages or enhancements like Microsoft’sLinq. This special syntax takes some getting used to and some developers may even be alittle frightened at first glance. However, these enhancements are extremely powerful and itis certainly worth taking the time to understand how they can help you to write code that isnot only concise, but also faster to write and more re-usable.

This book starts with an explanation of Lambda expressions, shows how they can be usedwith Streams and finally discusses how both Lambdas and Streams can be combined toimplement effective parallel processing.

The following task will run like a golden thread through the book:

1.2 The challenge

• Analyze a bigger amount of data according to varying criteria• Parallelize this task without explicit use of thread management, synchronization,Excecutor or ForkJoin

1.3 The solution

Use parallelStream() instead of stream()!

1

Page 14: Java Lambdas and (parallel) Streamssamples.leanpub.com/lambdas-sample.pdf · Firstanalysis-fromnaivetoflexible 8 ImplementationoftheconditionaccordingtointerfaceCondition 1 class

Inroduction 2

1.4 A first explanation

You may well ask “what the hell are the stream() and parallelStream() methods?” Here is thequick overview; a more detailed description is given in later chapters.

You may imagine a Stream as a continuous flow of data, comparable to something likean InputStream. The data might be emitted by different sources, like a collection, a file, agenerator, or some other source. However, the content of this stream is not simply bytes orcharacters; instead the stream emits arbitrary objects.

Stream (Quelle is German for source)

On their journey from source to target, the objects may be filtered, changed, transformed,collected or processed in some other way. How and with whichever means this happen willbe described later on.

A ParallelStream can be imagined as a parallel stream of objects of the same type. The objectsare split into different streams at their source. Later on, we will discuss the details of thissplitting task.

Parallel Streams

To implement solutions to our challenge we will use some of Java’s new language featuresincluding:

• Lambda statements

Page 15: Java Lambdas and (parallel) Streamssamples.leanpub.com/lambdas-sample.pdf · Firstanalysis-fromnaivetoflexible 8 ImplementationoftheconditionaccordingtointerfaceCondition 1 class

Inroduction 3

• Functional Interfaces• Default methods• Optionals• Streams• Operations on streams

Page 16: Java Lambdas and (parallel) Streamssamples.leanpub.com/lambdas-sample.pdf · Firstanalysis-fromnaivetoflexible 8 ImplementationoftheconditionaccordingtointerfaceCondition 1 class

2. The dataBack to the challenge.

Data about a large number of persons who buy and sell diverse products shall be analyzed.The data structure for this task has a simple design: A person has a given name, surame, ageand gender. A buyer might also be a vendor. Sales and purchases are stored in lists. Eachelement in this list represents a product by it’s article number, the quantity sold and the unitprice. The unit price may change per transaction due to various discounts. The followingdiagram visualizes the class Person.

Class Person

In the appendix you’ll find a simple program to create sample data.

4

Page 17: Java Lambdas and (parallel) Streamssamples.leanpub.com/lambdas-sample.pdf · Firstanalysis-fromnaivetoflexible 8 ImplementationoftheconditionaccordingtointerfaceCondition 1 class

3. First analysis - from naive to flexibleIn this section we will develop traditional solutions to various filtering requirements. Weavoid using Lambdas or Streams so that the techniques illustrated here can be comparedwith the solutions developed in Chapter 4.

3.1 Fix filter

The first task is to list all customers who are less than 20 years old. This can be done veryeasily; all we need is a loop with a filter condition to select young customers and a target listto collect them.

Simple implementation to select and collect persons younger then 20 years

1 private List<Person> getPersonsLessThan20Years(List<Person> persons){

2 List<Person> result = new ArrayList<>();

3 for (Person person : persons) {

4 if (person.getAge() < 20) {

5 result.add(person);

6 }

7 }

8 return result;

9 }

3.2 Simple parameterization

The next requirement is to collect the group of people between 30 and 40 years old. Of course,we realize that in the future we may need to query different age groups and so it would bebetter to parameterize the method rather than hard coding the condition.

5

Page 18: Java Lambdas and (parallel) Streamssamples.leanpub.com/lambdas-sample.pdf · Firstanalysis-fromnaivetoflexible 8 ImplementationoftheconditionaccordingtointerfaceCondition 1 class

First analysis - from naive to flexible 6

Parameterized implementation to choose all persons of a specified age group

1 private List<Person> getPersonsByAgeRange(

2 List<Person> persons,

3 int from,

4 int to) {

5 List<Person> result = new ArrayList<>();

6 for (Person person : persons) {

7 if (person.getAge() >= from && person.getAge() <= to) {

8 result.add(person);

9 }

10 }

11 return result;

12 }

Here, the developer has introduced some flexibility. However, this method still does no morethan select persons of a specified age group. If additional criteria are needed, like queryingthe gender, this method doesn’t help. A novice programmer might try to solve the problemby adding extra parameters for gender, vendor status etc.

overloading a method with (too) many parameters

1 private List<Person> getPersonsByDiverseCriteria(

2 List<Person> persons,

3 int ageFrom,

4 int ageTo,

5 Gender gender,

6 boolean isCustomer,

7 boolean isVendor) {

8 [loop omitted]

9 }

Senior developers might shake their heads at such naive code; their experience tells themthat one day you won’t be able to do your analysis because you will need at least one moreparameter.

Page 19: Java Lambdas and (parallel) Streamssamples.leanpub.com/lambdas-sample.pdf · Firstanalysis-fromnaivetoflexible 8 ImplementationoftheconditionaccordingtointerfaceCondition 1 class

First analysis - from naive to flexible 7

3.3 Behavior parameterization

The next evolutionary step towards a better solution is to create the condition or filter as astand-alone object and to pass it to the now more general purpose method. This allows themethod to be parameterized with different behavior, or different algorithms, reminding usof the strategy pattern.

For our task this behavior will implement an interface which contains a test to choose aperson by a specified condition. Let’s call this interface Condition.

Interface Condition

1 public interface Condition<T> {

2 boolean test(T t);

3 }

Now our method (the loop) needs only two parameters, the list of persons and the condition.

Flexible filtering due to injectable condition

1 private List<Person> getPersonsByCondition(List<Person> persons, \

2

3 Condition<Person> condition){

4 List<Person> result = new ArrayList<>();

5 for (Person person : persons) {

6 if (condition.test(person)) {

7 result.add(person);

8 }

9 }

10 return result;

11 }

The condition is swapped out and will be injected by a parameter. Thus, there is no need tochange the implementation of the method when we need a different filter. Now let’s refactorour first analysis to get everyone less than 20 years old.

Page 20: Java Lambdas and (parallel) Streamssamples.leanpub.com/lambdas-sample.pdf · Firstanalysis-fromnaivetoflexible 8 ImplementationoftheconditionaccordingtointerfaceCondition 1 class

First analysis - from naive to flexible 8

Implementation of the condition according to interface Condition

1 class YoungerThanCondition implements Condition<Person>{

2 private final int _age;

3 YoungerThanCondition(int age){

4 _age = age;

5 }

6

7 @Override

8 public boolean test(Person person) {

9 return person.getAge() < _age;

10 }

11 }

Now, the code to call our loop and to inject the filter looks more clean and concise.

Call loop with filter

1 persons = getPersonsByCondition(persons, new YoungerThanCondition(20));

Following the object oriented paradigm we pass the condition to the method as an object.Now, if we need other filter criteria, we simply create different filter classes as implementa-tions of theCondition interface. The loop to collect the persons of interest remains unchanged.

3.4 Anonymous classes

But creating a separate class for each different condition still seems to be a heavyweightapproach. The question is: “If we only need to use the condition in one place can we createthe class just where we’ll need it?” This is where anonymous classes come into play.

Page 21: Java Lambdas and (parallel) Streamssamples.leanpub.com/lambdas-sample.pdf · Firstanalysis-fromnaivetoflexible 8 ImplementationoftheconditionaccordingtointerfaceCondition 1 class

First analysis - from naive to flexible 9

Parameterize with anonymous class

1 persons = getPersonsByCondition(persons, new Condition<Person>(){

2 @Override

3 public boolean test(Person person) {

4 return person.getAge() < 20;

5 }

6 });

Since the anonymous class is just created where it is needed, we can’t re-use it. It doesn’tmake sense to pass the age as parameter, we simply write it directly into the condition.

Compared with the fully-fledged filter classes, anonymous classes are much shorter. But,instead of passing a short class name as parameter, we have to override the test method andto write a couple of lines. Anonymous classes are shorter than fully-fledged classes, but movethe code into the parameter; this may not seem ideal. And by the way - lots of programmersdislike anonymous classes.

Page 22: Java Lambdas and (parallel) Streamssamples.leanpub.com/lambdas-sample.pdf · Firstanalysis-fromnaivetoflexible 8 ImplementationoftheconditionaccordingtointerfaceCondition 1 class

4. Lambda expressionsAfter all these traditional approaches it’s time to move on to the lambda expressions, whichhave been introduced into Java 8.

Book contentHere, the book starts to explain lambda expressions. Not only this, it introduces into otherenhancements like default methods, optional and finally streams. And last but not leastparallel streams.

You may take a look into the full table of content on the book web site to suffer what thisbook is all about.

Enjoy reading!

10

Page 23: Java Lambdas and (parallel) Streamssamples.leanpub.com/lambdas-sample.pdf · Firstanalysis-fromnaivetoflexible 8 ImplementationoftheconditionaccordingtointerfaceCondition 1 class

5. Additional chaptersBe pleased about additional topics in future editions - pardon, updates - of this book. GladlyI like to respect your suggestions.

Remember, this is a “living” book. Once you purchased it, all future updates are available fordownload to you.

11