Other Stream CreationS2C 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.

Run TestIntStreamA class
Screenshot 1. The contents of the sayings.txt file.

package com.server2client;

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:

Run StreamCreationA class
Screenshot 2. Running the StreamCreationA class.

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 com.server2client;

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:

Run StreamCreationB class
Screenshot 3. Running the StreamCreationB class.

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 com.server2client;

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:

Run StreamCreationC class
Screenshot 4. Running the StreamCreationC class.

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.