MEAP Edition
Manning Early Access Program
Java 8 in Action: Lambdas, Streams and Functional-style Programming
Version 3
Copyright 2014 Manning Publications
For more information on this and other Manning titles go to www.manning.com
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
http://www.manning-sandbox.com/forum.jspa?forumID=881
Welcome
Thank you for purchasing the MEAP for Java 8: Lambdas in Action. We're excited to see the
book reach this stage, and look forward to its continued development and eventual release.
This is a book for Java programmers of all levels, designed to explain the new features in
Java 8—not only the ideas themselves, but also the changing computing background (multi-
core computers, cloud computing, big data) which has caused Java to evolve.
We've striven to make the content both approachable and meaningful: we include many
code examples, quizzes, and real-world use cases to help you start using the new features as
quickly as possible. In addition, we explain not just how to do things in Java 8, but also why
things are done the way they are.
We’re releasing the first three chapters to start. Chapter 1 explains how programming
languages form an eco-system, and how Java has to evolve or risk being marginalized like
other once-popular languages. We see how this evolution is driven by the need to exploit
multi-core computers more simply; it also summarizes, in broad-brush terms, the changes to
Java (lambdas, method references, streams and default methods). Chapters 2 and 3 give a
full explanation, with code examples and quizzes at every step, of the idea of lambda
expressions and method references (passing “code” as an argument to another method). By
the end of Chapter 3 you will have a full understanding of what lambda expressions are, and
will be able to write code that is both concise and flexible enough to easily adapt to changing
requirements.
Chapter 4 and 5, to be released in the next month, explore the new Stream API and its
emphasis on writing powerful code in a few lines, similarly to how we do things in SQL.
Chapter 6 covers the idea of “parallelism almost for free,” using parallel Streams and exploring
how you can make use of the new Java 8 features to write code that can execute rapidly on
multicore architectures.
Looking ahead, Part 3 (Chapters 7-9) shows how you can improve your existing code using
new Java 8 features and a few recipes. In addition, it explores vital software development
techniques such as testing, debugging and refactoring specifically for Java 8.
Part 4 (Chapters 10-12) stands back a little and gives a tutorial introduction to writing
effective functional-style programs in Java, along with an introduction to Scala and Clojure,
two Java-like languages which share the same JVM as Java and which, if Java chose not to
evolve, would continue to nibble away stealing its user-base.
As you’re reading, we hope you’ll take advantage of the Author Online forum. We’ll be
reading your comments and responding—your feedback is helpful in the development process
and we thank you in advance for it.
— Raoul-Gabriel Urma, Mario Fusco, Alan Mycroft
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
http://www.manning-sandbox.com/forum.jspa?forumID=881
brief contents
PART I: FUNDAMENTALS
1 Java 8: why should you care?
2 Passing code with behavior parameterization
3 Lambda expressions
PART II: FUNCTIONAL-STYLE DATA PROCESSING
4 Processing data with streams
5 Collecting data with streams
6 Parallel data processing and performance
PART III: EFFECTIVE JAVA 8 PROGRAMMING
7 Tools, testing, debugging
8 Default methods
9 Optional: a better alternative to null
10 CompletableFuture: composable asynchronous programming
PART IV: BEYOND JAVA 8
11 Functional programming: tying the pieces together
12 Scala
13 What the future holds
APPENDICES:
A New Java 8 time API
B Other Java 8 niceties
C How are lambdas implemented?
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
http://www.manning-sandbox.com/forum.jspa?forumID=881
1
Java 8: why should you care?
This chapter covers:
• Why are they changing Java again?
• The changing computing background (big data, multicore, cloud computing).
• The pressure for Java to evolve: new architectures favor a functional-like style rather
than the original Java imperative style.
• A brief summary of the new features in Java 8: lambda expressions, streams, default
methods.
Since the release of JDK 1.0 (Java 1.0) in 1996, Java has won a large following of students,
project managers, and programmers who are active users. It’s an expressive language and
continues to be used for projects both large and small. Its evolution (via the addition of new
features) from Java 1.1 (1997) to Java 7 (2011) has been well managed. And now Java 8 is
to appear in 2014. So the question is, Why should you care about Java 8?
• Perhaps your boss has decreed that some new project will use Java 8 (and you wish
people would just stop messing with languages and let you get on with your job as a
Java programmer).
• Perhaps you’ve heard that Java 8 makes it easier to exploit more of the multiple CPUs
on your desktop or laptop computer.
• Perhaps you’ve heard that Java 8 makes it easier to write in simple broad-brush
strokes using higher-level ideas.
Even if you fall into the first category and just want to know what’s new in Java 8, we beg
your indulgence. We spend just two pages wondering why languages evolve and then turn to
the tectonic forces causing the evolution to Java 8. These can be summarized as multicore
CPUs, big data, and the fact that programmers have learned new programming techniques
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
http://www.manning-sandbox.com/forum.jspa?forumID=881
1
using other languages (for example, why is so much easier to process data in databases
using SQL than Java?).
We then introduce each new idea (passing code, lambdas, streams, and default methods)
in a tutorial style—covering background so you can see why the developments happen but
also giving simple initial examples to be developed in more detail in successive chapters.
We argue that the changes to Java 8 are in many ways more profound than any other
change to Java in its 14-year history, with the possible exception of generics (using List
instead of List).
The big picture is this: commodity CPUs have become multicore; the processor in your
laptop or desktop machine probably has eight or so CPU cores within it. But the vast majority
of Java programs use only one of these cores and leave the other seven idle (or doing
something unrelated such as running part of the operating system or as a virus checker).
Although previous versions of Java made small-scale concurrency possible (threads,
synchronized classes), Java 8 has a new, simpler way of thinking about parallelism. Java 8
provides a new API (called Streams) that supports many parallel operations to process data
and resembles the way you might think in SQL. As result, it avoids the need for you to write
code that uses synchronized, which is not only highly error prone but is also more
expensive than programmers often realize on multicore CPUs. The addition of Streams in
Java 8 can be seen as a direct cause of the two other additions to Java 8: techniques to pass
code to methods (method references, lambdas) and default methods in interfaces.
But thinking of passing code to methods as a mere consequence of Streams downplays
its range of uses within Java 8. It gives programmers a new way to express behavior
parameterization. Suppose you want to write two methods that differ in only a few lines of
code; you can now pass the code of the parts that differ as an argument (this programming
technique is shorter, clearer, and less error prone than the common tendency to use copy
and paste). This Java 8 feature also provides access to a whole range of further techniques,
which are commonly referred to as functional-style programming. We start this chapter with
a high-level discussion on why languages evolve, continue with sections on the core features
of Java 8, and then introduce the ideas of functional-style programming, which the new
features simplify using and which new computer architectures favor. In essence section 1.1
starts with the evolution process and the concepts, which Java was previously lacking, to
exploit multicore parallelism; section 1.2 explains why passing code to methods in Java 8 is
such a powerful new programming idiom, and section 1.3 does the same for Streams—the
new Java 8 way of representing sequenced data and processing it in parallel. Section 1.4
explains how the new Java 8 feature of default methods enables interfaces and their libraries
to evolve with less fuss and less recompilation. Finally, section 1.5 looks ahead at the ideas
of functional-style programming in Java and other languages sharing the JVM. In summary,
this chapter introduces ideas that are successively elaborated in the rest of the book.
Enjoy the ride!
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
http://www.manning-sandbox.com/forum.jspa?forumID=881
2
1.1 Why is Java still changing?
In the 1960s there was the quest for the perfect programming language. In a landmark
article, Peter Landin, famous computer scientist of his day, noted1 in 1966 that there had
already been 700 programming languages and speculated on what the next 700 would be
like—including arguments for functional-style programming similar to that in Java 8.
Many thousands of programming languages later, academics have concluded that
programming languages behave like an ecosystem: new languages appear and old languages
are supplanted unless they evolve. Programmers live in hope of a perfect universal language,
but in reality certain languages are better fitted for certain niches. For example, C and C++
remain popular for building operating systems, in spite of their lack of programming safety,
leading to programs crashing unpredictably and opening security holes for viruses and the
like.
Prior occupancy of a niche tends to discourage competitors (changing to a new language
and tool chain is often too painful for just a single feature), but newcomers will eventually
displace existing languages, unless they evolve fast enough to keep up (older readers will
often be able to quote a range of such languages in which they may have previously coded
but whose popularity has since waned—Ada, Algol, Cobol, Pascal, Delphi, and Snobol, to
name but a few).
You’re a Java programmer, and Java has been successful at colonizing a large worldwide
niche for the last 15 years. Let’s examine some reasons for that.
1.1.1 Java's place in the ecosystem
Java started well. Right from the start, it was a well-designed object-oriented language, with
many useful libraries. It also supported small-scale concurrency from day one, with its
synchronized classes and methods. In addition, the decision to compile Java to JVM bytecode
(a virtual machine code that soon every browser supported) meant that it became the
language of choice for internet applet programs (do you remember applets?) Indeed, there’s
a danger that the Java virtual machine and its bytecode will be seen as more important than
Java itself, and that Java might be replaced by one of its competing languages such as Scala
or Groovy, which also run on the Java virtual machine. In fact, many recent updates to the
Java virtual machine (for example, the new invokedynamic bytecode in JDK7) aim to help
such competitor languages run smoothly on the JVM.
Java has also been successful at colonizing various aspects of embedded computing
(everything from smartcards, toasters, and set-top boxes to car braking systems and
autopilots).
1 P. J. Landin. The Next 700 Programming Languages. CACM 9(3):157–65, March 1966.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
http://www.manning-sandbox.com/forum.jspa?forumID=881
3
How did Java get into a general programming niche at all?
Object orientation had become fashionable in the 1990s for two reasons: (a) its
encapsulation discipline resulted in fewer software engineering issues than those of C and
(b) it matched the WIMP model of Windows 95 and up. Everything is an object; a mouse
click sends an event message to a handler (invokes the Clicked method in a Mouse object).
The write-once run-anywhere model and the ability of early browsers to execute (safe) Java
code applets gave it a niche in universities whose graduates then populated industry. There
was initial resistance to the additional run cost of Java over C/C++, but machines got faster
and programmer time became more and more important. Microsoft’s C# further validated
the Java-style object-oriented model.
But the climate is changing for the programming language ecosystem; programmers are
increasingly dealing with big data (terabytes and up) and wishing to exploit multicore
computers or computing clusters effectively to process this. And this means using parallel
processing—something Java was not previously good at.
You may have come across programming ideas from other programming niches (for
example, Google’s map-reduce or the relative ease of data manipulation in SQL) that help
you work with big data and multicore CPUs. Figure 1.1 summarizes the language ecosystem
pictorially: new languages are appearing and becoming increasingly popular because they’ve
adapted quickly to the climate change.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
http://www.manning-sandbox.com/forum.jspa?forumID=881
4
Figure 1.1 Programming languages ecosystem and climate change
We now highlight and develop the ideas behind three such programming concepts that
have driven the development of the Java 8 features to exploit parallelism. We introduce them
in a slightly different order from the rest of the book to enable a Unix-based analogy and to
expose the “need this because of this” dependencies in Java 8’s new parallelism for multi core.
1.1.2 Stream processing
The first programming concept is the idea of stream processing. A stream is a sequence of
data items that are produced one at a time. One practical example is in Unix or Linux where
many programs operate by reading data from stdin (standard input), operating on it, and then
writing their results on stdout (standard output). The Unix command line allows such
programs to be linked together with pipes (written |) giving examples such as
cat file1 file2 | tr "[A-Z]" "[a-z]" | sort | tail -3
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
http://www.manning-sandbox.com/forum.jspa?forumID=881
5
which, supposing file1 and file2 contain words, prints the three words from the files that
appear latest in dictionary order (after first translating them to lowercase). You say that sort
takes a stream of lines2 as input and produces another stream of lines as output (the latter
being sorted) as illustrated in figure 1.2. Note that in Unix the programs (cat, tr, sort, and
tail) are executed in parallel, so that sort can process the first few lines before cat or tr
has finished.
Figure 1.2 Unix commands operating on streams
Java 8 adds a Streams API (note the upper-case ‘S’) in java.util.stream based on this
idea – Stream is a sequence of items of type T. The Streams API has many methods that
can be chained to form a complex pipeline just like unix commands were chained above.
The key motivation for this is that Java can now transparently run your pipeline of Stream
operations on several CPU cores on disjoint parts of the input – this is parallelism almost for
free. We cover the Java 8 Streams API in detail in Chapter 4.
1.1.3 Passing code to methods
The second programming concept required above is the ability to “pass a piece of code to an
API”. This sounds awfully abstract. In the Unix example, we might want to tell the sort
command to use a custom ordering. While the sort command supports a few parameters to
perform different pre-defined sorting such as reverse order, these are limited. For example,
in Spanish the word “llama” appears after “lye”. What we really want is the ability to tell the
sort command to take as an argument an ordering defined by the user: a separate piece of
code passed to the sort command.
Now, as a direct parallel in Java, we want to tell a sort method to compare using Spanish
ordering. You could write a method compareWithSpanishOrdering to compare two words
but, prior to Java 8, you cannot pass this method to another method! Java 8 adds the ability
to pass methods (your code) as arguments to other methods. Figure 1.3 illustrates this idea.
We will also refer to this conceptually as behaviour parameterisation. Why is this important?
The Streams API is built upon the idea of passing code to parameterize the behavior of its
operations – just like we passed compareWithSpanishOrdering to parameterize the behavior
of sort.
2 Purists will say a “stream of characters,” but it’s conceptually simpler to think that sort reorders lines.
©Manning Publications Co. We welcome reader comments about anything in the manuscript - other than typos and
other simple mistakes. These will be cleaned up during production of the book by copyeditors and proofreaders.
http://www.manning-sandbox.com/forum.jspa?forumID=881
6
Figure 1.3 Passing a method as argument to sort
We summarize how this works in section 1.2 of this chapter but leave full details to
chapter 3. Chapter 10 looks at more advanced things you can do with code-as-a-value
beyond passing it to methods.
1.1.4 Parallelism and shared mutable data
The third programming concept is rather more implicit and arises from the phrase
“parallelism almost for free” in our previous discussion on stream processing. What do you
have to give up? The answer is no shared mutable data. The previous parallelism arises only
by assuming that multiple copies of your piece of code can work independently. If there’s a
shared variable or object, which is written to, then things no longer work: what if two
processes want to modify the shared variable at the same time? (Section 1.3 gives a more
detailed explanation with a diagram.)
Java 8 streams exploit parallelism in an easier way than Java’s existing Thread
本文档为【Java 8 in Action Lambdas, Streams and Functional-style Programming】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑,
图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。