Introduced in Java 8, streams are the easiest and most convenient way to operate on collections without altering the underlying data source.
List<Monitor>, int[], HashMap<String, String>
.forEach
method (which operates in serial order), streams can be executed either in parallel or in serial order. int totalVMwareCPU = monitors.stream().filter(monitor - > monitor.getMonitorType() == MonitorType.VMWARE).mapToInt(monitor - > monitor.getCPU()).sum();
In the above example, we are computing the total CPU of VMware monitors. filter()
and mapToInt are intermediate functional operations pipelined (combined one another) and sum()
is the terminal operation. Source data in Collection<Monitor>
is never altered.
Streams are available from Java Development Kit (JDK) version 8. The following code is an another variant without using streams for previous JDK versions.
int totalVMwareCPU = 0;
for(Monitor monitor : monitors) {
if(monitor.getMonitorType() == MonitorType.VMWARE) {
totalVMwareCPU += monitor.getCPU();
}
}
parallelStream
method in the collection object. monitors.stream().filter(monitor - > monitor.getMonitorType() == MonitorType.VMWARE).parallel().mapToInt(Monitor::getCPU).sum();
We have used the method reference "Monitor::getCPU" inside the mapToInt
functional operation. The exact lambda equivalent is mapToInt(monitor -> monitor.getCPU())
In the above code, we have explicitly mentioned parallel processing. The following code prints the threads involved in parallel processing.
monitors.stream() .filter(monitor -> monitor.getMonitorType() == MonitorType.VMWARE) .parallel().mapToInt(monitor -> {
System.out.println("Thread name: " + Thread.currentThread().getName());
eturn monitor.getCPU();
}).sum();
Output:
Thread name: ForkJoinPool.commonPool-worker-9
Thread name: ForkJoinPool.commonPool-worker-2
Thread name: ForkJoinPool.commonPool-worker-3
The fork/join framework is used and the worker threads in the common pool are employed for processing. Fork/join frameworks take care of splitting the sequential data across different worker threads and combining it by handling the callbacks on completion.
The number of threads in the common pool is based on the number of processor cores the machine has. To specify a custom value, the following code snippet has to be included in the JVM arguments.
-D java.util.concurrent.ForkJoinPool.common.parallelism=3
This setting is a global setting at the JVM level. Example using the reduce operation.
monitors.stream().filter(monitor - > monitor.getMonitorType() == MonitorType.VMWARE).parallel().reduce(0, (accumulatedCPU, monitor1) - > accumulatedCPU + monitor1.getCPU(), Integer::sum);
The reduce operation is used to produce a single value by applying and accumulating values using the specified operation on every sequence of object in the collection. In the above example:
(accumulatedCPU, monitor1) -> accumulatedCPU + monitor1.getCPU()
is the accumulator.
Integer::sum
combines the results from various sub streams. The accumulator lambda function takes two arguments of different data types. Without a combiner, Java will throw a compilation error, because it would think both arguments are monitor types. Based on combiner result intelligence, the compiler would now treat the first argument accumulatedCPU as an integer.
This is the default mode in stream execution. A singe thread handles processing the pipeline operations.
Fig. 2. Serial Streams in Javaint totalVMwareCPU = monitors.stream().filter(monitor - > monitor.getMonitorType() == MonitorType.VMWARE).mapToInt(monitor - > monitor.getCPU()).sum();
Since a single thread is processing the operations, the order of processing the sequential elements in predictable.
List < String > words = Arrays.asList("Site24x7", "-", "All", "in", "one", "monitoring", "solution");
String sentence = words.stream()
.reduce("", (concat, word) - > concat + word + " ");
System.out.println(sentence);
Output:
Site24x7 - All in one monitoring solution
The following code snippet use "method reference" instead of lambda expression
List < String > words = Arrays.asList("Site24x7 ", "- ", "All ", "in ", "one ", "monitoring ", "solution");
String sentence = words.stream()
.reduce("", String::concat);
System.out.println(sentence);
Java streams are considered important for their parallel processing capabilities. Choosing between serial and parallel streams depends on the developer's requirements.
In case if you have a huge data set to process with each data processing consuming more time, you can use parallel streams, so data processing is executed parallel in different CPU cores.
Write for Site24x7 is a special writing program that supports writers who create content for Site24x7 “Learn” portal. Get paid for your writing.
Apply Now