[Java 8] Tìm hiểu về flatMap

Chào các bạn, trong bài viết này, chúng ta sẽ cùng tìm hiểu về flatMap trong Java 8

Trong Java 8, Stream có thể giữ nhiều kiểu dữ liệu khác nhau trong nó, ví dụ như:

Java:
Stream<String[]> 

Stream<Set<String>> 

Stream<List<String>> 

Stream<List<Object>>
Thế nhưng, các phép toán trên Stream (filter, sum. Distinct..) và collectors thì không hỗ trợ điều này. Vì thế, chúng ta cần flatMap() để thực hiện các chuyển đổi bên dưới:

Java:
Stream<String[]>        -> flatMap ->    Stream<String>
Stream<Set<String>>    -> flatMap ->    Stream<String>
Stream<List<String>>    -> flatMap ->    Stream<String>
Stream<List<Object>>    -> flatMap ->    Stream<Object>
flatMap hoạt động như thế nào:
Java:
{ {1,2}, {3,4}, {5,6} } -> flatMap -> {1,2,3,4,5,6}


{ {'a','b'}, {'c','d'}, {'e','f'} } -> flatMap -> {'a','b','c','d','e','f'}
1. Stream + String[] + flatMap
1.1 Ví dụ bên dưới sẽ in ra một chuỗi kết quả rỗng, bởi vì filter() không biết làm thế nào để lọc một stream kiểu String[].

TestExample1.java
Java:
package com.mkyong.java8;

import java.util.Arrays;

import java.util.stream.Stream;

public class TestExample1 {

    public static void main(String[] args) {

        String[][] data = new String[][]{{"a", "b"}, {"c", "d"}, {"e", "f"}};

        //Stream<String[]>
        Stream<String[]> temp = Arrays.stream(data);

        //filter a stream of string[], and return a string[]?
        Stream<String[]> stream = temp.filter(x -> "a".equals(x.toString()));

        stream.forEach(System.out::println);

    }

}
Kết quả
Code:
//empty...
1.2 Ví dụ trên, chúng ta phải sử dụng flatMap() để chuyển đổi Stream<String[]> sang Stream<String>

TestExample1.java
Java:
package com.mkyong.java8;

import java.util.Arrays;
import java.util.stream.Stream;

public class TestExample1 {

    public static void main(String[] args) {

        String[][] data = new String[][]{{"a", "b"}, {"c", "d"}, {"e", "f"}};

        //Stream<String[]>
        Stream<String[]> temp = Arrays.stream(data);

        //Stream<String>, GOOD!
        Stream<String> stringStream = temp.flatMap(x -> Arrays.stream(x));

        Stream<String> stream = stringStream.filter(x -> "a".equals(x.toString()));

        stream.forEach(System.out::println);

        /*Stream<String> stream = Arrays.stream(data)
                .flatMap(x -> Arrays.stream(x))
                .filter(x -> "a".equals(x.toString()));*/

    }

}
Kết quả
Code:
a
2. Stream + Set + flatMap
2.1 Lớp student.

Student.java
Java:
package com.mkyong.java8;

import java.util.HashSet;
import java.util.Set;

public class Student {

    private String name;
    private Set<String> book;

    public void addBook(String book) {
        if (this.book == null) {
            this.book = new HashSet<>();
        }

        this.book.add(book);
    }

    //getters and setters

}

2.2 flatMap() và Set.

TestExample2.java
Java:
package com.mkyong.java8;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class TestExample2 {

    public static void main(String[] args) {

        Student obj1 = new Student();
        obj1.setName("mkyong");
        obj1.addBook("Java 8 in Action");
        obj1.addBook("Spring Boot in Action");
        obj1.addBook("Effective Java (2nd Edition)");

        Student obj2 = new Student();
        obj2.setName("zilap");
        obj2.addBook("Learning Python, 5th Edition");
        obj2.addBook("Effective Java (2nd Edition)");

        List<Student> list = new ArrayList<>();
        list.add(obj1);
        list.add(obj2);

        List<String> collect =
                list.stream()
                        .map(x -> x.getBook())      //Stream<Set<String>>
                        .flatMap(x -> x.stream())   //Stream<String>
                        .distinct()
                        .collect(Collectors.toList());

        collect.forEach(x -> System.out.println(x));
    }

}
Kết quả
Code:
Spring Boot in Action
Effective Java (2nd Edition)
Java 8 in Action
Learning Python, 5th Edition
Thử đóng dòng code flatMap(x -> x.stream()), trình biên dịch sẽ báo lỗi dòng Collectors.toList(), bởi vì nó không biết làm thế nào để tập hợp một stream từ Set đối tượng.

3. Stream + Primitive + flatMapToInt
3.1 Với kiểu nguyên thủy (Primitive), bạn có thể sử dụng flatMapToInt

TestExample3.java
Java:
package com.mkyong.java8;

import java.util.Arrays;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class TestExample3 {

    public static void main(String[] args) {

        int[] intArray = {1, 2, 3, 4, 5, 6};

        //1. Stream<int[]>
        Stream<int[]> streamArray = Stream.of(intArray);

        //2. Stream<int[]> -> flatMap -> IntStream
        IntStream intStream = streamArray.flatMapToInt(x -> Arrays.stream(x));

        intStream.forEach(x -> System.out.println(x));

    }

}
Kết quả

Code:
1
2
3
4
5
6

Cám ơn các bạn đã theo dõi. Hẹn gặp lại các bạn trong các bài viết sau :)

Bài viết tham khảo tại: https://mkyong.com/java8/java-8-flatmap-example
 
Sửa lần cuối:

Bình luận