Techdozo
  • Microservices
    • All
    • GraphQL
    • gRPC
    • Spring Boot
    gRPC Bidirectional Streaming with Code Example

    gRPC Bidirectional Streaming with Code Example

    gRPC Client Streaming

    gRPC Client Streaming

    Distributed transaction in microservices using Saga

    Distributed Transactions in Microservices: implementing Saga with Temporal

    Temporal Workflow Orchestration

    Workflow Orchestration with Temporal and Spring Boot

    GraphQL Directive

    GraphQL Directive

    Spring for GraphQL mutation

    Spring for GraphQL: Mutation

  • Spring Boot
    Spring Boot GraphQL service

    Getting started with Spring Boot GraphQL service

    Deploying a RESTful Spring Boot Microservice on Kubernetes

    Deploying a RESTful Spring Boot Microservice on Kubernetes

    RESTful Microservices with Spring Boot and Kubernetes

    RESTful Microservices with Spring Boot and Kubernetes

    RESTful API Gateway with gRPC

    RESTful API Gateway with gRPC

  • gRPC
    gRPC Bidirectional Streaming with Code Example

    gRPC Bidirectional Streaming with Code Example

    gRPC Client Streaming

    gRPC Client Streaming

    gRPC Interceptor: unary interceptor with code example

    gRPC Interceptor: unary interceptor with code example

    gRPC: synchronous and asynchronous Server streaming RPC

    gRPC: synchronous and asynchronous Server streaming RPC

    Photo by Ramón Salinero on Unsplash

    gRPC: synchronous and asynchronous unary RPC in Java

    Microservices inter-process communication using gRPC

    gRPC for microservices communication

  • GraphQL
    GraphQL Directive

    GraphQL Directive

    Spring for GraphQL mutation

    Spring for GraphQL: Mutation

    Spring for GraphQL: How to solve the N+1 Problem?

    Spring for GraphQL: How to solve the N+1 Problem?

    Spring GraphQL with @Controller, @SchemaMapping and @QueryMapping

    Spring for GraphQL : @SchemaMapping and @QueryMapping

    Spring Boot GraphQL service

    Getting started with Spring Boot GraphQL service

  • Kubernetes
    Deploying a RESTful Spring Boot Microservice on Kubernetes

    Deploying a RESTful Spring Boot Microservice on Kubernetes

    Components of Kubernetes Architecture

    Components of Kubernetes Architecture

    Helm Chart: quick start your app deployment on Kubernetes

    Helm Chart: quick start your app deployment on Kubernetes

    gRPC load balancing on Kubernetes (using Headless Service)

    gRPC load balancing on Kubernetes (using Headless Service)

    Getting started with Kind: quick start a multi-node local Kubernetes cluster

    Getting started with Kind: quick start a multi-node local Kubernetes cluster

    Getting started with Minikube: deploying application on local Kubernetes cluster

    Getting started with Minikube: deploying application on local Kubernetes cluster

  • Java
    Java Streams: Stream Operation with Examples

    Java Streams: Stream Operation with Examples

    Java Streams: stream creation with examples

    Java Streams: stream creation with examples

    Garbage Collection

    Super Fast Garbage Collectors in Java

    Calculus

    Functional Programming in Java

