1. Overview
In this article, You'll learn how to create infinite streams and how to use them in java 8.
Use Stream.iterate() and Stream.generate() method to create infinite streams in java. These two are declared as static methods and these are called utility methods.
Before diving into the Infinite Stream concepts, Let us understand the few concepts such as Intermediate and Terminal operation from Stream API.
2. Stream Intermediate and Terminal Operations
When the stream is created using stream() method internally pipeline will be created. All the methods invoked on Stream are placed inside the pipeline. Whenever methods called at the beginning of the streams are called as Intermediate Operations.
All the intermediate operations returns Stream<T> instance such as filter(), map() and flatMap() comes under Intermediate Operations. If any method is not returning Stream then it is not Intermediate Operation.
Stream Intermediate Operations:
filter()
map()
flatMap()
distinct()
sorted()
peek()
limit()
skip()
Note: All intermediate operations are immediately executed and only executed after calling the terminal operations. Even though you add 10 intermediate operations to stream, all of these are not executed unless you call at least one terminal operation.
After using the intermediate operations, to collect the final output you need to use anther list of methods such as collect(), count(), anyMatch().
Final output can be List, Set or Map, Optional values and these are produced by only upon invocation of the following list of terminal methods
toArray()
collect()
count()
reduce()
forEach()
forEachOrdered()
min()
max()
anyMatch()
allMatch()
noneMatch()
findAny()
findFirst()
3. Infinite Streams in Java 8
By the time now you should be good with the intermediate and terminal operations and their execution flows.
Why I was saying in the above sections that stream intermediate methods must be followed by at least one terminal operation because when you call to iterate() or generate() methods start putting the data into the stream then it will be added with infinite values. So if intermediate methods are invoked in the pipeline then it will consume the memory and may end up with the OutOfMemoryError. Because of this reason, terminal operations are needed to end the stream processing.
4. Stream.iterate() Infinite Streams
API description for this method.
"Returns an infinite sequential ordered Stream produced by iterative application of a function f to an initial element seed, producing a Stream consisting of seed, f(seed), f(f(seed)), etc.
The first element (position 0) in the Stream will be the provided seed. For n > 0, the element at position n, will be the result of applying the function f to the element at position n - 1."
Syntax:
static <T> Stream<T> iterate(T seed, UnaryOperator<T> f)Let us create an infinite number series that starts from 0 and increment by 1.
Stream.iterate(1, i -> i +1);Now, this is adding the elements to the stream and there is no limit for that. Before calling the terminal operation such as collect(), it is good practice to use limit() method.
package com.javaprogramto.java8.streams.infinite;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class StreamIterateExample {
public static void main(String[] args) {
// Creating a infinite Stream
Stream<Integer> integerInfiniteStream = Stream.iterate(1, i -> i +1);
List<Integer> first15Numbers = integerInfiniteStream.limit(15).collect(Collectors.toList());
System.out.println("integerInfiniteStream with limit 15 : "+first15Numbers);
}
}
Output:integerInfiniteStream with limit 15 : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
5. Stream.generate() Infinite Streams
static <T> Stream<T> generate(Supplier<T> s)
package com.javaprogramto.java8.streams.infinite;
import java.util.List;
import java.util.UUID;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class StreamGenerateExample {
public static void main(String[] args) {
// Generates the UUID
Supplier<UUID> randomUUIDSupplier = () -> UUID.randomUUID();
List<UUID> uuidList = Stream.generate(randomUUIDSupplier).limit(10).collect(Collectors.toList());
System.out.println("10 random UUID list : "+uuidList);
}
}
10 random UUID list : [2800389f-221f-4258-b892-94c74b71da7c, 6adcfba0-2670-40e9-b7c0-320cd11ef965, 894be0cc-c254-4ea9-b7c6-8e3c19e7c34d, 7d4e65d8-e0e4-4759-b98d-17e472f67c3e, 1c53963c-5b73-4fee-bc14-7e9ed9b2b838, 96dc6394-cb99-4547-bfba-88d79487841b, a0b949e1-a424-4a3d-acd9-8b6d5674bd0a, 4748832c-be4f-4b95-a333-392359a06d46, f82b2a23-9aa9-4c67-a9eb-2fdec8cfe62b, 44c33cd9-b3a7-4a23-be5b-def78893bdf1]
6.Stream.iterate() vs Stream.generate()
import java.util.List; import java.util.Random; import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; public class StreamGenerateVSIterate { public static void main(String[] args) { // Example to generate 10 random numbers from 0 to 20. Supplier<Integer> infiniteStream1 = () -> new Random().nextInt(20); List<Integer> randomNumbers = Stream.generate(infiniteStream1).limit(10).collect(Collectors.toList()); System.out.println("10 random numbers list : " + randomNumbers); // Example to generate 10 random numbers from 0 to 20. Stream<Integer> infiniteStream2 = Stream.iterate(0, i -> i + 1); List<Integer> first10Numbers = infiniteStream2.limit(10).collect(Collectors.toList()); System.out.println("first 10 numbers list : " + first10Numbers); } }
10 random numbers list : [2, 5, 0, 7, 0, 9, 11, 3, 12, 16] first 10 numbers list : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
7. Infinite Streams With Custom Objects
import java.io.Serializable; import java.util.List; import java.util.Random; import java.util.stream.Collectors; import java.util.stream.Stream; public class CustomObjectsStreamGenerateExample { public static void main(String[] args) { List<Book> uuidList = Stream.generate(Book::create) .limit(10) .collect(Collectors.toList()); System.out.println("10 random UUID list : "+uuidList); } } class Book implements Serializable { private int id; private String title; private double price; public Book(int id, String title, double price) { this.id = id; this.title = title; this.price = price; } public static Book create(){ int id = new Random().nextInt(10); return new Book(id, "name "+id, id * 2.2); } @Override public String toString() { return "Book{" + "id=" + id + ", title='" + title + '\'' + ", price=" + price + '}'; } }
10 random UUID list : [ Book{id=1, title='name 1', price=2.2}, Book{id=0, title='name 0', price=0.0}, Book{id=6, title='name 6', price=13.200000000000001}, Book{id=3, title='name 3', price=6.6000000000000005}, Book{id=1, title='name 1', price=2.2}, Book{id=0, title='name 0', price=0.0}, Book{id=1, title='name 1', price=2.2}, Book{id=1, title='name 1', price=2.2}, Book{id=2, title='name 2', price=4.4}, Book{id=5, title='name 5', price=11.0}]
No comments:
Post a Comment
Please do not add any spam links in the comments section.