Stream was introduced in Java 8, the Stream API is used to process collections of objects. A stream in Java is a sequence of objects that supports various methods that can be pipelined to produce the desired result.
Use of Stream in JavaThe uses of Stream in Java are mentioned below:
Java Stream Creation is one of the most basic steps before considering the functionalities of the Java Stream. Below is the syntax given for declaring a Java Stream.
SyntaxStream<T> stream;
Here, T is either a class, object, or data type depending upon the declaration.
Java Stream FeaturesThe features of Java streams are mentioned below:
There are two types of Operations in Streams:
Intermediate Operations are the types of operations in which multiple methods are chained in a row.
Characteristics of Intermediate OperationsThere are some benefits because of which we use Stream in Java as mentioned below:
There are a few Intermediate Operations mentioned below:
1. map(): The map method is used to return a stream consisting of the results of applying the given function to the elements of this stream.
Syntax:
<R> Stream<R> map(Function<? super T, ? extends R> mapper)
2. filter(): The filter method is used to select elements as per the Predicate passed as an argument.
Syntax:
Stream<T> filter(Predicate<? super T> predicate)
3. sorted(): The sorted method is used to sort the stream.
Syntax:
Stream<T> sorted()
Stream<T> sorted(Comparator<? super T> comparator)
4. flatMap(): The flatMap operation in Java Streams is used to flatten a stream of collections into a single stream of elements.
Syntax:
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)
5. distinct(): Removes duplicate elements. It returns a stream consisting of the distinct elements (according to Object.equals(Object)).
Syntax:
Stream<T> distinct()
6. peek(): Performs an action on each element without modifying the stream. It returns a stream consisting of the elements of this stream, additionally performing the provided action on each element as elements are consumed from the resulting stream.
Syntax:
Stream<T> peek(Consumer<? super T> action)
Java program that demonstrates the use of all the intermediate operations:
Java
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class StreamIntermediateOperationsExample {
public static void main(String[] args) {
// List of lists of names
List<List<String>> listOfLists = Arrays.asList(
Arrays.asList("Reflection", "Collection", "Stream"),
Arrays.asList("Structure", "State", "Flow"),
Arrays.asList("Sorting", "Mapping", "Reduction", "Stream")
);
// Create a set to hold intermediate results
Set<String> intermediateResults = new HashSet<>();
// Stream pipeline demonstrating various intermediate operations
List<String> result = listOfLists.stream()
.flatMap(List::stream) // Flatten the list of lists into a single stream
.filter(s -> s.startsWith("S")) // Filter elements starting with "S"
.map(String::toUpperCase) // Transform each element to uppercase
.distinct() // Remove duplicate elements
.sorted() // Sort elements
.peek(s -> intermediateResults.add(s)) // Perform an action (add to set) on each element
.collect(Collectors.toList()); // Collect the final result into a list
// Print the intermediate results
System.out.println("Intermediate Results:");
intermediateResults.forEach(System.out::println);
// Print the final result
System.out.println("Final Result:");
result.forEach(System.out::println);
}
}
Intermediate Results: STRUCTURE STREAM STATE SORTING Final Result: SORTING STATE STREAM STRUCTUREExplanation of the above Program:
List of Lists Creation:
Stream Operations:
The program prints the intermediate results stored in the intermediateResults set. Finally, it prints the result list, which contains the fully processed strings after all stream operations.
This example showcases how Java Streams can be used to process and manipulate collections of data in a functional and declarative manner, applying transformations and filters in a sequence of operations.
Terminal OperationsTerminal Operations are the type of Operations that return the result. These Operations are not processed further just return a final result value.
Important Terminal OperationsThere are a few Terminal Operations mentioned below:
1. collect(): The collect method is used to return the result of the intermediate operations performed on the stream.
Syntax:
<R, A> R collect(Collector<? super T, A, R> collector)
2. forEach(): The forEach method is used to iterate through every element of the stream.
Syntax:
void forEach(Consumer<? super T> action)
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.
Syntax:
T reduce(T identity, BinaryOperator<T> accumulator)
Optional<T> reduce(BinaryOperator<T> accumulator)
4. count(): Returns the count of elements in the stream.
Syntax:
long count()
5. findFirst(): Returns the first element of the stream, if present.
Syntax:
Optional<T> findFirst()
6. allMatch(): Checks if all elements of the stream match a given predicate.
Syntax:
boolean allMatch(Predicate<? super T> predicate)
7. anyMatch(): Checks if any element of the stream matches a given predicate.
Syntax:
boolean anyMatch(Predicate<? super T> predicate)
Here ans variable is assigned 0 as the initial value and i is added to it.
Note: Intermediate Operations are running based on the concept of Lazy Evaluation, which ensures that every method returns a fixed value(Terminal operation) before moving to the next method.
Java Program Using all Terminal Operations:
Java
import java.util.*;
import java.util.stream.Collectors;
public class StreamTerminalOperationsExample {
public static void main(String[] args) {
// Sample data
List<String> names = Arrays.asList(
"Reflection", "Collection", "Stream",
"Structure", "Sorting", "State"
);
// forEach: Print each name
System.out.println("forEach:");
names.stream().forEach(System.out::println);
// collect: Collect names starting with 'S' into a list
List<String> sNames = names.stream()
.filter(name -> name.startsWith("S"))
.collect(Collectors.toList());
System.out.println("\ncollect (names starting with 'S'):");
sNames.forEach(System.out::println);
// reduce: Concatenate all names into a single string
String concatenatedNames = names.stream().reduce(
"",
(partialString, element) -> partialString + " " + element
);
System.out.println("\nreduce (concatenated names):");
System.out.println(concatenatedNames.trim());
// count: Count the number of names
long count = names.stream().count();
System.out.println("\ncount:");
System.out.println(count);
// findFirst: Find the first name
Optional<String> firstName = names.stream().findFirst();
System.out.println("\nfindFirst:");
firstName.ifPresent(System.out::println);
// allMatch: Check if all names start with 'S'
boolean allStartWithS = names.stream().allMatch(
name -> name.startsWith("S")
);
System.out.println("\nallMatch (all start with 'S'):");
System.out.println(allStartWithS);
// anyMatch: Check if any name starts with 'S'
boolean anyStartWithS = names.stream().anyMatch(
name -> name.startsWith("S")
);
System.out.println("\nanyMatch (any start with 'S'):");
System.out.println(anyStartWithS);
}
}
Output:
Explanation of the above Program:List Creation:
Stream Operations:
The program prints each name, names starting with 'S', concatenated names, the count of names, the first name, whether all names start with 'S', and whether any name starts with 'S'.
Real-World Use Cases of Java StreamsStreams are widely used in modern Java applications for:
Important Points:
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4