Don’t worry about the details of this code for now; you’ll see the Streams API in depth in Chapter 3. For now, think of a Stream as a new abstraction for expressing data processing queries in a readable way.
Multicore
The second big change in Java 8 was necessitated by multicore processors. In the past, your computer would have only one processing unit. To run an application faster usually meant increasing the performance of the processing unit. Unfortunately, the clock speeds of processing units are no longer getting any faster. Today, the vast majority of computers and mobile devices have multiple processing units (called
Applications should utilize the different processing units for enhanced performance. Java applications typically achieve this by using threads. Unfortunately, working with threads tends to be difficult and error-prone and is often reserved for experts.
The Streams API in Java 8 lets you simply run a data processing query in parallel. For example, to run the preceding code in parallel you just need to use parallelStream() instead of stream():
List
In Chapter 3, I will discuss the details and best practices when using parallel streams.
A Quick Tour of Java 8 Features
This section provides an overview of Java 8’s primary new features—with code examples—to give you an idea of what’s available. The next two chapters will focus on Java 8’s two most important features: lambda expressions and streams.
Lambda Expressions
Lambda expressions let you pass around a piece of code in a concise way. For example, say you need to get a Thread to perform a task. You could do so by creating a Runnable object, which you then pass as an argument to the Thread: Runnable runnable = new Runnable() { @Override public void run() { System.out.println("Hi"); } }; new Thread(runnable).start();
Using lambda expressions, on the other hand, you can rewrite the previous code in a much more readable way: new Thread(() -> System.out.println("Hi")).start();
You’ll learn about lambda expressions in much greater detail in Chapter 2.
Method References
The code just shown is extremely verbose. After all, all you need is the method compareToIgnoreCase. Using method references, you can explicitly say that the comparison should be performed using the method compareToIgnoreCase defined in the String class: Collections.sort(strs, String::compareToIgnoreCase);
The code String::compareToIgnoreCase is a method reference. It uses the special syntax ::. (More detail on method references is in the next chapter.)
Streams
Nearly every Java application creates and processes collections. They’re fundamental to many programming tasks since they let you group and process data. However, working with collections can be quite verbose and difficult to parallelize. The following code illustrates how verbose processing collections can be. It processes a list of invoices to find the IDs of training-related invoices sorted by the invoice’s amount:
List