No Result
View All Result
  • Login
  • Microservices
    • All
    • GraphQL
    • gRPC
    • Spring Boot
    gRPC Bidirectional Streaming with Code Example

    gRPC Bidirectional Streaming with Code Example

    gRPC Client Streaming

    gRPC Client Streaming

    Distributed transaction in microservices using Saga

    Distributed Transactions in Microservices: implementing Saga with Temporal

    Temporal Workflow Orchestration

    Workflow Orchestration with Temporal and Spring Boot

    GraphQL Directive

    GraphQL Directive

    Spring for GraphQL mutation

    Spring for GraphQL: Mutation

  • Spring Boot
    Spring Boot GraphQL service

    Getting started with Spring Boot GraphQL service

    Deploying a RESTful Spring Boot Microservice on Kubernetes

    Deploying a RESTful Spring Boot Microservice on Kubernetes

    RESTful Microservices with Spring Boot and Kubernetes

    RESTful Microservices with Spring Boot and Kubernetes

    RESTful API Gateway with gRPC

    RESTful API Gateway with gRPC

  • gRPC
    gRPC Bidirectional Streaming with Code Example

    gRPC Bidirectional Streaming with Code Example

    gRPC Client Streaming

    gRPC Client Streaming

    gRPC Interceptor: unary interceptor with code example

    gRPC Interceptor: unary interceptor with code example

    gRPC: synchronous and asynchronous Server streaming RPC

    gRPC: synchronous and asynchronous Server streaming RPC

    Photo by Ramón Salinero on Unsplash

    gRPC: synchronous and asynchronous unary RPC in Java

    Microservices inter-process communication using gRPC

    gRPC for microservices communication

  • GraphQL
    GraphQL Directive

    GraphQL Directive

    Spring for GraphQL mutation

    Spring for GraphQL: Mutation

    Spring for GraphQL: How to solve the N+1 Problem?

    Spring for GraphQL: How to solve the N+1 Problem?

    Spring GraphQL with @Controller, @SchemaMapping and @QueryMapping

    Spring for GraphQL : @SchemaMapping and @QueryMapping

    Spring Boot GraphQL service

    Getting started with Spring Boot GraphQL service

  • Kubernetes
    Deploying a RESTful Spring Boot Microservice on Kubernetes

    Deploying a RESTful Spring Boot Microservice on Kubernetes

    Components of Kubernetes Architecture

    Components of Kubernetes Architecture

    Helm Chart: quick start your app deployment on Kubernetes

    Helm Chart: quick start your app deployment on Kubernetes

    gRPC load balancing on Kubernetes (using Headless Service)

    gRPC load balancing on Kubernetes (using Headless Service)

    Getting started with Kind: quick start a multi-node local Kubernetes cluster

    Getting started with Kind: quick start a multi-node local Kubernetes cluster

    Getting started with Minikube: deploying application on local Kubernetes cluster

    Getting started with Minikube: deploying application on local Kubernetes cluster

  • Java
    Java Streams: Stream Operation with Examples

    Java Streams: Stream Operation with Examples

    Java Streams: stream creation with examples

    Java Streams: stream creation with examples

    Garbage Collection

    Super Fast Garbage Collectors in Java

    Calculus

    Functional Programming in Java

No Result
View All Result
Techdozo
No Result
View All Result
Home Java

Java Streams: stream creation with examples

Pankaj by Pankaj
May 1, 2021
in Java
Reading Time: 16 mins read
0
A A
0
Java Streams: stream creation with examples

Photo by Vincent Ledvina on Unsplash

0
SHARES
23
VIEWS
Share on FacebookShare on TwitterShare on Linkedin
  • Share on Facebook
  • Share on Twitter
  • Share on Pinterest
  • Share on Linkedin
  • Share on Reddit

Streams let us do computation on the collection of data in a declarative way. In a declarative way of programming, you don’t specify how to do but you specify what to do. You can create a stream pipeline to perform a computation. A stream pipeline consists of :

  • a source
  • zero or more intermediate operations
  • a terminal operation

Java streams are lazy. As a result, intermediate operations are performed only when the terminal operation is initiated.

Java stream pipeline

Let’s consider an example of finding all Java books author from the catalog of books. Using stream declarative construct you can write code as:


List<Book> books = 
  Catalog.books();

List<String> javaAuthors =
  books.stream()
  .filter(book -> book.getCategory().equals(JAVA))
  .map(Book::getAuthor)
  .collect(Collectors.toList());

Let’s try to understand the above stream pipeline in the context of – ‘a stream pipeline consists of a source, zero or more intermediate operations, and a terminal operation‘

Stream Source

in Java source of the stream could be an array, a collection, a generator function, an I/O channel, value range, etc. In the above example stream is created by calling stream() method of the Collection class.

Intermediate Operation

An intermediate operation transforms a stream into another stream. The intermediate operations are always lazy. Executing an intermediate operation such as filter() does not actually perform any filtering, but instead creates a new stream. The new stream when traversed contains the elements of the initial stream that match the given predicate. Here, you have used filter(Predicate) to filter out books by category. The map(Function) transforms stream of books to stream of authors.

