Java 17 Recipes


Download 3.2 Mb.
Pdf ko'rish
bet145/245
Sana02.06.2024
Hajmi3.2 Mb.
#1839910
1   ...   141   142   143   144   145   146   147   148   ...   245
Bog'liq
Java 17 Recipes

 How It Works
Prior to Java 8, iterating over a collection required some kind of looping block. This is 
known as external iteration, a.k.a. programmatic looping in sequential order. In most 
cases, a for loop worked through each element within a collection, processing each 
element according to an application’s requirements. While a for loop is a reasonable 
solution for performing iteration, it is both a nonintuitive and verbose strategy. Since the 
release of Java 8, the boilerplate of iterating over collections was removed, along with the 
requirement to spell out how the iteration was to be completed. The compiler already 
knows how to iterate a collection, so why tell it exactly how to do it? Why not simply tell 
the compiler that you want to iterate the collection and perform a task on each element. 
The concept of streams enables this hands-off approach to iteration.
Let the compiler take care of the nonintuitive looping, and simply hand the task 
off to the compiler and tell it what action to perform on each element. This concept is 
known as internal iteration. With internal iteration, your application determines what 
needs to be iterated, and the JDK decides how to perform the iteration. Internal iteration 
not only alleviates the requirement to program the looping logic, but it also has other 
advantages. One such advantage is that internal iteration is not limited to sequential 
iteration over elements. Therefore, the JDK decides how to iterate, choosing the best 
algorithm for the task at hand. Internal iteration also can more easily take advantage 
of parallel computing. This concept involves subdividing tasks into smaller problems, 
simultaneously solving each, and combining the results.
A stream is a sequence of object references generated on all collection types. The 
Stream API makes it possible to perform a sequence of aggregate operations on those 
object references and either return a result or apply the changes to the objects inline. 
This is also known as a pipeline. The pseudocode for generation and use of a stream is as 
follows.
Collection -> (Stream) -> (Zero or More Intermediate Operations) -> 
(Terminal Operation)
Let’s put this pseudocode into a real example. In the solution, a list of Stock objects 
is used for demonstrating stream iteration. Let’s suppose you want to print out each 
stock that contains a number of shares that is over a designated threshold (100 shares in 
this example). You can use the following code to perform this task.
Chapter 7 Data SourCeS anD ColleCtionS


281
myStocks.stream()
.filter(s -> s.getShares() > 100.0)
.forEach(s->System.out.println(s.getName()));
In the previous example, an intermediate operation known as a filter() applies 
a limitation on the elements, thereby filtering out all elements that do not match the 
supplied predicate. The predicate is written as a lambda expression; it tests each element 
and returns a Boolean result. The terminal operation in the example uses forEach() to 
print each matching element. A terminal operation is the last operation in a pipeline, 
and it produces a nonstream result such as a primitive, collection, or no value at all. In 
the example case, no result is returned.
To generate a stream on a Collection type, call the stream() method, which returns 
a Stream type. In most cases, the Stream type is not the desired result, so the Stream API 
makes it possible to invoke zero or more intermediate operations on a stream, forming 
a pipeline of operations. For example, in the solution, the list of Stock objects is sorted 
by the number of shares using the following code. Note that Comparator byShares is 
applied to each object in the stream and Stream is returned as a result.
Stream sortedByShares = myStocks.stream()
.sorted(byShares);
A single intermediate operation, sorted(), is performed on the stream in the 
previous example. As mentioned previously, there could be more than one intermediate 
operation chained to this pipeline, thereby performing the next operation on those 
objects that meet the criteria of the previous operation. Each of the intermediate 
operations returns a Stream type. Each pipeline can contain a terminal operation
thereby applying the terminal operation to each of the resulting stream objects. As 
mentioned previously, a terminal operation may or may not return a result. In the 
previous example, no terminal operation is applied.
Note the documentation for Stream (
https://docs.oracle.com/en/java/
javase/17/docs/api/java.base/java/util/stream/Stream.html
) lists 
all the intermediate and terminal operations available on a stream.
Chapter 7 Data SourCeS anD ColleCtionS


282
Streams have been a revolutionary change for the Java programming language. They 
change how a developer thinks about a program, making the developer more productive 
and the code more efficient. While legacy iteration techniques such as the for loop are 
still considered valid procedures, streams are the preferred technique for iteration when 
you’re using Java 8 or beyond.

Download 3.2 Mb.

Do'stlaringiz bilan baham:
1   ...   141   142   143   144   145   146   147   148   ...   245




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling