Java 8 Streams – Streams in Java With Examples

What are Streams?

  •  Sequence of objects supporting multiple methods.

Features:

  • Stream is not a data structure and does not store elements.
  • Source of stream remains unmodified after operations are performed.
  • Streams perform operation over the collection but actually does not modify the underlying collection.
  • Laziness, evaluates only when requried. (When Terminal operation is identified)
  • Visitation of elements only once, to revisit we need new stream. If same stream used it throws IllegalStateException.

Laziness:

  • Intermediate operations are not evaluated until terminal operation invoked.
  • Each intermediate operation creates a new stream and process and returns stream.
  • When terminal invoked, traversal begins and operations are performed one by one.
  • Parallel streams does not evaluate only by one but simultaneously based on available ones.

Intermediate and Terminal Operations:

  • Every stream will perform Intermediate and Terminal Operations.
  • There can be any number of Intermediate operations but only one Terminal operation
  • Streams will not process until it reaches the Terminal operation, once it reaches Terminal operation then only stream processing will start.
  • It is mandatory for a stream to have Terminal operation for the stream to process or Streams will not process.
Intermediate Operations Terminal Operations
filter toArray()
map Collect
flatmap Count
distinct reduce
sorted forEach
limit forEachOrdering
skip min
peek max
Anymatch
allmatch
nonematch
findfirst

findany

 

let us see some examples of some Intermediate and Terminal operations,

class Student {
	
	String studentName;
	List<String> studentSubjects;
	int salary;

	/**
	 * @return the salary
	 */
	public int getSalary() {
		return salary;
	}

	/**
	 * @param salary the salary to set
	 */
	public void setSalary(int salary) {
		this.salary = salary;
	}

	public String getStudentName() {
		return studentName;
	}

	public void setStudentName(String studentName) {
		this.studentName = studentName;
	}

	public List<String> getStudentSubjects() {
		return studentSubjects;
	}

	public void setStudentSubjects(List<String> studentSubjects) {
		this.studentSubjects = studentSubjects;
	}

	@Override
	public String toString() {
		return "Student [studentName=" + studentName + ", studentSubjects=" + studentSubjects + "]";
	}
}

Let us create a main method to populate the object,

public class Operations {

	public static void main(String[] args) {
		List<String> strList1 = Arrays.asList("Zebra","Alpha", "Beta", "Charlie", "Delta", "Alp", "Alphine", "Alphabet");
		List<Integer> intList = Arrays.asList(10,35,44,32,1);
		Student student1 = new Student();
		student1.setStudentName("Alpha Student");
		
		List<String> stud1Subj = new LinkedList<String>();
		stud1Subj.add("Computers");
		stud1Subj.add(" Information Technology");
		student1.setStudentSubjects(stud1Subj);
		student1.setSalary(10000);
		
		
		Student student2 = new Student();
		student2.setStudentName("Beta Student");
		List<String> stud2Subj = new LinkedList<String>();
		stud2Subj.add("Java");
		stud2Subj.add(" Spring");
		student2.setStudentSubjects(stud2Subj);
		student2.setSalary(200000);
		
		
		List<Student> studList = Arrays.asList(student1, student2);
		System.out.println("==================== STUDLIST========================");
		System.out.println(studList);
		System.out.println();
        }
}

Output:

==================== STUDLIST========================
[Student [studentName=Alpha Student, studentSubjects=[Computers, Information Technology]], Student [studentName=Beta Student, studentSubjects=[Java, Spring]]]

 



Map vs FlatMap:
Map
produces one output value for each input value

FlatMap takes one input value and provides arbitrary number of values. In short helps to flatten a Collection<Collection<T>> into a Collection<T>.

Now let us see an example,

		List<List<String>> mapList = studList.stream().map(Student::getStudentSubjects).collect(Collectors.toList());
		System.out.println("========== Map in Stream ==========");
		mapList.forEach(System.out::print);
		System.out.println();
		
		List<String> flatmapList = studList.stream().map(Student::getStudentSubjects).flatMap(Collection::stream).collect(Collectors.toList());
		System.out.println("========== FlatMap in Stream ==========");
		flatmapList.forEach(System.out::print);

Output:



Distinct:
To get unique values from the collection.

		List<String> distincts = strList1.stream().distinct().collect(Collectors.toList());
		System.out.println("========== Distinct ==========");
		distincts.forEach(x -> System.out.print(x+" "));
		System.out.println();

Output:



Limit:
Limit result to certain number of records. In the below example we are limiting the total number of records to 3.

		List<String> limits = strList1.stream().limit(3).collect(Collectors.toList());
		System.out.println("========== LIMIT ==========");
		limits.forEach(x -> System.out.print(x+" "));
		System.out.println();

Output:



Peek:
When we have to view any value in the middle of Stream operations, We can use peek.

		Set<String> peekValue = strList1.stream().filter(x -> x.equals("Alpha")).peek(s -> System.out.println(s)).collect(Collectors.toSet());
		System.out.println("========== PEEK ==========");
		peekValue.forEach(x -> System.out.print(x+" "));
		System.out.println();

Output:



Skip:
Skips the specific number of elements. In the below example, first 3 elements are skipped and values are printed from 4th element.

		List<String> skipList = strList1.stream().skip(3).collect(Collectors.toList());
		System.out.println("========== Skip ==========");
		skipList.forEach(x -> System.out.print(x+" "));
		System.out.println();

Output:



Sorting:
We can do sorting using Streams, reverse sorting and natural order sorting. We had done reverse and natural order sorting in the below example.

		List<String> sorting = strList1.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
		System.out.println("========== Sorted Reverse ==========");
		sorting.forEach(x -> System.out.print(x+" "));
		System.out.println();
		List<String> sorting1 = strList1.stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList());
		System.out.println("========== Sorted Natural Order ==========");
		sorting1.forEach(x -> System.out.print(x+" "));
		System.out.println();
		List<String> sorting2 = strList1.stream().sorted().collect(Collectors.toList());
		System.out.println("========== SORTING ==========");
		sorting2.forEach(x -> System.out.print(x+" "));
		System.out.println();

Output:



Count:
To count the number to elements in the collection.

		long num = strList1.stream().count();
		System.out.println("========== Count ==========");
		System.out.println(num);
		System.out.println();

Output:


Min And Max:
To find the Minimum and Maximum from collection. Below are few examples,

		System.out.println("==========min and max================");
		int max = intList.stream().max(Integer::compare).get();
		System.out.println("Max value is: "+max);
		int min = intList.parallelStream().min(Integer::compare).get();
		System.out.println("Min value is: "+min);
		int min1 = intList.parallelStream().max(Comparator.reverseOrder()).get();
		System.out.println("Min value 1 is: "+min1);
		System.out.println();

Output:

 


ForEach vs Stream.forEach:
Both are used for Iterating a collection, The difference between them are,

forEach – Does not maintain order
Stream.forEach – Maintains Order

		System.out.println("===========for each vs stream.foreach============");
		strList1.forEach(s -> System.out.print(s+" "));
		System.out.println();
		strList1.parallelStream().forEach(s -> System.out.print(s+" "));
		System.out.println();

Output:

Reduce:
Used to perform operations are multiple values and returns a single result. In the below example we have used addition.

		int reduce = intList.parallelStream().reduce((x1,x2)-> x1+x2).get();
		System.out.println("======= Reduce ===========");
		System.out.println("Reduce is: "+reduce);
		System.out.println();

Output:



Filter, FindAny, FindFirst, AnyMatch and AllMatch:
Filter:
Similar to if condition to search or find any value
FindAny:
Returns an object which may or may not contain a non-null value
FindFirst:
Finds the first element when it is matched
AnyMatch:
Return true if atleast one element matches the condition
AllMatch: 
Returns true if all elements in the stream are matched (satisfies the condition)

		//Filter operation
		System.out.println("======= Filter ===========");
		Optional<String> filterValue = strList1.parallelStream().filter(x -> x.equalsIgnoreCase("delta")).findFirst();
		System.out.println("Filter with findfirst: "+filterValue);
		System.out.println();
				
		//Stream with Filter
		
		String filterContains = strList1.stream().filter(s -> s.equalsIgnoreCase("charlie")).findAny().get();
		System.out.println("Filter with findAny: "+filterContains);
		System.out.println();
		
		System.out.println("======= Find Any ===========");
		boolean findAny = strList1.stream().filter(s -> s.equalsIgnoreCase("che")).findAny().isPresent();
		System.out.println("FindAny isPresent: "+findAny);
		System.out.println();
		
		
		String findAnyTest = strList1.stream().filter(s -> s.contains("Alp")).findAny().get();
		System.out.println("Find Any with value: "+findAnyTest);
		System.out.println();
		
		System.out.println("======= Find First ===========");
		String findFirstTest = strList1.stream().filter(s -> s.contains("Alp")).findFirst().get();
		System.out.println("Find first value: "+findFirstTest);
		System.out.println();
		
		System.out.println("======= All Match ===========");
		boolean allMatch = strList1.stream().allMatch(s -> s.equalsIgnoreCase("Alp"));
		System.out.println("All Match : "+allMatch);
		System.out.println();
		
		System.out.println("======= Any Match ===========");
		boolean anyMatch = strList1.stream().anyMatch(s -> s.equalsIgnoreCase("Alp"));
		System.out.println("Any Match : "+anyMatch);
		System.out.println();

 

 Complete Code:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

class Student {
	
	String studentName;
	List<String> studentSubjects;
	int salary;

	/**
	 * @return the salary
	 */
	public int getSalary() {
		return salary;
	}

	/**
	 * @param salary the salary to set
	 */
	public void setSalary(int salary) {
		this.salary = salary;
	}

	public String getStudentName() {
		return studentName;
	}

	public void setStudentName(String studentName) {
		this.studentName = studentName;
	}

	public List<String> getStudentSubjects() {
		return studentSubjects;
	}

	public void setStudentSubjects(List<String> studentSubjects) {
		this.studentSubjects = studentSubjects;
	}

	@Override
	public String toString() {
		return "Student [studentName=" + studentName + ", studentSubjects=" + studentSubjects + "]";
	}
}


public class Operations {

	public static void main(String[] args) {
		List<String> strList1 = Arrays.asList("Zebra","Alpha", "Beta", "Charlie", "Delta", "Alp", "Alphine", "Alphabet");
		List<Integer> intList = Arrays.asList(10,35,44,32,1);
		Student student1 = new Student();
		student1.setStudentName("Alpha Student");
		
		List<String> stud1Subj = new LinkedList<String>();
		stud1Subj.add("Computers");
		stud1Subj.add(" Information Technology");
		student1.setStudentSubjects(stud1Subj);
		student1.setSalary(10000);
		
		
		Student student2 = new Student();
		student2.setStudentName("Beta Student");
		List<String> stud2Subj = new LinkedList<String>();
		stud2Subj.add("Java");
		stud2Subj.add(" Spring");
		student2.setStudentSubjects(stud2Subj);
		student2.setSalary(200000);
		
		
		List<Student> studList = Arrays.asList(student1, student2);
		System.out.println("==================== STUDLIST========================");
		System.out.println(studList);
		System.out.println();
		List<List<String>> mapList = studList.stream().map(Student::getStudentSubjects).collect(Collectors.toList());
		System.out.println("========== Map in Stream ==========");
		mapList.forEach(System.out::print);
		System.out.println();
		
		List<String> flatmapList = studList.stream().map(Student::getStudentSubjects).flatMap(Collection::stream).collect(Collectors.toList());
		System.out.println("========== FlatMap in Stream ==========");
		flatmapList.forEach(System.out::print);
		
		System.out.println();
		
		List<String> distincts = strList1.stream().distinct().collect(Collectors.toList());
		System.out.println("========== Distinct ==========");
		distincts.forEach(x -> System.out.print(x+" "));
		System.out.println();
		
		List<String> limits = strList1.stream().limit(3).collect(Collectors.toList());
		System.out.println("========== LIMIT ==========");
		limits.forEach(x -> System.out.print(x+" "));
		System.out.println();
		
		Set<String> peekValue = strList1.stream().filter(x -> x.equals("Alpha")).peek(s -> System.out.println(s)).collect(Collectors.toSet());
		System.out.println("========== PEEK ==========");
		peekValue.forEach(x -> System.out.print(x+" "));
		System.out.println();
		
		
		List<String> skipList = strList1.stream().skip(3).collect(Collectors.toList());
		System.out.println("========== Skip ==========");
		skipList.forEach(x -> System.out.print(x+" "));
		System.out.println();
		
		List<String> sorting = strList1.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
		System.out.println("========== Sorted Reverse ==========");
		sorting.forEach(x -> System.out.print(x+" "));
		System.out.println();
		List<String> sorting1 = strList1.stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList());
		System.out.println("========== Sorted Natural Order ==========");
		sorting1.forEach(x -> System.out.print(x+" "));
		System.out.println();
		List<String> sorting2 = strList1.stream().sorted().collect(Collectors.toList());
		System.out.println("========== SORTING ==========");
		sorting2.forEach(x -> System.out.print(x+" "));
		System.out.println();
		
		long num = strList1.stream().count();
		System.out.println("========== Count ==========");
		System.out.println(num);
		System.out.println();
		
		System.out.println("==========min and max================");
		int max = intList.stream().max(Integer::compare).get();
		System.out.println("Max value is: "+max);
		int min = intList.parallelStream().min(Integer::compare).get();
		System.out.println("Min value is: "+min);
		int min1 = intList.parallelStream().max(Comparator.reverseOrder()).get();
		System.out.println("Min value 1 is: "+min1);
		System.out.println();
		
		System.out.println("======= for each ===========");
		strList1.parallelStream().forEach(x -> System.out.print(x+" "));
		System.out.println();
		System.out.println("======= for each Ordering===========");
		strList1.parallelStream().forEachOrdered(x -> System.out.print(x+" "));
		System.out.println();
		
		int reduce = intList.parallelStream().reduce((x1,x2)-> x1+x2).get();
		System.out.println("======= Reduce ===========");
		System.out.println("Reduce is: "+reduce);
		System.out.println();
		
		System.out.println("===========for each vs stream.foreach============");
		strList1.forEach(s -> System.out.print(s+" "));
		System.out.println();
		strList1.parallelStream().forEach(s -> System.out.print(s+" "));
		System.out.println();
		
		//Filter operation
		System.out.println("======= Filter ===========");
		Optional<String> filterValue = strList1.parallelStream().filter(x -> x.equalsIgnoreCase("delta")).findFirst();
		System.out.println("Filter with findfirst: "+filterValue);
		System.out.println();
				
		//Stream with Filter
		
		String filterContains = strList1.stream().filter(s -> s.equalsIgnoreCase("charlie")).findAny().get();
		System.out.println("Filter with findAny: "+filterContains);
		System.out.println();
		
		System.out.println("======= Find Any ===========");
		boolean findAny = strList1.stream().filter(s -> s.equalsIgnoreCase("che")).findAny().isPresent();
		System.out.println("FindAny isPresent: "+findAny);
		System.out.println();
		
		
		String findAnyTest = strList1.stream().filter(s -> s.contains("Alp")).findAny().get();
		System.out.println("Find Any with value: "+findAnyTest);
		System.out.println();
		
		System.out.println("======= Find First ===========");
		String findFirstTest = strList1.stream().filter(s -> s.contains("Alp")).findFirst().get();
		System.out.println("Find first value: "+findFirstTest);
		System.out.println();
		
		System.out.println("======= All Match ===========");
		boolean allMatch = strList1.stream().allMatch(s -> s.equalsIgnoreCase("Alp"));
		System.out.println("All Match : "+allMatch);
		System.out.println();
		
		System.out.println("======= Any Match ===========");
		boolean anyMatch = strList1.stream().anyMatch(s -> s.equalsIgnoreCase("Alp"));
		System.out.println("Any Match : "+anyMatch);
		System.out.println();
		
	}

}

 

 

 

By Sri

Leave a Reply

Your email address will not be published. Required fields are marked *