DEV Community

Code Craft Club
Code Craft Club

Posted on • Originally published at Medium

Streams in Java made super simple with examples! — An Easy Beginner’s Guide!

Data structures such as arrays, sets, etc. are commonly used to store and manipulate data in Java. However, iterating over these data structures and performing operations on them can be cumbersome. Java 8 introduced a new feature called Streams, which allows us to process data in a declarative and functional way making it more safer and concise.

In this blog, we will discuss about the concept and working of Streams in Java with a delightful analogy that makes it super easy!

Stream

A stream is a way of processing a sequence of elements in a functional and declarative manner. A stream does not store the data itself, but only provides a view of the data source. This means that the data source is not modified by the stream operations.

Imagine Java Streams like a stream of vehicles passing through a toll gate. Each vehicle represents an element in the stream. Just as vehicles pass through a toll gate one by one, elements in a stream are processed sequentially or in parallel.

toll

Java provides a Stream interface in the java.util.stream package that defines the methods for creating and manipulating streams.

However, the Stream interface does not support primitive types such as int, long, and double. To use streams with these types, we need to use their corresponding wrapper classes Integer, Long, and Double.

Creating an Empty Stream

The Stream interface consists of a static and default method empty() that can be used to create an empty stream.

Creating an empty stream in Java is similar to having an empty toll lane at a toll gate. Just as an empty lane at a toll gate waits for vehicles to pass through, an empty stream in Java is ready to receive elements for processing. It serves as a placeholder, waiting to be filled with data before any operations can be performed on it.

empty stream

In the above code, we have created an empty stream using the default method empty().

Creating a Stream with Collections

In Java, we can create a Stream from a collection (such as a List, Set, or Map) using the stream() method. Here’s how we can create a Stream from various types of collections:

Syntax:

collection.stream()
Enter fullscreen mode Exit fullscreen mode

Example Syntax -

stream collec

In the above code, we have created a list of Strings and assigned it to myList variable. From the list of Strings we have created a stream and assigned it to the streamFromList. Here, the stream does not occupy any memory, instead it just provides a way to access the original elements.

Direct creation of Stream

In Java, the Stream.of() method is a convenient way to create a Stream from a sequence of elements. It allows us to create a Stream directly from individual elements or an array of elements without needing a collection.

Here’s how you can use the Stream.of() method:

Stream.of(list of elements);
Enter fullscreen mode Exit fullscreen mode

Example Syntax -

Streamof

How to work with Streams?

Working with Streams involves the usage of some operations. These operations are basically divided as Intermediate Operations and Terminal Operations. Let us understand these terms easily using the same analogy of a Toll Booth.

Intermediate Operations

Intermediate operations are like toll booth workers who filter, transform, or manipulate the vehicles before they leave the toll gate.

These intermediate operations always produces a new stream as output after performing the specified operations.

toll2

There are different types of intermediate operations:

  • filter()
  • map()
  • sorted()
  • distinct()

Filter()

Filtering allows us to select elements based on a certain condition.

filter

Output -

Bike
Truck
Cycle
Enter fullscreen mode Exit fullscreen mode

In the above code, we have created a stream of vehicles, filtered the names that have more than 3 letters and displayed the resultant names on the console.

Map()

Mapping helps to perform an operation on each element of the stream.

Image map

Output -

15
25
35
45
Enter fullscreen mode Exit fullscreen mode

In the above code, the lambda expression eachNumber -> eachNumber + 5 is being used to map each element and increment each number by 5.

Sorted()

Sorting arranges elements in a specified order.

Image sorted

Output -

100
500
700
800
Enter fullscreen mode Exit fullscreen mode

In the above code, the sorted() method has arranged the elements of the numbers stream in ascending order.

Distinct()

Distinct method removes the duplicate elements from the stream.

Image distinct

Output -

Apple
Mango
Enter fullscreen mode Exit fullscreen mode

In the above code, the distinct() method has removed the duplicate strings from the stream.

Terminal Operations

Terminal operations are like the toll booth itself - once a vehicle passes the toll booth, it can't go back. Similarly, terminal operations are the final actions on a stream.

A terminal operation is a stream operation that consumes the elements of a stream and produces a result.

Image toll

Types of terminal operations include:

  • forEach
  • reduce
  • count

ForEach()

This method is used for performing an action on each element.

Image foreach

Output -

Apple
Mango
Banana
Kiwi
Enter fullscreen mode Exit fullscreen mode

In the above code, the forEach() method is used to display the elements of the resultant stream on the console.

reduce()

The reduce() is a terminal operation that combines all elements of the stream into a single result. It takes two parameters: an identity value and a Binary Operator (a function that takes two elements and produces a single result). The reduce() operation repeatedly applies the Binary Operator to the current result and each element of the stream until all elements have been processed, producing a final result.

Let’s take an example to find the sum of all numbers in a list.

Image reduce

Output -

15
Enter fullscreen mode Exit fullscreen mode

In this example, the reduce operation starts with an initial value of 0 (identity). For each element in the stream, it adds the element to the current sum (a + b). The result is the sum of all elements in the stream, which is 15 in this case.

Use Case - reduce() is useful when you want to aggregate elements of the stream into a single value, such as finding the sum, maximum, minimum, or concatenating strings.

count()

The count() method returns a long integer that indicates the number of elements present in the stream.

Image count

Output -

3
Enter fullscreen mode Exit fullscreen mode

In the above code, the vehicles that has greater than 3 letters were filtered and the count() method is used to get the number of vehicles in the resultant stream.

ForEach() vs Map()

Wondering what’s the difference between forEach() and map() methods? Though both these operations seem to be very similar, however they behave and operate differently.

The forEach() method works similar to the map(). It iterates over the elements in the stream and performs the specified operation on each element.

However, the only difference between forEach() and map() is -

  • The forEach() method does not return any stream while the map() method returns a stream.
  • forEach is used for performing actions on elements, whereas map transforms elements.

Use Case of map(): Use map when you want to transform the elements of the Stream from one form to another. For example, transforming strings to uppercase, converting objects to specific properties, or performing any other form of transformation.

Use Case of forEach(): Use forEach when you want to perform an action (such as printing, logging, or updating external states) for each element in the Stream.

Closing Thoughts:

Thank you for reading our blog. We appreciate your time and interest in our content. If you have any questions, feedback, or topics you’d like us to cover in our future articles, please feel free to leave a comment below. Your input is valuable, and it helps us create content that matters to you.

Stay connected with us for more insightful articles on various topics related to technology, programming, and much more.

Happy coding!

Top comments (0)