Terminal Operation

A terminal operation produces a result or side-effect. After the terminal operation is performed, the stream pipeline is considered consumed, and can no longer be used. Here, collect is a terminal operation. This accumulates input elements into a List.


Stream Operation
A stream pipeline consists of a Source, one or many intermediate, and a terminal operation

Code sample

Let’s see some stream creation examples. You can find the code of this article on GitHub .

Creating a stream

There are many ways you can create a stream in Java. Let’s look at a few of them.

Stream from individual elements

Stream of(T… values) – returns a sequential ordered Stream whose elements are the specified values.


Stream<String> numbers = 
  Stream.of("One", "Two", "Three");

All streams operations can execute either in serial or in parallel. The stream implementations in the JDK create serial streams unless parallelism is explicitly requested. For example, Collection has methods Collection.stream() and Collection.parallelStream(), which produce sequential and parallel streams respectively; other stream-bearing methods such as IntStream.range(int, int) produce sequential streams but these streams can be efficiently parallelized by invoking their BaseStream.parallel() method.

JDK stream documentation

Stream ofNullable(T t) – return a sequential stream containing a single element, if non-null, otherwise returns an empty stream.


Stream<String> numbers = 
  Stream.ofNullable("One");

Stream<String> empty = 
  Stream.empty(); 

The method Stream.ofNullable provides a simplified null check. For example – if you need to convert Collection<T> to Stream<T> you can do something like:


static Stream<Integer> toStream(Collection<Integer> numbers) {
   return Stream.ofNullable(numbers)
  .flatMap(Collection::stream);
}

The method ofNullable(T t) was added in Java 9.

An alternative approach can be to use optional as:


return Optional
  .ofNullable(numbers)
  .stream()
  .flatMap(Collection::stream);

Stream from Array

You can create a sequential Stream with the specified array as its source as:


String[] names = 
  new String[] {"Jack","Jill"};

Stream<String> stream1 = 
  Stream.of(names);
 
Stream<String> stream2 = 
  Arrays.stream(names);

Stream from a Collection

A sequential Stream can be created by calling the default stream method of collection.


List<String> namesList = 
  List.of("Jack", "Jill");

Stream<String> stream = 
  namesList.stream();

Stream from a Builder

Using builder you can build an ordered stream by calling add and build method.


Stream<String> stream = 
  Stream.<String>builder()
  .add("Jack")
  .add("Jill")
  .build();

Stream using Generate

You can use generate method to create an infinite sequential unordered stream where each element is generated by the provided Supplier. This is suitable for creating a constant stream, a stream of random elements, etc.


Stream<Integer> randomNumbers = 
  Stream
  .generate(new Random()::nextInt)
  .limit(10);

Stream using Iterate

You can create an infinite sequential ordered stream by calling a static factory method iterate (Stream iterate(final T seed, final UnaryOperator f)). The first element of the Stream is determined by seed and for n > 0, the element at position n will be the result of applying the function f to the n-1.


Stream<Integer> even = 
  Stream
  .iterate(0, n -> n + 2)
  .limit(10);

Primitive Stream

Specialized primitive interfaces IntStream, DoubleStream, and LongStream were added as part of Java 8 to handle primitive operations efficiently.

Let’s try to understand the need for primitive specialization with one example. Consider a Book class


@Setter
@Getter
public class Book {
  private String name;
  private Category category;
  private double price;
  private String author;
  private String publisher;
}

To find the accumulative price of all the books, you can do something like:


static double priceOfAllBooks(List<Book> books) {                              
  Double allBooksPrice = 
  books.stream()
  .map(Book::getPrice)
  .reduce(0d, Double::sum);

  return allBooksPrice;                                                                     
}                                                                                           

In the above example, you first transform the stream of the book into the stream of Double by calling map(Book::getPrice) then the sum is calculated by calling terminal operation reduce(0d, Double::sum).

You can simplify this example by transforming Stream<Book> to DoubleStream as:


