In this article, we will discuss various ways to create Stream in Java 1.8 version
1. Stream API method :
There are few useful methods available in Stream API which allows to create Stream from different input sources as listed below,
- of(T… values) :- Returns a sequential ordered stream whose elements are the specified values
- of(T t) :- Returns a sequential
Stream
containing a single element - empty() :- Returns an empty sequential
Stream
- generate(Supplier<T> s) :- Returns an infinite sequential unordered stream where each element is generated by the provided
Supplier
- iterate(T seed, UnaryOperator<T> f) :- Returns an infinite sequential ordered
Stream
produced by iterative application of a functionf
to an initial elementseed
, producing aStream
Note for example :-
- All Stream API methods listed above are static
- So, we can invoke directly as Stream.<staticMethodName>
- we will use another Stream method forEach() to iterate through each elements of Stream and at the same printing to console for output
1.1 of(T… values) :
- This method converts specified values into sequential ordered stream
- Method signature :- static Stream of(T… values)
StreamOfMethod.java
package net.bench.resources.stream.creation.example;
import java.util.stream.Stream;
public class StreamOfMethod {
public static void main(String[] args) {
// 1. square values
System.out.println("1. Stream of Integer values in varargs - Square values : \n");
Stream<Integer> stream1 = Stream.of(1, 4, 9, 16, 25, 36, 49, 64, 81, 100);
stream1.forEach(i -> System.out.println(i));
// 2. Integer array - fibonacci series
Integer[] intArray = {1, 2, 3, 5, 8, 13, 21, 34, 55, 89};
// 2.A create stream from Arrays
System.out.println("\n2. Stream of Integer Array - Fibonacci series : \n");
Stream<Integer> stream2 = Stream.of(intArray);
stream2.forEach(i -> System.out.println(i));
// 3. String Array
String[] strArray = {
"Vijay",
"Ajith",
"Kamal",
"Rajni",
"Suriya",
"Vikram",
"Dhanush"
};
// 3.A create stream from Arrays
System.out.println("\n3. Stream of String Array - Names : \n");
Stream<String> stream3 = Stream.of(strArray);
stream3.forEach(str -> System.out.println(str));
}
}
Output:
1. Stream of Integer values in varargs - Square values :
1
4
9
16
25
36
49
64
81
100
2. Stream of Integer Array - Fibonacci series :
1
2
3
5
8
13
21
34
55
89
3. Stream of String Array - Names :
Vijay
Ajith
Kamal
Rajni
Suriya
Vikram
Dhanush
1.2 of(T t) :
- This method converts specified single element into sequential stream
- Method signature :- static Stream of(T t)
StreamOfExample.java
package net.bench.resources.stream.creation.example;
import java.util.stream.Stream;
public class StreamOfExample {
public static void main(String[] args) {
// 1. Integer value
System.out.println("1. Converting single Integer element into Stream : ");
Stream<Integer> stream1 = Stream.of(100);
stream1.forEach(i -> System.out.println(i));
// 2. String value
System.out.println("\n2. Converting single String element into Stream : ");
Stream<String> stream2 = Stream.of("BenchResources.Net");
stream2.forEach(str -> System.out.println(str));
}
}
Output:
1. Converting single Integer element into Stream :
100
2. Converting single String element into Stream :
BenchResources.Net
1.3 empty() :
- This method returns an empty sequential
Stream
- When we try to print on console using Stream’s forEach() method, it won’t print anything to console because of empty Stream
- Method signature :- static Stream empty()
StreamEmptyMethod.java
package net.bench.resources.stream.creation.example;
import java.util.stream.Stream;
public class StreamEmptyMethod {
public static void main(String[] args) {
// empty Stream of String
Stream<String> stream = Stream.empty();
// displaying empty Stream of String
stream.forEach(System.out::println);
}
}
Output:
Nothing to display
1.4 generate(Supplier<T> s) :
- This method returns an infinite sequential unordered
Stream
- Each element is generated by the provided
Supplier
- Method signature :- static Stream generate(Supplier s)
StreamGenerateMethod.java
package net.bench.resources.stream.creation.example;
import java.util.Random;
import java.util.stream.Stream;
public class StreamGenerateMethod {
public static void main(String[] args) {
System.out.println("1. Generating first 5 Random Integer numbers : \n");
// 1. generating first 10 Random Integer number
Stream.generate(new Random()::nextInt) // 1. Supplier to generate Random Integer
.limit(5) // 2. intermediate operation to limit to 5 Integer numbers only
.forEach(System.out::println); // 3. terminal operation to print to console
System.out.println("\n2. Generating first 10 Random Integer"
+ " within boundary of 1000 : \n");
// 2. generating first 10 random Integer number within boundary of 1000
Stream.generate(() -> (new Random()).nextInt(1000)) // 1. Supplier to generate Random
.limit(10) // 2. intermediate operation to limit to 10 Integer numbers only
.forEach(i -> System.out.println(i)); // 3. terminal operation to print to console
System.out.println("\n3. Generating first 7 Random Double numbers : \n");
// 3. generating first 7 Random double number
Stream.generate(() -> (new Random()).nextDouble()) // 1. Supplier to generate Random
.limit(7) // 2. intermediate operation to limit to 7 double numbers only
.forEach(dbl -> System.out.println(dbl)); // 3. terminal operation to print to console
}
}
Output:
1. Generating first 5 Random Integer numbers :
1488825536
1390299139
356595619
941436694
-73125112
2. Generating first 10 Random Integer within boundary of 1000 :
404
906
13
29
896
241
277
5
682
672
3. Generating first 7 Random Double numbers :
0.050964282000754535
0.7763745295382452
0.9618087047680688
0.4930172107957018
0.47256213342121267
0.031847973917700334
0.5298139644068673
1.5 iterate(T seed, UnaryOperator<T> f) :
- This method returns an infinite sequential ordered
Stream
- Each element is generated by the provided
Function
rather UnaryOperator<T> whose 1 input argument and return-type is same starting from provided seed - Method signature :- static Stream iterate(T seed, UnaryOperator f)
StreamIterateMethod.java
package net.bench.resources.stream.creation.example;
import java.util.stream.Stream;
public class StreamIterateMethod {
public static void main(String[] args) {
System.out.println("1. Iterating first 10 Integer numbers starting from 0 : \n");
// 1. Stream of first 10 integer numbers
Stream.iterate(0, i -> i+1) // 1. Function to iterate Integer numbers
.limit(10) // 2. intermediate operation to limit to 10 numbers
.forEach(System.out::println); // 3. terminal operation to print to console
System.out.println("\n2. Iterating first 5 EVEN Integer numbers starting from 0 : \n");
// 2. Stream of EVEN integer numbers
Stream.iterate(0, i -> i+2) // 1. Function to iterate EVEN numbers
.limit(5) // 2. intermediate operation to limit to 5 numbers
.forEach(System.out::println); // 3. terminal operation to print to console
System.out.println("\n3. Iterating first 7 ODD Integer numbers starting from 1 : \n");
// 3. Stream of ODD integer numbers
Stream.iterate(1, i -> i+2) // 1. Function to iterate ODD numbers
.limit(7) // 2. intermediate operation to limit to 7 numbers
.forEach(System.out::println); // 3. terminal operation to print to console
}
}
Output:
1. Iterating first 10 Integer numbers starting from 0 :
0
1
2
3
4
5
6
7
8
9
2. Iterating first 5 EVEN Integer numbers starting from 0 :
0
2
4
6
8
3. Iterating first 7 ODD Integer numbers starting from 1 :
1
3
5
7
9
11
13
2. Collection API method :
There are 2 useful methods available in Collection API which allows to create Stream as listed below,
- stream() :- Returns a sequential
Stream
with invoking collection as its source - parallelStream() :- Returns a possibly parallel
Stream
with invoking collection as its source
2.1 stream() :
- This method returns sequential
Stream
for the invoking Collection like List or Set - Then we can apply chain of multiple intermediate operation, if required
- Finally apply terminal operation to get result be it collecting to another List/Set or printing to console or counting, etc.
- Method signature :- default Stream stream()
CollectionToStreamConversion.java
package net.bench.resources.stream.creation.example;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class CollectionToStreamConversion {
public static void main(String[] args) {
System.out.println("1. List<Integer> to Stream conversion : \n");
// 1. List of Integers
List<Integer> numbers = Arrays.asList(
10, 20, 30, 40, 50, 60, 70, 80, 90);
// 1.1 collection to stream
Stream<Integer> stream1 = numbers.stream();
// 1.2 print to console using forEach()
stream1.forEach(i -> System.out.println(i));
System.out.println("\n2. List<String> to Stream conversion : \n");
// 2. List of String
List<String> names = Arrays.asList(
"Vijay",
"Vikram",
"Ajith",
"Suriya",
"Karthi",
"Dhanush",
"Simbhu"
);
// 2.1 collection to stream and print to console
names // original source
.stream() // 1. get stream
.forEach(i -> System.out.println(i)); // 3. terminal operation to print
// 3. Names with length greater than 5 letters
System.out.println("\n3. After Stream conversion,"
+ " print names with length greater than 5 : \n");
names // original source
.stream() // 1. get stream
.filter(name -> name.length() > 5) // 2. intermediate operation for filtering names
.forEach(i -> System.out.println(i)); // 3. terminal operation to print to console
}
}
Output:
1. List<Integer> to Stream conversion :
10
20
30
40
50
60
70
80
90
2. List<String> to Stream conversion :
Vijay
Vikram
Ajith
Suriya
Karthi
Dhanush
Simbhu
3. After Stream conversion, print names with length greater than 5 :
Vikram
Suriya
Karthi
Dhanush
Simbhu
2.2 parallelStream() :
- This method returns possibly parallel
Stream
for the invoking Collection like List/Set - Then we can apply chain of multiple intermediate operation, if required
- Finally apply terminal operation to get result be it collecting to another List/Set or printing to console or counting, etc.
- The advantage of parallel Stream over sequential Stream is that, it distributes work/process across multiple threads taking leverage of underlying multi-core processor for faster execution
- Method signature :- default Stream parallelStream()
ParallelStreamExample.java
package net.bench.resources.stream.creation.example;
import java.util.ArrayList;
import java.util.List;
class Student {
// member variables
String name;
int marks;
// public no-arg constructor
public Student(String name, int marks) {
this.name = name;
this.marks = marks;
}
}
public class ParallelStreamExample {
public static void main(String[] args) {
// local variables
long startTs;
long endTs;
long count;
List<Student> studentList = getStudentList(); // student list
// 1. Serial execution
startTs = System.currentTimeMillis();
count = studentList // original source
.stream() // 1. get SERIAL stream
.filter(s -> s.marks > 60) // 2. intermediate operation to filter wrt marks
.count(); // 3. terminal operation to count after filtering
System.out.println("1.1 Number students with marks more than 60 is : "
+ count);
endTs = System.currentTimeMillis();
System.out.println("\n1.2 Time taken for Serial execution : "
+ (endTs - startTs));
// 1. parallel execution
startTs = System.currentTimeMillis();
count = studentList // original source
.parallelStream() // 1. get PARALLEL stream
.filter(s -> s.marks > 60) // 2. intermediate operation to filter wrt marks
.count(); // 3. terminal operation to count after filtering
System.out.println("\n\n2.1 Number students with marks more than 60 is : "
+ count);
endTs = System.currentTimeMillis();
System.out.println("\n2.2 Time taken for Parallel execution : "
+ (endTs - startTs));
}
/**
* Method to return list of Student
* @return
*/
public static List<Student> getStudentList() {
// create List object
List<Student> list = new ArrayList<Student>();
// add few students for testing purpose
list.add(new Student("Vijay", 97));
list.add(new Student("Ajith", 82));
list.add(new Student("Vikram", 77));
list.add(new Student("Suriya", 65));
list.add(new Student("Dhanush", 60));
list.add(new Student("Arya", 48));
list.add(new Student("Vishal", 35));
// return list
return list;
}
}
Output:
1.1 Number students with marks more than 60 is : 4
1.2 Time taken for Serial execution : 75
2.1 Number students with marks more than 60 is : 4
2.2 Time taken for Parallel execution : 6
3. Difference between Sequential and parallel stream ?
- Sequential Stream :- It executes in single thread linearly or serially or sequentially
- Parallel Stream :- It distributes work across multiple threads thereby leveraging the underlying multi-core processor of the system
- Comparison :- When we compare these 2 execution mechanism in terms of time it taken to complete work, then parallel Stream possibly performs better than Sequential Stream
- Execution time comparison :- As you can see in the above example, time taken to complete one unit of work with parallel stream is 6 ms whereas for same work sequential stream took 75 ms
Related Articles:
- Stream API
- How to create Stream
- Stream filter() method with examples
- Stream map() method with examples
- Stream flapMap method with examples
- Difference between map() and flatMap() in Stream API
- Stream forEach() method with examples
- Stream forEachOrdered() method
- Stream sorted() method with examples
- Stream count() method with examples
- Stream distinct() method with examples
- Stream min() and max() methods
- Stream skip() and limit() methods
- Stream peek() method with examples
References:
- https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html
- https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html
- https://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html
- https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html
- https://docs.oracle.com/javase/tutorial/collections/streams/parallelism.html
Happy Coding !!
Happy Learning !!