Thanks to Michael Brush who contributed significantly to this article. -- ACO

Java 8 may be the most anticipated version of Java ever. Originally slated for release in September, Java 8 has been delayed until March of next year, supposedly to buy time to make security fixes aimed mainly at client-side Java (JavaFX/Swing). Since I, like most of you, stopped caring about client-side Java shortly after Duke finally finished jumping rope, we won't address any of that.

Java 8 is trying to "innovate," according to the Microsoft meaning of the word. This means stealing a lot of things that have typically been handled by other frameworks and languages, then incorporating them into the language or runtime (aka standardization). Ahead of the next release, the Java community is talking about Project Lambda, streams, functional interfaces, and all sorts of other goodies. So let's dive into what's great -- and what we can hate.

[ Think you know Java? Test your programming smarts in InfoWorld's Java IQ test. | Master the latest in Java development with our JavaWorld Enterprise Java newsletter. ]

Streams

The changes to collections are driving a lot of the other changes in the language. The main component of making those collections better is a new collection called a "stream." This is not to be confused with java.io package's InputStream and OutputStream -- it's a separate concept altogether.

Streams are not meant to replace ArrayLists or other collections. They are only meant to make manipulating the data easier and faster. A stream is a one-time-use Object . Once it has been traversed, it cannot be traversed again.

Streams have the ability to filter, map, and reduce while being traversed. There are two "modes" for a stream: sequential and parallel. This is where the ability of the stream to use the multicore processors of today comes into play. It uses fork/join parallelism to split up the work and speed the processing along.

Using a sequential stream:

List <Person> people = list.getStream.collect(Collectors.toList());

Using a parallel stream:

List <Person> people = list.getStream.parallel().collect(Collectors.toList());

When the stream is traversed sequentially, each item in the stream is read processed, then the next item is read. When the stream is traversed in parallel, the array is split into multiple segments, each of which is processed individually on a different thread. The results are then put back together for the output.

Parallel stream flow:

List originalList = someData;

split1 = originalList(0, mid);

split2 = originalList(mid,end);

new Runnable(split1.process());

new Runnable(split2.process());

List revisedList = split1 + split2;

This very simplified example shows how the parallel Stream would be processed. This is how it will take advantage of multicore processors.

Since a Stream can only be traversed once and generally returns another Stream , use a terminal method to get a useful result. Examples of a terminal method are sum() , collect() , or toArray() . Until the Stream is terminated, the results of the operations are not realized. For example:

Double result = list.getStream().mapToDouble(f -> f.getAmount()).sum();