static double priceOfAllBooks(List<Book> books) {                   
  double allBooksPrice = 
  books.stream()
  .mapToDouble(Book::getPrice)
  .sum();  

  return allBooksPrice;                                                     
}                                                                           

In the above example mapToDouble is an intermediate operation, which returns a DoubleStream. The DoubleStream is a stream of double, which defines handy methods such as sum,min,max,etc.

Java has three primitive streams – IntStream, DoubleStream, LongStream to perform stream operation int, double and long primitive type.

Creating Primitive Streams

You can create a primitive stream from a regular stream using methods from the Stream class. For example, mapToDouble method converts a stream to DoubleStream. Similarly, the Stream class also has mapToInt and mapToLong method.

Let’s look at the example of creating primitive streams.

Of

You can create a Sequential ordered Stream using the static factory method of as:


IntStream intOne = 
  IntStream.of(1);

IntStream intOneTwo = 
  IntStream.of(1,2);

DoubleStream doubleOne = 
  DoubleStream.of(1);

LongStream longOneTwo = 
  LongStream.of(1,2); 

Range

You can use the range method from primitive specialization to create a sequential ordered stream.


IntStream oneToNine = 
  IntStream.range(1, 10);

// Range inclusive
IntStream oneToTen = 
  IntStream.rangeClosed(1, 10);

Generate

You can create an infinite sequential unordered primitive stream using by using the generate method of primitive specialization stream. This is suitable for generating constants streams, streams of random numbers, etc.


IntStream tenOnes = 
  IntStream.generate(() -> 1).limit(10);

DoubleStream tenRandomDouble = 
  DoubleStream
  .generate(() -> new Random()
  .nextDouble()).limit(10);

Generating Fibonacci numbers

You can use generate method for some interesting use cases. For example, the Fibonacci numbers can be generated as:


public class Fibonacci {
  private int prev = 0;
  private int curr = 1;

  private int next() {
    int temp = prev + curr;
    prev = curr;
    curr = temp;
    return curr;
  }

  public IntStream stream() {
    return IntStream
    .generate(this::next);
  }
}

//Caller
Fibonacci fibonacci = 
  new Fibonacci();

IntStream fibStream = 
  fibonacci.stream().limit(10);

Iterate

You can create an infinite sequential ordered stream using the iterate method. In IntStream class, the iterate method is defined as IntStream iterate(final int seed, final IntUnaryOperator f).

The iterate method produces an infinite stream by applying function f to an initial seed. This produces a Stream consisting of seed, f(seed),f(f(seed)), etc.


IntStream evenNumbers = 
  IntStream
  .iterate(0, n -> n + 2)
  .limit(10);

Other ways of creating Streams

There are many other ways a Stream can be created. For instance, you can combine two streams to create a new stream. Let’s look at a few examples.

Concat

You can use concat operation of the stream to create a new stream. The elements of the new stream are all the elements of the first stream followed by all the elements of the second stream. The new stream is ordered if both of the input streams are ordered, and parallel if either of the input streams is parallel. If the resulting stream is closed, then both input streams are closed as well.


Stream<Integer> prime = 
  Stream
  .concat(Stream.of(2, 3), 
    Stream.of(5, 7, 11));

