Exploring Java 8/8 : Streams terminal functions
Hello there techie Ninja's, Hope you are doing well. Today, in this blog we would be learning about the terminal operations in java 8 streams. You might have seen in previous blogs that intermediate operation flows the data, transform it but it again produces new streams. If you want to collect the data from streams to normal collection class or another format, you need to use the terminal operation. One of the terminal functions we have seen till now is Collectors.collect(). Yes, it is a terminal function. Apart from this one, java streams have a few more terminal functions, which you can use as per need. Let's check this out.
Terminal Functions/Operations in Java 8 Streaming API
- allMatch
- anyMatch
- noneMatch
- count
- forEach
- min
- max
- reduce
- collect
allMatch(), anyMatch(), noneMatch()
These 3 termination functions accept a predicate and return a boolean value. These functions mainly used to evaluate a condition on the elements of a stream and return true or false based on the condition. The point to note here is that it is a termination function. once you invoke it on stream, the stream will no longer be opened. it would be terminated once you call the termination function. let's have a look at the below example
Signature :
1boolean anyMatch(Predicate<? super T> predicate);
2boolean allMatch(Predicate<? super T> predicate);
3boolean noneMatch(Predicate<? super T> predicate);
Example :
1package org.java4ninja.exploringjava8.streams;
2
3import java.util.Arrays;
4
5public class TerminalOperations {
6 public static void main(String args[]) {
7 // return true if all words have minimum 2 or more characters
8 // expected to match the condition by all elements of streams
9 boolean doesAllWordsHas3Letters = Arrays.asList(
10 "ANT",
11 "BAT",
12 "CAT",
13 "DOG",
14 "EAT",
15 "FAT").stream().allMatch((s) -> s.length() >= 2);
16
17 // return true if at least one cat exist
18 // expected to match the condition by at least by one element
19 boolean isCatPresentInStream = Arrays.asList(
20 "ANT",
21 "BAT",
22 "CAT",
23 "DOG",
24 "EAT",
25 "FAT").stream().anyMatch((s) -> s.equalsIgnoreCase("cat"));
26
27 // return true if none of the element matches the condition
28 // expected to not to match
29 boolean noneOfTheElementMatchCondition = Arrays.asList(
30 "ANT",
31 "BAT",
32 "CAT",
33 "DOG",
34 "EAT",
35 "FAT").stream().noneMatch((s) -> s.length() > 3);
36 System.out.println(noneOfTheElementMatchCondition);
37 }
38}
min() and max()
This terminal operation returns the smallest and biggest element in the stream. min() function return the smallest element whereas max() function return the biggest element. Both of them take the comparator as an input and return the Optional of the type. When Stream is empty this function will return Optional empty().
Signature:
1Optional<T> min(Comparator<? super T> comparator);
2Optional<T> max(Comparator<? super T> comparator);
Example :
1package org.java4ninja.exploringjava8.streams;
2
3import java.util.Arrays;
4import java.util.Comparator;
5import java.util.List;
6import lombok.AllArgsConstructor;
7import lombok.Getter;
8import lombok.ToString;
9
10public class TerminalOperationMinMax {
11
12 @AllArgsConstructor
13 @ToString
14 @Getter
15 private static class Employee {
16 private int id;
17 private String name;
18 private int age;
19 }
20
21 public static void main(String args[]) {
22
23 List<Employee> listOfEmployees = Arrays.asList(
24 new Employee(1, "Anil", 29),
25 new Employee(2, "Joe", 21),
26 new Employee(3, "Jane", 35),
27 new Employee(4, "Bob", 26)
28 );
29
30 Employee youngestEmployee = listOfEmployees
31 .stream()
32 .min(Comparator.comparing(Employee::getAge))
33 .get();
34
35 System.out.println("Youngest Employee : " + youngestEmployee);
36
37 Employee eldestEmployee = listOfEmployees
38 .stream()
39 .max(Comparator.comparing(Employee::getAge))
40 .get();
41
42 System.out.println("Eldest Employee : " + eldestEmployee);
43 }
44}
count(), forEach() and reduce()
count terminal function counts the number of elements in the stream and returns the long value.
forEach terminal function iterate over the element of the streams. forEach is a terminal function don't expect you will get the stream back from forEach function.
reduce is a reducer function that returns a single value representing the collection. if you have seen the map-reduce program, where map operation transforms the data and reduces operation reduce it to a single figure. reduce() function is the reducer part of a map-reduce program in the stream.
Signature
1long count();
2void forEach(Consumer<? super T> action);
3T reduce(T identity, BinaryOperator<T> accumulator);
4Optional<T> reduce(BinaryOperator<T> accumulator);
5<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner);
Example
1package org.java4ninja.exploringjava8.streams;
2
3import java.util.Arrays;
4import java.util.List;
5import lombok.AllArgsConstructor;
6import lombok.Getter;
7import lombok.ToString;
8
9public class TerminalOperationCountForEachReduce {
10
11 @AllArgsConstructor
12 @ToString
13 @Getter
14 private static class Employee {
15 private int id;
16 private String name;
17 private int age;
18 }
19
20 public static void main(String args[]) {
21
22 List<Employee> listOfEmployees = Arrays.asList(
23 new Employee(1, "Anil", 29),
24 new Employee(2, "Joe", 21),
25 new Employee(3, "Jane", 35),
26 new Employee(4, "Bob", 26)
27 );
28
29 long count = listOfEmployees.stream().count();
30 System.out.println("There are " + count + " employees in office");
31
32 System.out.println("========= Employee Detaills =======");
33 listOfEmployees
34 .stream()
35 .forEach(eachEmployee -> {
36 System.out.println(eachEmployee.toString());
37 });
38
39 Integer combinedAgeOfCompany = listOfEmployees
40 .stream()
41 .map(Employee::getAge)
42 .reduce((firstAge, secondAge) -> firstAge + secondAge)
43 .get();
44
45 System.out.println("Combined Age of Company is " + combinedAgeOfCompany);
46 }
47}
collect()
It is the most widely used terminal operation on stream. It takes Collector as an input and returns collection in various formats. We would be going to see the collection with most of the use cases in the next another series with the name "Java 8 Streaming API Examples". So we keep this topic for the new blog series
I hope you have enjoyed this tutorial. Please let me know your comments, suggestion, and improvements I will try to improve my blog.
Till then, Good Bye Happy Coding !!!
<< Chapter 7 : Internal working of Streams
comments powered by Disqus