Exploring Java 8/6 : Intermediate Streams Operations
Hello there techie Ninja, Hope you are doing good. Welcome to the Blog. Today in this blog we would be exploring some intermediate operations that can be performed on streams. I hope you went through my last blog "Introduction to Streams API". If you are a beginner to java streams I would recommend you to read the previous blog, which would clear the basics about streams.
Following are the Intermediate operations available on Streams
- map
- filter
- flatMap
- distinct
- sorted
- peek
- limit
- skip
Before we dig into those operations, I would like to tell you that, each of those methods returns a new Stream reference. Each of the intermediate operations creates a new streams object, that's why you can take advantage of method chaining and can write concise and easy-to-read code.
map() operation
map() operation accepts a function Functional Interface Lamdba and it perform transform operation. use case of map() operation would be whenever you wanted to transform any data from one data type to another data type you can use the map operation.
Syntax :
1Stream<R> map(Function<? super T, ? extends R> mapper)
Example :
1package org.java4ninja.exploringjava8.streams;
2
3import java.util.Arrays;
4import java.util.List;
5import java.util.function.Function;
6import java.util.stream.Collectors;
7
8class Employee {
9 private String firstName;
10 private String lastName;
11
12 public Employee(String firstName, String lastName) {
13 this.firstName = firstName;
14 this.lastName = lastName;
15 }
16
17 @Override public String toString() {
18 return "Employee{firstName='" + firstName + "\' lastName='" + lastName + "\'}";
19 }
20}
21
22public class StreamsIntermediateExample {
23 public static void main(String args[]) {
24 List<String> listOfEmployeeNames = Arrays.asList("Will Smith", "Smith Jones",
25 "Cierra Vega", "Alden Cantrell", "Thomas Crane");
26
27 // function which input the string and convert the string to the object of Employee
28 Function<String, Employee> createEmployeeFromName = (name) -> {
29 String firstName = name.split(" ")[0];
30 String lastName = name.split(" ")[1];
31 return new Employee(firstName, lastName);
32 };
33
34 List<Employee> listOfEmployeeObjects = listOfEmployeeNames
35 .stream()
36 .map(createEmployeeFromName)
37 /* more concise way of writing
38 /*.map((name) -> {
39 String firstName = name.split(" ")[0];
40 String lastName = name.split(" ")[1];
41 return new Employee(firstName, lastName);
42 })*/
43 .collect(Collectors.toList());
44
45 System.out.println(listOfEmployeeObjects);
46 }
47}
filter() Operation
filter() operation is used to filter out elements from the streams. suppose you have streams of elements, and you want that certain element which does not match our criteria should be filtered out. and should not be sent ahead for further processing. in such cases, you can use filter() operation. filter operation accepts a Predicate function as an Input.
Syntax :
1Stream<T> filter(Predicate<? super T> predicate);
Example :
1package org.java4ninja.exploringjava8.streams;
2
3import java.util.Arrays;
4import java.util.List;
5import java.util.function.Predicate;
6import java.util.stream.Collectors;
7
8class Student {
9 private String name;
10 private double marksOutOf100;
11
12 public Student(String name, double marksOutOf100) {
13 this.name = name;
14 this.marksOutOf100 = marksOutOf100;
15 }
16
17 public String getName() {
18 return name;
19 }
20
21 public double getMarksOutOf100() {
22 return marksOutOf100;
23 }
24}
25
26public class FilterOperationOnStreams {
27 public static void main(String args[]) {
28
29 List<Student> studentList = Arrays.asList(
30 new Student("Tim", 86),
31 new Student("Joe", 44),
32 new Student("Lisa", 91),
33 new Student("Tom", 52));
34
35 Predicate<Student> passingCriteria = student -> student.getMarksOutOf100() > 50;
36
37 List<String> listOfStudentWhoPassTheExam = studentList
38 .stream()
39 .filter(passingCriteria)
40 /* more concise way inline predicate function */
41 //.filter(student -> student.getMarksOutOf100() > 50)
42 .map(student -> student.getName())
43 /* more concise way using method reference */
44 //.map(Student::getName)
45 .collect(Collectors.toList());
46
47 System.out.println(listOfStudentWhoPassTheExam);
48 }
49}
flatMap() Operation
flatMap() is the most confusing operation of streams, Many people gets confuse between map() and flatMap(). It would be easy if you understood them correctly with the correct example. flatMap() operation is used to convert the Streams<Streams
Syntax :
1Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
Example :
1package org.java4ninja.exploringjava8.streams;
2
3import java.util.List;
4import java.util.stream.Collectors;
5import lombok.AllArgsConstructor;
6import lombok.Data;
7import static java.util.Arrays.asList;
8
9/* I have used lombok here in order to write minimal code,You can
10always use lombok, or manually create constructor and getter setters*/
11@Data @AllArgsConstructor
12class Sales {
13 private String item;
14 private double price;
15}
16
17@Data @AllArgsConstructor
18class SalesEmployee {
19 private String name;
20 private List<Sales> listOfSales;
21}
22
23public class FlatMapOperationOnStreams {
24 public static void main(String args[]) {
25 List<SalesEmployee> listOfEmployee = asList(
26 new SalesEmployee("Joe", asList(
27 new Sales("Iron", 150),
28 new Sales("Washing Machine", 1500))),
29 new SalesEmployee("Honey", asList(
30 new Sales("Mobile", 1400),
31 new Sales("TV", 13499))),
32 new SalesEmployee("Lisa", asList(
33 new Sales("Bed", 150),
34 new Sales("Laptop", 12999))),
35 new SalesEmployee("Hayaat", asList(
36 new Sales("Pen Drive", 399),
37 new Sales("Desktop Computer", 8999))));
38
39 List<Sales> listOfSales = listOfEmployee
40 .stream()
41 .flatMap(employee -> employee.getListOfSales().stream())
42 .collect(Collectors.toList());
43
44 System.out.println(listOfSales);
45 }
46}
distinct() and sorted()
The name itself depicts its usage, distinct() method used to extract out all the distinct elements from the streams. and remove all duplicate elements. distinct does not take any argument as input.
sorted() method is useful to sort the elements in the streams. it sorts the element in its natural order. It expects that the class should be comparable. otherwise, you can pass a Comparator object to the sorted() method.
Syntax :
1Stream<T> distinct();
2Stream<T> sorted();
3Stream<T> sorted(Comparator<? super T> comparator);
Example :
1package org.java4ninja.exploringjava8.streams;
2
3import java.util.Arrays;
4import java.util.Comparator;
5import java.util.List;
6import java.util.stream.Collectors;
7
8public class DistinctAndSortedOnStreams {
9 public static void main(String args[]) {
10
11 List<Integer> listOfIntegers = Arrays.asList(1, 2, 5, 33, 22, 2,
12 33, 90, 11, 15, 19, 8, 90, 155, 65, 22);
13
14 List<Integer> listOfDistinctAndSortedIntegers = listOfIntegers
15 .stream()
16 .distinct()
17 .sorted()
18 .collect(Collectors.toList());
19 System.out.println(listOfDistinctAndSortedIntegers);
20
21 List<Integer> listOfDistinctAndSortedInReverseOrderIntegers = listOfIntegers
22 .stream()
23 .distinct()
24 .sorted(Comparator.reverseOrder())
25 .collect(Collectors.toList());
26 System.out.println(listOfDistinctAndSortedInReverseOrderIntegers);
27 }
28}
peek() limit() and skip()
peek() operation is more of debugging method in the streams, it accepts a consumer function and generally, we use it for printing things out so that on each step of streams you will come to know which elements are going to pass to the next intermediate operation
limit() operation is used to limit the number of the element which can be pass through the streams. it accepts a Long integer, which used to denote the number of the element should be pass to the next intermediate operations
skip() operation again is used to skip first n elements from the streams. it accepts Long integer which is used to skip the first n elements from the beginning of the streams
Syntax :
1Stream<T> peek(Consumer<? super T> action);
2Stream<T> limit(long maxSize);
3Stream<T> skip(long n);
Example :
1package org.java4ninja.exploringjava8.streams;
2
3import java.util.Arrays;
4import java.util.stream.Collectors;
5
6public class PeekLimitAndSkipOperation {
7 public static void main(String args[]) {
8 Arrays
9 .asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
10 .stream()
11 // skip first 2 element
12 .skip(2)
13 // limit the result for next 5 elements only
14 .limit(5)
15 // do a peek a boo on the current elements of streams
16 .peek((element) -> System.out.println(element))
17 .peek(System.out::println)
18 .collect(Collectors.toList());
19 }
20}
I hope you learned all the operations we have discussed in this blog, Let me know your comment, suggestion for this blog. it would be helpful for me to improve myself and my blogs.
Till then, Thank You Good-Bye Happy Coding
<< Chapter 5 : Introduction to Streams API | Chapter 7 : Internal working of Streams >>
comments powered by Disqus