The concept of final and intermediate operations. Examples. Methods stream(), parallelStream()
Contents
- 1. Final and intermediate operations. Definition
- 2. Final operation. Example
- 3. Intermediate operation. Example
- 4. Formation of new data streams using a conveyer. Example
- 5. Examples of receiving (opening) a data stream. Methods stream(), parallelStream()
- Related topics
Search other websites:
1. Final and intermediate operations. Definition
Under operation involves calling a method that handles stream. When processing a stream, the concepts of a final operation and an intermediate operation arise. If the term “final operation” is described in the definition of a method, it means that the entire stream has been revised (processed) from beginning to end and the final result has been obtained. After that, this stream is considered consumed and cannot be reused. If you try to process the consumed stream after the final operation (method) has been completed, the system will generate an exception.
If an “intermediate operation” is specified in the description of an operation (method), it means that a new data stream is created (produced), which can be further processed in a pipeline mode. The pipeline mode provides for the further use of intermediate or final operations on the newly created stream. In this case, the final operation is called last.
⇑
2. Final operation. Example
The example demonstrates the use of final operations.
Task. Calculate the minimum and maximum values in a set of random numbers of type Double.
The demo program is as follows.
import java.util.ArrayList; import java.util.Optional; import java.util.stream.*; public class StreamAPI { public static void main(String[] args) { // Convert a stream of numbers to a Double[] array // 1. Declare a set of numbers as a collection ArrayList<Double> AL = new ArrayList<Double>(); // 2. Fill a set of numbers with random values for (int i=0; i<10; i++) AL.add((Math.random()*10)); // 3. Create a stream of numbers Stream<Double> stream = AL.stream(); // 4. Find the maximum value in an array Optional<Double> max = stream.max(Double::compare); System.out.println("max = " + max.get()); // 5. Attempt to call another operation - search for the minimum stream = AL.stream(); // Be sure to create a new stream Optional<Double> min = stream.min(Double::compare); System.out.println("min = " + min.get()); } }
The above code first searches for the maximum, then searches for the minimum. Maximum search operation
stream.max (Double::compare);
is the final. This means that after its execution, the stream is considered consumed.
The consumed stream cannot be processed further. If, after searching for the maximum, remove the line
stream = AL.stream ();
then after running for execution, the program will throw an IllegalStateException exception.
The result of the program
max = 8.627680677435304 min = 1.4456409633880085
⇑
3. Intermediate operation. Example
The example demonstrates performing an intermediate operation that sorts a stream of numbers in descending order.
import java.util.*; import java.util.function.*; import java.util.stream.*; public class StreamAPI { public static void main(String[] args) { // Sorting a stream of numbers in descending order of values // 1. Create a set of numbers ArrayList<Integer> AL = new ArrayList<Integer>(); for (int i=0; i<10; i++) AL.add((int)(Math.random()*10)); System.out.println("AL = " + AL); // 2. Create a stream of numbers based on the AL collection Stream<Integer> stream = AL.stream(); // 3. Call an intermediate sort operation - a new stream is created // 3.1. Create comparison method Comparator<Integer> comparator = (a, b) -> b-a; // 3.2. Create a new sorted stream is an intermediate operation, // after which the stream can be processed further Stream<Integer> sortStream = stream.sorted(comparator); // 3.3. Output a new stream System.out.print("sorted AL = "); // 3.3.1. Create an action that displays a stream item on the screen Consumer<Integer> action; action = (n) -> { System.out.print(n + " "); }; // Pass the action to the forEach() method for elementwise processing sortStream.forEach(action); // forEach() - final operation } }
The above code creates a stream of numbers stream from the AL collection. The resulting stream is sorted by an intermediate sorted() operation. The sorted() method creates a new sorted stream
Stream<Integer> sortStream = stream.sorted(comparator);
Since sorted() is an intermediate operation, the new stream can be processed further. In our case, the entire stream is outputted element by element using the forEach() method as shown below
sortStream.forEach(action); // forEach() - final operation
The forEach() method is the final operation. This means that the sortStream has been consumed. To reuse the stream, it needs to be restored from its source – a set of AL numbers.
After execution, the program will give the following result
AL = [5, 4, 0, 5, 2, 9, 1, 3, 0, 2] sorted AL = 9 5 5 4 3 2 2 1 0 0
⇑
4. Formation of new data streams using a conveyer. Example
Task. A stream of numbers is given. Find the minimum number of the stream numbers that are greater than 5 and less than 20.
Solution. To solve the problem, you need to use a conveyer approach to modify the stream. Using two operations (methods):
- operation (method) filter() – intermediate operation;
- operation (method) min() – final operation.
The text of the solution to the problem is as follows
import java.util.*; import java.util.function.*; import java.util.stream.*; public class StreamAPI { public static void main(String[] args) { // Task. A stream of numbers is given. Find the minimum // number of the stream numbers that are greater than 5 and less than 20. // 1. Create a set of numbers ArrayList<Integer> AL = new ArrayList<Integer>(); AL.add(15); AL.add(13); AL.add(7); AL.add(1); AL.add(23); AL.add(6); AL.add(3); AL.add(11); AL.add(22); AL.add(2); // 2. Create a stream of numbers based on the AL collection Stream<Integer> stream = AL.stream(); System.out.println("AL = " + AL); // 3. Call an intermediate filtering operation - a new stream is created // 3.1. Create comparison method - numbers greater than 5 Predicate<Integer> predicate = (a) -> a>5; // condition // 3.2. Create a new filtered stream // after which the stream can be processed further Stream<Integer> filteredStream = stream.filter(predicate); // 4. Call another intermediate filtering operation - a new stream is created // This time, numbers that are less than 20 are filtered. predicate = (a) -> a<20; // 5. Filter the same stream again filteredStream = filteredStream.filter(predicate); // this is again an intermediate operation // 6. Find the minimum value in the newly created stream Optional<Integer> min = filteredStream.min(Integer::compare); // this is final operation // 7. Display the minimum value on the screen System.out.println("min = " + min.get()); } }
After execution, the program will give the following result
AL = [15, 13, 7, 1, 23, 6, 3, 11, 22, 2] min = 6
⇑
5. Examples of receiving (opening) a data stream. Methods stream(), parallelStream()
The example implements obtaining a data stream for various types of collections. The stream() method is used to get a sequential stream. The parallelStream() method is used to get a parallel stream.
import java.util.*; import java.util.stream.*; public class StreamAPI { public static void main(String[] args) { // Task. A set of numbers is given. Create a stream from this set // 1. Create a data stream from a collection of type ArrayList<T> // 1.1. Create a collection of numbers ArrayList<Integer> AL = new ArrayList<Integer>(); AL.add(15); AL.add(13); AL.add(7); AL.add(1); AL.add(23); AL.add(6); AL.add(3); AL.add(11); AL.add(22); AL.add(2); // 1.2. Create sequential data stream based on AL collection Stream<Integer> stream = AL.stream(); // 1.3. Create parallel data stream from AL collection Stream<Integer> parallelStream = AL.parallelStream(); // 2. Create data stream from the array of integers int[] AI = { 2, 5, 4, 8, -1, 3, 9 }; IntStream streamInt = Arrays.stream(AI); // sequential stream IntStream parallelStreamInt = streamInt.parallel(); // parallel stream // 3. Create data stream from the array of real numbers double[] AD = { 0.5, -1.8, 3.77, 4.23, 21.7, -10.8 }; DoubleStream streamDouble = Arrays.stream(AD); // sequential stream to a given DoubleStream parallelStreamDouble = streamDouble.parallel(); // parallel stream // 4. Create a stream of data from the array of type long Long[] ALong = { 282039l, 3239290l, 23902309l, 72083289L }; Stream<Long> streamLong = Arrays.stream(ALong); // sequential stream Stream<Long> parallelStreamLong = streamLong.parallel(); // parallel stream } }
⇑
Related topics
⇑