Other Stream CreationJ8 Home « Other Stream Creation
In the Introducing Streams we learnt how to produce streams from collections and made Array Type Streams and Numeric Streams in subsequent lessons.
In this lesson we take a final look at stream creation by creating streams from files, functions and iterations and also find out about creating infinite streams.
Streams From Files Top
So far we've been creating streams from collections, arrays and objects but another common way of creating a stream is from a file, in fact the java.nio.file
Api was specifically updated to take advantage of streams!
Lets look at stream creation from a file by coding a StreamCreationA
class.
We will be using a sayings.txt
file for testing this class, the contents of which are shown in the following screenshot.
package info.java8;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.stream.Stream;
public class StreamCreationA {
/* Stream files */
public static void main(String[] args) {
// Stream file contents
long totalWords = 0;
try(Stream<String> lines =
Files.lines(Paths.get("D:\\_Streams\\src\\info\\java8\\sayings.txt"))) {
totalWords = lines.flatMap(line -> Arrays.stream(line.split(" ")))
.count();
}
catch(IOException e){
e.printStackTrace();
}
System.out.println("Total words in sayings.txt file is: " + totalWords);
// Stream directory paths
try(Stream<Path> entries =
Files.list(Paths.get("D:\\_Streams\\src\\info\\java8\\"))) {
entries.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Building and running the StreamCreationA
class produces the following output:
Lets go though the code and see what's new!
We used the Files.lines()
method which reads all lines from a file and produces a Stream<String>
object. We then flatten the stream using the flatMap()
method and then use count()
to sum up the elements in this stream.
We also used the Files.list()
method which returns a lazily populated Stream<Path>
object, the elements of which are the entries in the directory. We then iterated over the stream printing out directory entries.
Stream From Functions Top
The iterate()
method of the Stream<E>
interface returns an infinite sequential ordered Stream
produced by iterative application of a function f
to an initial element seed
, producing a Stream
consisting of seed
, f(seed)
, f(f(seed))
, etc.
Did you notice that in the description of the iterate()
method it mentions that an infinite stream is returned? Because we are computing values on the fly the stream is unbounded and will continue producing results ad infinitum. We can stop this happening by limiting the size of the stream using the limit()
method of the Stream<E>
interface.
Lets look at stream creation from a function by coding a StreamCreationB
class.
package info.java8;
import java.util.stream.Stream;
public class StreamCreationB {
/* Stream from functions */
public static void main(String[] args) {
// iterate over function creating power to the twos
Stream.iterate(3, n -> n * n)
.limit(5)
.forEach(System.out::println);
System.out.println("+++++++++++++");
// iterate over function creating power to the threes
Stream.iterate(3, n -> n * n * n)
.limit(4)
.forEach(System.out::println);
}
}
Building and running the StreamCreationB
class produces the following output:
In both examples we use the iterate()
method of the Stream<E>
interface and our function is just a lambda of type UnaryOperator<T>
. We start with an initial value of 3
and multiply it by 2
for squares and 3
for cubes. This is a very useful method for creating sequential streams of data with a couple of lines of code.
Removing the limit()
method will make the streams infinite.
Generated Streams Top
The generate()
method of the Stream<E>
interface returns an infinite sequential unordered stream where each element is generated by the provided Supplier
.
Lets look at stream creation using by the generate()
method by coding a StreamCreationC
class.
package info.java8;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class StreamCreationC {
/* Generated streams */
public static void main(String[] args) {
// create stream of 2s
IntStream.generate(() -> 2)
.limit(5)
.forEach(System.out::println);
System.out.println("+++++++++++++");
// create stream of random numbers
Stream.generate(Math::random)
.limit(5)
.forEach(System.out::println);
}
}
Building and running the StreamCreationC
class produces the following output:
On the surface the generate()
method seems very similar to the iterate()
method but it doesn't generate values from a constant iteration over a function. It also uses a lambda of type Supplier<T>
for generating new values which of course can be replaced with a method reference as in the second example above.
Just like the iterate()
method removing the limit()
method will make the streams infinite.
Related Quiz
Streams Quiz 6 - Other Stream Creation Quiz
Lesson 6 Complete
In this lesson we looked at stream creation by creating streams from files, functions and iterations and also find out about creating infinite streams.
What's Next?
In the next lesson we look at finding and matching elements within our streams.