We need to exercise caution with nested concatenation, Stream.concat(Stream.of(..), Stream(Stream.of(..),Stream.of(..)), as it can result in a deep call chain or even worse StackOverflowError.

String

Java 8 added utility methods to create a stream from the String object.

Lines

You can create a stream of lines separated by line terminator as:


static Stream<String> lines() {                       
  return "Line separated by newline.\nAnother line."
  .lines(); 
}                                               

The above example creates a stream consisting of two elements:

  1. Line separated by newline.
  2. Another line.

Chars

You can use chars method of String class to create IntStream of chars, as:


static IntStream chars() { 
  return "XYZ".chars();            
}                                  

Random

The Random class has a couple of useful methods to generate streams of random numbers of primitive specialization types.


// Infinite Stream                                  
IntStream randomInts = 
  new Random().ints();
         
// Fixed Size Stream                                
IntStream tenRandomInts = 
  new Random().ints(10);   
 
// Infinite Stream                                  
DoubleStream randomDoubles = 
  new Random().doubles();

// Fixed Size Stream                                
DoubleStream tenRandomDoubles = 
  new Random().doubles(10);

// Infinite Stream                                  
LongStream randomLongs = 
  new Random().longs();      

// Fixed Size Stream                                
LongStream tenRandomLongs = 
  new Random().longs(10); 

Summary

Streams let us do computation on the collection of data in a declarative way. You can create a stream pipeline to perform a computation. A stream pipeline consists of :

  • a source
  • zero or more intermediate operations
  • a terminal operation

There are many ways a stream can be created. For instance, you can create steam from an array, collection, or individual elements. You can even create a stream using generate, iterate, or builder method of the Stream class.

Java 8 also added specialized primitive streams. For instance, IntStream, DoubleStream, and LongStream are primitive streams.

The primitive stream can be created from individual elements and using the range method of the primitive stream class. Similarly, the primitive stream can be created using a builder, iterate or generate method.

Tags: java
Previous Post

Running microservice applications locally using Docker and Kubernetes

Next Post

Java Streams: Stream Operation with Examples

Pankaj

Pankaj

Software Architect @ Schlumberger ``` Cloud | Microservices | Programming | Kubernetes | Architecture | Machine Learning | Java | Python ```

Related Posts

Java Streams: Stream Operation with Examples
Java

Java Streams: Stream Operation with Examples

May 8, 2021
Garbage Collection
Java

Super Fast Garbage Collectors in Java

September 14, 2020
Calculus
Java

Functional Programming in Java

September 7, 2020

Discussion about this post

Recent Articles

gRPC Bidirectional Streaming with Code Example

gRPC Bidirectional Streaming with Code Example

February 17, 2023
gRPC Client Streaming

gRPC Client Streaming

January 20, 2023
Distributed transaction in microservices using Saga

Distributed Transactions in Microservices: implementing Saga with Temporal

November 8, 2022
Temporal Workflow Orchestration

Workflow Orchestration with Temporal and Spring Boot

October 29, 2022
  • Trending
  • Comments
  • Latest
Deploying a RESTful Spring Boot Microservice on Kubernetes

Deploying a RESTful Spring Boot Microservice on Kubernetes

August 18, 2021
Temporal Workflow Orchestration

Workflow Orchestration with Temporal and Spring Boot

October 29, 2022
gRPC Interceptor: unary interceptor with code example

gRPC Interceptor: unary interceptor with code example

April 30, 2022
Microservices inter-process communication using gRPC

gRPC for microservices communication

August 29, 2021
Calculus

Functional Programming in Java

0
Java Streams: stream creation with examples

Java Streams: stream creation with examples

0
Garbage Collection

Super Fast Garbage Collectors in Java

0
Java Streams: Stream Operation with Examples

Java Streams: Stream Operation with Examples

0
gRPC Bidirectional Streaming with Code Example

gRPC Bidirectional Streaming with Code Example

February 17, 2023
gRPC Client Streaming

gRPC Client Streaming

January 20, 2023
Distributed transaction in microservices using Saga

Distributed Transactions in Microservices: implementing Saga with Temporal

November 8, 2022
Temporal Workflow Orchestration

Workflow Orchestration with Temporal and Spring Boot

October 29, 2022
Facebook Twitter Pinterest

TECHDOZO

Simplifying modern tech stack!

Browse by Category

  • Bitesize
  • GraphQL
  • gRPC
  • Java
  • Kubernetes
  • Microservices
  • Spring Boot

Recent Articles

gRPC Bidirectional Streaming with Code Example

gRPC Bidirectional Streaming with Code Example

February 17, 2023
gRPC Client Streaming

gRPC Client Streaming

January 20, 2023

© 2023 Techdozo.

No Result
View All Result
  • Home
  • gRPC
  • Kubernetes
  • Microservices
  • GraphQL

© 2023 Techdozo.

Welcome Back!

Sign In with Google
OR

Login to your account below

Forgotten Password?

Retrieve your password

Please enter your username or email address to reset your password.

Log In