Streams in Java

Streams are introduced as part of Java 8 release, Streams provide a better handling/processing way for the Collection data. If we want to apply some kind of operations on all the objects or specific objects of Collection then we can go for Streams.

In layman terms, Consider Solid ice as collection/array which is the base, now when we make the ice to flow through a pipe by melting it.

We would be able to get every single drop of the water at the end of the pipe, We can use this water drops based on our need like for paint mixing, drinking, cleaning, adding color to water. The process of melting the ICE to water is done with streams.

In the below example, we are going to filter out the even number from a List.

List<Integer> li = new ArrayList<Integer>();
li.add(2);
li.add(5);
li.add(6);
li.add(9);
Till Java 1.7:

Till the Java 1.7 version, we have to use the loop and if block to process this kind of operation and then store back to a new list.

List<Integer> newList = new ArrayList<Integer>();
for (Integer item : li) {
	if (item % 2 ==0 ) {
		newList.add(item);
	}
}
System.out.println(newList);

streams-java-example

With Java 1.8 Version:

Streams concept is introduced in Java 1.8 version, streams basically combine the iterator with conditional statements. ( Below code, I have not explained but we will learn all of it.)

List<Integer> stLi = li.stream().filter(item->item%2==0).collect(Collectors.toList());
System.out.println(stLi);
Do not be scared of bit lengthy line, I will explain in a better way so that it will be a cake walk to you.

with-streams-collection-filter

Stream method in java

stream() is a default method present in the Collection Interface, stream() method is introduced in Java 8. stream() method creates a stream object on the collections for processing them.

Stream stObj = anyCollection.stream();
  • Stream - is an interface present in the java.utils package
  • stObj - is variable to hold the stream object
  • anyCOllection - nothing but any kind of collection present in Java like Set, List, Queue, etc.
  • stream() - stream() method create stream object for collections.

The main object of the stream() method to process the collection object, stream processing contains two major steps:

  • Configuration: configures how a collection should be modified, whether to apply an operation on all element or just to retrieve elements based on a certain condition. Configuration can be applied on collection using two methods 1. filter, 2. map
  • Processing: How the configures element should be stored

filter in the stream of Java

filter() method accepts a logic and applies the same logic on all the objects present in the collection. filter() method returns all the object that are satisfying the given logic. logic could be of Predicate or lambda function.

The filter() method returns all the elements which satisfy a condition and those will be in the form of Stream object.

Stream stObj = anyCollection.stream().filter(logic);
The number of elements present before and after applying the filter() method could be the same or lesser than compared before applying the filter() method

Let's create a program where we filter Integer values which are greater than 90.

List<Integer> li = new ArrayList<Integer>();
li.add(7);
li.add(96);
li.add(86);
li.add(94);
li.add(65);

List<Integer> stLi = li.stream().filter(item->item>90).collect(Collectors.toList());
System.out.println("Original list : " +li);
System.out.println("Filtered List : " +stLi);

filter-stream-java

collect(Collectors.toList()); used to collect the objects from the Stream object. We have covered collect() method in detail.

map method in streams of Java

If we want to manipulate every item present in the collection then we can use the map() method. map method applies given operation on all the elements present in the collection. The number of elements will not change before and after applying the map() method.

Stream stObj = anyCollection.stream().map(operation);

The operation could be a function or a lambda expression.

public static void main(String[] args) {
List<Integer> li = new ArrayList<Integer>();
li.add(7);
li.add(96);
li.add(86);
li.add(94);
li.add(65);

List<Integer> stLi = li.stream().map(item->item * 10).collect(Collectors.toList());
System.out.println("Original list : " +li);
System.out.println("Mapped List : " +stLi);

map-stream-java

collect(Collectors.toList()); used to collect the objects from the Stream object. We have covered the collect() method in detail.

collect() method in Java streams

collect() method collects all the objects from the Stream object, collected objects will be stored in the type of collection, the user has to provide the in what type of collection the result should be stored.

We can specify the collection type using the Collectors Enum, please be aware it is Collectors Enum, not Collector Interface.

Ther different types and different operation are present in the Collectors Enum, but most of the time we will be settled with Collectors.toList(), Collectors.toSet(), Collectors.toMap().

List<Integer> li = new ArrayList<Integer>();
li.add(7);
li.add(96);
li.add(86);
li.add(94);
li.add(65);

List<Integer> stLi = li.stream().map(item->item * 10).collect(Collectors.toList());
System.out.println("Original list : " +li);
System.out.println("Mapped List : " +stLi);
// storing the value in set
Set<Integer> setType = li.stream().map(item->item * 10).collect(Collectors.toSet());
System.out.println("Mapped Set : " +setType);

collect-stream-method-java

Count() method in streams:

Along with the collect() method, there are few other methods are also present, one which is count() method which will give us the number of objects present in the Stream object.

List<Integer> li = new ArrayList<Integer>();
li.add(7);
li.add(96);
li.add(86);
li.add(94);
li.add(65);

long stLi = li.stream().map(item->item * 10).count();
System.out.println("Number of object : " +stLi);

count-method-stream-java

sorted() method in Java Stream

sorted() method will sort the objects in the Stream Object, by default, sorted() method follows natural sort order (ascending). Passing a.compareTo(b) will generate ascending order

If we want to have customized sorting order or descending order then we need to provide a comparator for the sorted() method.

Descending order also can be achieved by adding a minus (-) to the ascending order -a.compareTo(b)

List<Integer> li = new ArrayList<Integer>();
li.add(7); 
li.add(96);
li.add(86);
li.add(94);
li.add(65);

List<Integer> stLi = li.stream().map(item->item * 10)
		.sorted().collect(Collectors.toList());
System.out.println("Default/Ascending sort : " +stLi);

List<Integer> descSort = li.stream().map(item->item * 10)
		.sorted((a,b)->b.compareTo(a)).collect(Collectors.toList());
System.out.println("Descending sort : " +descSort);

List<Integer> descSortMinus = li.stream().map(item->item * 10)
		.sorted((a,b)->-a.compareTo(b)).collect(Collectors.toList());
System.out.println("Descending sort using minus: " +descSort);

sorted-method-streams-java

min() and Max() in stream of Java

min() value fetches the minimum value present in the Stream Object, max() method bring the maximum value present in the Stream Object. But the user has to provide the comparator to these methods to calculate the min and max value present in the Stream.

List<Integer> li = new ArrayList<Integer>();
li.add(7);
li.add(96);
li.add(86);
li.add(94);
li.add(65);

Integer min = li.stream().min((a,b)->a.compareTo(b)).get();
System.out.println("Min Value sort : " +min);

Integer max = li.stream().max((a,b)->a.compareTo(b)).get();
System.out.println("Max Value sort : " +max);

min-max-value-stream-java

My Understanding: When we provide a comparator, the min() method sorts the stream object and fetches first value (i.e at 0th index).
Similarly, the max() method fetches the last value (at the end index) after sorting.

In the below example, I am passing a comparator to sort the stream in descending order,

List<Integer> li = new ArrayList<Integer>();
li.add(7);
li.add(96);
li.add(86);
li.add(94);
li.add(65);

Integer min = li.stream().min((a,b)->-a.compareTo(b)).get();
System.out.println("Min Value : " +min);

Integer max = li.stream().max((a,b)->-a.compareTo(b)).get();
System.out.println("Max Value : " +max);1
Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions