What is a Stream ?
A stream is a sequence of objects on which various methods can be applied to get the desired results.
Stream is not a data structure.
How to work with Stream ?
Step 1: Create a Stream.
Step 2: Perform intermediate operation on the initial stream to transform it to another stream and do further intermediate operation on it.
Step 3: Perform terminal operation on the final stream.
How to create a Stream ?
Below are the some of the ways to create a stream:
Stream stream1=Stream.of(1,2,3,4); Stream stream2=Stream.of(array); Stream stream3=Stream.of(list); Stream stream4=list.stream();//sequential stream will be created. Stream stream5=list.parallelStream();//parallel stream will be created. Stream stream6=Arrays.asList(1,2,3,4).stream(); Stream stream7=Stream.generate( () -> return "abc";); Stream stream8=Stream.iterate("abc", (i) -> i);
What are Intermediate Operations ?
Intermediate operations return another Stream which allows you to call multiple operations in the form of a query.
Stream intermediate operations do not get executed until a terminal operation is invoked.
All Intermediate operations are lazy, so they’re not executed until a result of a processing is actually needed.
Traversal of the Stream does not begin until the terminal operation of the pipeline is executed.
Here is the list of all Stream intermediate operations:
filter() map() flatMap() distinct() sorted() peek() limit() skip()
What are Terminal Operations ?
These are the operations that are at the end of the statement. Below are some of the methods:
1. collect: The collect method is used to return the result of the intermediate operations performed on the stream.
List number = Arrays.asList(2,3,4,5,3); Set square = number.stream().map(x -> x*x).collect(Collectors.toSet()); List square = number.stream().map(x-> x*x).collect(Collectors.toList());
2. forEach: The forEach method is used to iterate through every element of the stream.
List number = Arrays.asList(2,3,4,5); number.stream().map(x -> x*x).forEach(y-> System.out.println(y));
3. reduce: The reduce method is used to reduce the elements of a stream to a single value.
The reduce method takes a BinaryOperator as a parameter.
List number = Arrays.asList(2,3,4,5); //In below example, ans variable is assigned 0 as the initial value and i is added to it: int even = number.stream().filter(x -> x%2==0).reduce(0,(ans,i)-> ans+i); //In below example, doesn’t make much sense of this statement. Before printing it you are collecting it as a Set, but saving it to a Set: number.stream().map(x->x*x).collect(Collectors.toSet()).forEach(s -> System.out.println(s));
How to iterate a stream ?
stream1.forEach(s -> System.out.println(s));
Is there any other way to iterate a stream ?
stream1.forEach(new MyConsumer());
import java.util.function.Consumer; class MyConsumer implements Consumer<Integer>{ public void accept(Integer i){ System.out.println(i); } }
How does parallel stream work interanally, does it uses threads ?
How to convert a Stream to Collection object ?
List list=(List)stream.collect(Collectors.toList());
How to convert a Stream to Array ?
Integer[] intArray = (Integer[])stream.toArray(s -> new Integer[s]);
Lets see some of the programs using Streams. These are very important for an interview perspective:
How to print 10 random numbers ?
new Random().ints().limit(10).forEach(s -> System.out.println(s));
How to print 10 even numbers staring from 1 ?
Stream.iterate(1, c->c+1) .filter(s -> s%2==0) .limit(10) .forEach(k -> System.out.println(k));
How to iterate over a list of integers and find out sum of all the integers greater than 10 ?
list.stream().filter(i -> i > 10).mapToInt(i -> i).sum(); //list is an ArrayList object.
How to print only the salary from all the Employee objects in a ArrayList object ?
List<Employee> empList=new ArrayList<>(); //Make sure to use generics for the empList object, otherwise the below line will give CTE. Why ? //add code here to add Employee objects to empList object. empList.stream().filter(s2->s2.getSalary() > 0).forEach(s -> System.out.println(s.salary)); //Another way below: empList.stream().filter(s2->s2.getAge() > 0).map(s -> s.age).forEach(s3 -> System.out.println(s3));