Hello everyone,
Let's continue Stream API with intermediate operations.Stream API supported for two major operations. They are,
1) Intermediate Operation.
2) Terminal Operation.
In this tutorial I will go to the depth in the Intermediate Operations. Before continuing this tutorial I recommend you to read my Stream API and Intermediate Operation.
Operations that give back values like numbers or objects are called terminal operations. Unlike other operations, we can't link them in a chain. Terminal operations provide the final result, and after they're done, the stream is no longer usable. So, we can't use that stream again once a terminal operation is finished.
Ex :- toArray(), reduce(), collect(), min(),max(),count(), anyMatch(), allMatch(),findFirst(), foreach(), findAny()
long count()
We can use this method to count the number of elements in a finite stream.
For example, let's call the count() method to find the number of students in the stream below.
public class Main {
public static void main(String[] args) {
Stream<String> namesList = Stream.of("Mike","Anne","Sara","Robot");
System.out.println("Count of Names :"+ namesList.count());
}
}
Output
Count of Name :4
The distinct() function returns the unique values from the original stream. In other words, it removes the duplicates. This distinct method uses the hashcode() and equals() method to determine the distinctness.
Optional<T> min(<? super T> comparator)
Optional<T> max(<? super T> comparator)
min() and max() functions allow us to find the min and max values in the finite stream. This also allows us to pass the custom comparator to find the largest and smallest value in the finite stream according to the sort order.
public class Main {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(5, 2, 8, 1, 6, 3);
// Finding minimum number
Optional<Integer> minNumber = numbers.stream()
.min(Integer::compareTo);
minNumber.ifPresent(min -> System.out.println("Minimum Number: " + min));
// Finding maximum number
Optional<Integer> maxNumber = numbers.stream()
.max(Integer::compareTo);
maxNumber.ifPresent(max -> System.out.println("Maximum Number: " + max));
}
}
Remember that this function returns an Optional rather than the value. To print the minimum or maximum value, use the optional method along with a method reference. This way, you’ll display the value only if it exists.
Optional<T> findFirst()
Optional<T> findAny()
findAny() method allows us to retrieve any element from a stream. This is useful when we’re looking for an element without paying attention to the encounter order. This method returns an Optional instance, which is empty if the stream is empty. In a non-parallel operation, it is likely that findAny() will return the first element in the stream, but this is not guaranteed. In a parallel operation, the result is not reliably determined due to performance optimizations.
findFirst() method used to find the first element in a stream. If there is no encounter order, it returns any element from the stream.The return type is also an Optional instance
public class Main {
public static void main(String[] args) {
List<String> fruits = Arrays.asList("Apple", "Banana", "Orange", "Mango", "Grapes");
// Using findAny() to retrieve any element from the stream
Optional<String> anyFruit = fruits.stream()
.findAny();
// Printing the result if any element is present
anyFruit.ifPresent(fruit -> System.out.println("Any Fruit: " + fruit));
}
}
Output
Any Fruit: Apple
public class Main {
public static void main(String[] args) {
// Create a list of names
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Eva");
// Use stream to find any name that starts with 'C'
Optional<String> anyNameStartingWithC = names.stream()
.filter(name -> name.startsWith("C"))
.findAny();
// Print the result
if (anyNameStartingWithC.isPresent()) {
System.out.println("Name starting with 'C' found: " + anyNameStartingWithC.get());
} else {
System.out.println("No name starting with 'C' found.");
}
}
}
Output
Name starting with 'C' found: Charlie
This function allows you to sort elements in a collection (such as a list) based on a specified ordering.
boolean anyMatch(Predicate <? super T> predicate)
boolean allMatch(Predicate <? super T> predicate)
boolean noneMatch(Predicate <? super T> predicate)
This method checks at least one element in the stream satisfies the given predicate. This method stops evaluating once it finds a matching element. As an example, If the fourth element satisfies the predicate, the rest of the stream elements won’t be processed. Conversely, if none of the elements match the predicate, the entire stream will be processed.
This method returns true, if all elements in the stream satisfy the provided predicate.If the first element doesn't meet the condition, the evaluation stops.
The noneMatch() method checks if none of the elements in the stream satisfy the given predicate.It only evaluates the predicate on elements until it finds one that satisfies the predicate, then it returns false. It processes the entire stream only when none of the elements match the predicate.
public class Main {
public static void main(String[] args) {
// Create a list of numbers
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// Check if any element is greater than 5
boolean anyGreaterThanFive = numbers.stream()
.anyMatch(num -> num > 5);
System.out.println("Any element greater than 5? " + anyGreaterThanFive);
// Check if all elements are less than 20
boolean allLessThanTwenty = numbers.stream()
.allMatch(num -> num > 20);
System.out.println("All elements greater than 20? " + allLessThanTwenty);
// Check if none of the elements are negative
boolean noneNegative = numbers.stream()
.noneMatch(num -> num < 0);
System.out.println("None of the elements are negative? " + noneNegative);
}
}
Output :
Any element greater than 5? true All elements less than 20? false None of the elements are negative? true
void forEach(Consumer <? super T> action)
When iterating elements of a stream, it's important to note that forEach() is the only terminal operation with a return type of void. Additionally, it's worth mentioning that forEach() can be called directly on a Collection or on a Stream. It's also important to understand that the Stream API in Java 8 cannot use a traditional for loop to run because it doesn't implement the Iterable interface.
public class Main {
public static void main(String[] args) {
Stream<String> fruits = Stream.of("Apple", "Banana", "Orange", "Mango", "Grapes");
// Use forEach to print each element in uppercase
fruits.forEach(fruit -> System.out.println(fruit.toUpperCase()));
}
}
Output
APPLE BANANA ORANGE MANGO GRAPES
There are two variants of the collect() method.
R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner)
R collect(Collector<? super T, A, R> collector)
Let’s break down the parameters:
supplier: A function that creates a new mutable result container. For parallel execution, this function may be called multiple times, and it must return a fresh value each time.
accumulator: A stateless function that folds an element into the result container.
combiner: A stateless function that merges two partial result containers. It must be compatible with the accumulator function.
This method performs a mutable reduction operation on the elements of the stream.What does “mutable reduction” mean? While processing the stream elements, it collects input elements into a mutable result container, such as a Collection or a StringBuilder.
public class Main {
public static void main(String[] args) {
// Create a stream of numbers
Stream<Integer> numberStream = Stream.of(11, 2, 33, 44, 5);
// Use collect to transform the stream into a List
List<Integer> numberList = numberStream.collect(Collectors.toList());
// Print the result
System.out.println("List of numbers: " + numberList);
}
}
Now you have a better understand about the intermediate operation in Stream API, how to use it, and the how to use that function using real world examples. In the next Tutorial, I will talk about Terminal Operations in Stream API (Terminal Operation).