Overview
The Stream API offers easy filtering, counting, and a mapping of collections, as well as different ways to get slices and subsets of information out of them.
It also allows shorter and more elegant code for working with collections.
What is a Stream?
The
The Stream interface supports the map/filter/reduce pattern and executes lazily, forming the basis (along with lambdas) for functional-style programming in Java 8.
There are also corresponding primitive streams (IntStream, DoubleStream, and LongStream) for performance reasons.
Generating Streams
There are many ways to create a Stream in Java 8. Many of the existing Java core library classes have Stream returning methods in Java 8.
-
Streaming Collections
The most obvious way to create a stream is from a
Collection .The Collection interface has two default methods on it for creating streams:
stream() : Returns a sequential Stream with the collection as its source.parallelStream() : Returns a possibly parallel Stream with the collection as its source.
The ordering of the Stream relies on the underlying collection just like an Iterator.
-
Streaming Files
The BufferedReader now has the
lines() method which returns a Stream; for example:012345try (FileReader fr = new FileReader("file");BufferedReader br = new BufferedReader(fr)) {br.lines().forEach(System.out::println);}You can also read a file as a Stream using
Files.lines(Path filePath); for example:01234try (Stream st = Files.lines(Paths.get("file"))) {st.forEach(System.out::println);}Note this populates lazily; it does not read the entire file when you call it.
-
Streaming File Trees
There are several static methods on the
Files class for navigating file trees using a Stream.list(Path dir) : Stream of files in the given directory.walk(Path dir) : Stream that traverses the file tree depth-first starting at the given directory.walk(Path dir, int maxDepth) : Same as walk(dir) but with a maximum depth.
-
Ranges
There are also new methods for creating ranges of numbers as Streams.
For example, the static method, range, on the
IntStream interface:012IntStream.range(1, 11).forEach(System.out::println);The above would print out the numbers one through ten.
Each primitive Stream (
IntStream ,DoubleStream , andLongStream ) has a corresponding range method
For Each
The most basic thing you can do with a Stream is loop through it using the
For example, to print out all of the files in the current directory, you could do the following:
0 1 2 |
Files.list(Paths.get(".")).forEach(System.out::println); |
For the most part, this replaces the “for loop”. It is more concise, and more object-oriented since you are delegating the implementation of the actual loop.
Comparisons to Java 7
To better illustrate the benefit of Streams in Java 8, here are some examples of code from Java 7 compared to their new versions.
Finding a maximum
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
// Java 7 double max = 0; for (Double d : list) { if (d > max) { max = d; } } //Java 8 max = list.stream().reduce(0.0, Math::max); // or max = list.stream().mapToDouble(Number::doubleValue).max().getAsDouble(); |
Calculating an average
0 1 2 3 4 5 6 7 8 9 10 |
double total = 0; double ave = 0; // Java 7 for (Double d : list) { total += d; } ave = total / ((double) list.size()); //Java 8 ave = list.stream().mapToDouble(Number::doubleValue).average().getAsDouble(); |
Printing the numbers one through ten
0 1 2 3 4 5 6 7 8 9 10 11 |
// Java 7 for (int i = 1; i < 11; i++) { System.out.println(i); } // Java 8 IntStream.range(1, 11) .forEach(System.out::println); //or Stream.iterate(1, i -> i+1).limit(10) .forEach(System.out::println); |
Conclusions
The Stream API is a powerful but simple to understand set of tools for processing sequence of elements. It allows us to reduce a huge amount of boilerplate code, create more readable programs and improve app’s productivity when used properly.
Very interesting points you have remarked, appreciate it for putting up.
Thanks, Ruslle.
We have many other topics on Java 8, You can find it here http://www.codenuclear.com/category/java/java8/