How to Create Streams in Java

  • Post last modified:December 15, 2022
  • Reading time:4 mins read
Photo by Steve Adams on Unsplash

Introduction

  • Streams is the one of the most important feature that was added in Java 8.
  • Streams allowed java developers to to convert a collection into streams of elements and define the intermediate and terminal operations. Basically it gave more power to developer to write concise and elegant code with fewer lines and more declarative in nature.
  • In this article , we will explore various ways to create Java streams from different data sources.

Creating Streams From Values

  • Stream Interface consist of two static of Methods, to which we can either pass single object or collection of objects.
Stream<String> stream1 = Stream.of("test1");
Stream<String> stream2 = Stream.of("test1", "test2", "test3", "test1");
  • Once we have streams we can use intermediate and terminal operations.
    Below are the some of the operations that we can do over a stream.
  • I would like to filter only distinct elements from stream2 to output.
stream2
        .distinct()
        .forEach(System.out::println);
  • Streams Interface also provides creating streams from Builder pattern.
Stream<Integer> build1 = Stream.<Integer>builder()
        .add(2)
        .add(1)
        .add(3)
        .add(5)
        .build();

Creating Streams From Arrays

  • Array is most common data structure in any programming language. We will convert Arrays data source into Java streams.
String[] domains = {"abc.com", "pqr.net", "tuf.org", "abc.com"};
  • We have array of domains data source. Now let’s create streams from it so that we can use nice functional style programming.
Stream<String> domainsStream = Stream.of(domains);
  • Now let’s see how can we create streams from primitive elements.
  • In order to create streams from primitive array we have to use IntStream type. Arrays class provides stream method to convert primitive to IntStream.
int[] ints = {1,2,3};
IntStream stream = Arrays.stream(ints);
Arrays.stream(ints).forEach(System.out::println);

More information can be found here.

Creating Streams from Functions

  • We can also create streams from infinite sequence of numbers. Streams Interface provides method such as generate() and iterate() which can be used to create infinite sequence of numbers.

Using generate(Supplier<? extends T> s):

  • As we can see generate takes supplier as argument to generate infinite sequence of numbers.
  • We are passing randomUUID method from UUID class to generate unique id every time generate is invoked. We are limiting the result to 10 and printing the result.
Stream
        .generate(UUID::randomUUID)
        .limit(10)
        .forEach(System.out::println);

Using Iterate(T Seed, UnaryOperator<T> f)

  • Iterate method can generate infinite sequence based on order. In below example we are passing unaryoperator that takes current element and increase by 1.
Stream
        .iterate(10, n->n+1)
        .limit(10)
        .forEach(System.out::println);
  • If we use parallel stream here we might not get desired stream since order might not be respected.

Creating From Collection

  • Collection Interface provides stream and parallelStream method to create stream form Collection.
Set<Integer> set = new HashSet<>(List.of(3,2,1));
System.out.println(set.
        stream().
        sorted().
        reduce(Integer::max));

Creating Streams from File IO

  • Java NIO File class & BufferedReader also provides streams from lines() method.
// NIO Files.lines()
try (Stream<String> lines = Files.lines(Path.of(""))){
    System.out.println(lines);
}catch (Exception ex){
    System.out.println(ex);
}
// bufferedreader
BufferedReader bufferedReader = new BufferedReader(new FileReader(""));
try(Stream<String> lines = bufferedReader.lines()){
    lines.forEach(System.out::println);
}catch (Exception ex){
    System.out.println(ex);
}

Creating Empty Streams

  • We can also create empty streams as shown below. Empty streams my be useful to avoid null pointer exception when there is no element.
Stream<String> empty = Stream.empty();

Conclusion

  • In this article we discussed different ways to create streams from different input sources such as collections, arrays, IO etc.
  • Streams gives as opportunity to write functional code with lazy evaluation of operations.

Bonus Tip

Leave a Reply