Trying on Java 8 Stream Parallel

I had been trying on Java 8 Stream Parallel.

Refer following code:

import java.util.*;
public class Test {
	public static void main(String args[]) {
		List list = new ArrayList<>();
		list.add(new Employee("First", "YongHao"));
		list.add(new Employee("Second", "YongHao"));
		list.add(new Employee("Third", "YongHao"));
		
		list.stream().sorted((e1, e2) -> e1.getFirstName().compareTo(e2.getFirstName()))
		        .forEach(System.out::println);
		
		System.out.println("--------------");
		
		list.stream().parallel().sorted(Comparator.comparing(e -> e.getFirstName()))
		        .forEachOrdered(System.out::println);
		        
		        
	}
	
	public static class Employee {
		String firstName;
		String lastName;
		public Employee(String firstName, String lastName) {
			this.firstName = firstName;
			this.lastName = lastName;
		}
		public String getFirstName() {
			return firstName;
		}
		public String getLastName() {
			return lastName;
		}
		public String toString() {
			return firstName + " " + lastName;
		}
	}
}

The result will be:
➜ java2 javac Test.java
➜ java2 java Test
First YongHao
Second YongHao
Third YongHao
————–
First YongHao
Second YongHao
Third YongHao

Look at first:

list.stream().sorted((e1, e2) -> e1.getFirstName().compareTo(e2.getFirstName()))
.forEach(System.out::println);

It first returns the list as a stream, sort the list using the lambda expression and then iterating the list and print its output.

Look at second:

list.stream().parallel().sorted(Comparator.comparing(e -> e.getFirstName()))
.forEachOrdered(System.out::println);

Notice, after returned stream-ed list, there is a chained parallel(), which will actually doing background task distribution fully utilizing your system cores. And notice, forEachOrdered method at the end, which guarantees the ordered result be returned. If we replace forEachOrdered to forEach, you will see random order be returned. Because forEach method cannot guarantee ordered result when doing parallel operation.

Another note, see the chained operation, from the list, to stream(), parallel(), sorted(), at the point Java had not yet execute anything, list.stream() did return a stream-ed list, or more formally, a lazy list, the actual execution started when we call forEach or forEachOrdered function.

I did some simple benchmark to measure the speed for these two, one without parallel and one with parallel.

Here come modified code:

import java.util.*;
public class Test {
	public static void main(String args[]) {
		List list = new ArrayList<>();
		generateList(list);
		long start = System.currentTimeMillis();
		list.stream().sorted((e1, e2) -> e1.getFirstName().compareTo(e2.getFirstName()))
		        .toArray();
		System.out.println("Elapsed:"+(System.currentTimeMillis() - start));
		System.out.println("--------------");
		start = System.currentTimeMillis();
		list.stream().parallel().sorted(Comparator.comparing(e -> e.getFirstName()))
		        .toArray();
		System.out.println("Elapsed:"+(System.currentTimeMillis() - start));        
	}
	
	private static void generateList(List list) {
		for(int i = 0; i < 2000000; i++) {
			Employee e = new Employee("EMP" + i, "YONGHAO");
			list.add(e);
		}
	}
	
	public static class Employee {
		String firstName;
		String lastName;
		public Employee(String firstName, String lastName) {
			this.firstName = firstName;
			this.lastName = lastName;
		}
		public String getFirstName() {
			return firstName;
		}
		public String getLastName() {
			return lastName;
		}
		public String toString() {
			return firstName + " " + lastName;
		}
	}
}

The result will be:
java2 javac Test.java
➜ java2 java Test
Elapsed:1901
--------------
Elapsed:337
➜ java2 java Test
Elapsed:296
--------------
Elapsed:494
➜ java2
➜ java2 java Test
Elapsed:288
--------------
Elapsed:1425
➜ java2
➜ java2 java Test
Elapsed:1834
--------------
Elapsed:422

OK, the result showed that... well, most of the time parallel operation faster, actually it should be faster when operating quite big data. Because it distributes the tasks to multiple cores.

OK, conclusion, worth to learn this new technology.

Stream and Lambda is the new features added in Java 8. A lot more to explore.

Author: fyhao

Jebsen & Jessen Comms Singapore INTI University College Bsc (Hon) of Computer Science, Coventry University

Leave a Reply