java-flatmap-map-stream

Java map và flatmap – điều gì làm nên khác biệt?

Trước khi bắt đầu tìm hiểu về Java Map và flatMap, bạn nào chưa biết về Java Stream có thể đọc bài Stream – KieBlog để tìm hiểu và nhớ lại kiến thức về Stream trước khi bắt đầu vào nội dung chính của bài đọc.

1. Map trong Java Stream

Trong Stream API, phương thức Map() hoạt động như là một functions có argument (đối số).

Thứ nhất, phương thức này là phương thức trung gian (terminal operation).Phương thức này applie tất cả các chứng năng có ở funtions cho các elements trong Stream.

Cùng xem qua ví dụ sau đây:

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

public class MapExample {

    public static void main(String[] args) {
        List words= Arrays.asList("KieBlog","In", "God","We trust");

        List wordCount = words.stream()
                        .map(String::length)
                        .collect(Collectors.toList());

        wordCount.forEach(System.out::println);
    }
}

Ở ví dụ trên, phương thức Map() sử dụng phương thức String::length nhằm tính đoán độ dài các chuỗi String trong List. Kết quả trả về sẽ là một list độ dài các chuỗi.

Output:
16
4
11
6

Phương thức Map() đã hoạt động hoàn hảo. Câu hỏi đặt ra là tại sao ta lại cần thêm phương thức flatMap()?. Tại sao lại cần thêm phương thức này?.

Cùng tìm hiểu tiếp nhé.

2. flatMap là gì?

Đầu tiên, không cần phải nạp vào đầu những khái niệm lằng nhằng, rắc rối. Để đơn giản và dễ hiểu, ta cứ nhớ rằng:

flatMap = flat + Map (2 nhân tố cấu thành nên flatmap).
flat ở đây là Flattening (làm phẳng, làm cho bẹp lép :)).

Ủa, vậy làm bẹp lép là làm gì?.

java-flatmap-example
Flattening sẽ chuyển đổi list trong list. Merge lại tất cả lại với nhau thành một list duy nhất. Tất nhiên, nó bao gồm tất cả các phần tử có trong list con.

Từ từ, hãy cùng phân tích định nghĩa đã

3. Tại sao lại cần thêm flatmap?

Để hiểu được tại sao lại cần thêm flatmap, hãy cùng xem xét hai ví dụ sau đây:

Ta có một Array String các chuỗi mã hóa bị trùng lặp. Bài toán đặt ra: loại bỏ trùng lặp, lấy giá trị chuỗi.

Ù uôi, dễ thế!. Chẳng phải sử dụng Java distince() kết hợp với Map là sẽ xong sao?. Vấn đề không đơn giản như thế!, yêu cầu ngặt ngèo hơn. Kiểu trả về bắt buộc phải là Stream<String[]>, không được sử dụng thêm phương thức nào ngoài khác Stream API.

// Chuỗi mã hóa
List enscriptLst = Arrays.asList("AABYAJWLZ","DDA");
// Với yêu cầu ban đầu, ta có thể sử dụng map() và distince(), phân tách các kí tự
// loại bỏ trùng lặp
enscriptLst.stream().map( s-> s.split("")).distinct().collect(Collectors.toList());

Đoạn source này cho ta kết quả chính xác. Đoạn mã được loại bỏ trùng lắp. Nhưng kiểu trả về thì lại là List<String[]>.

Tại sao lại vậy?. Nguyên nhân là do Stream sẽ thực hiện chia tách và loại bỏ các từ trên từng Object String trong Arrays.

Đây chính là lúc mà ta cần tới flatMap:

// Chuỗi mã hóa
List <String> enscriptLst = Arrays.asList("AABYAJWLZ", "DDA");
List <String> enscriptLstAfterRemoveDup = enscriptLst.stream()
 .map(s -> s.split(""))
 .flatMap(Arrays::stream)
 .distinct()
 .collect(Collectors.toList());

Để ý tới hình ảnh phía dưới để biết phương thức flatMap() đã loại bỏ trùng lặp và trả về cho ta một List<String> duy nhất như thế nào.

4. Kết luận

The main difference between the map and flatMap is the return type.

Điểm khác biệt cốt lõi giữa map và flatMap là kiểu trả về (return type).

The Stream’s map() method produces or returns a single result value, which is sent to the Output stream.

Phương thức Stream map() chỉ xử lí và trả về duy nhất một kết quả, kết quả này được trả về thông qua Output của stream.

The Stream’s flatMap() method produces or returns a Stream of elements.

Phương thức Stream flatMap() sẽ xử lí và trả về danh sách các stream.

The map() method is only used for modification while the flatMap() method is used for both flattening and modification.

Khác với phương thức map(), flatMap() ngoài sử dụng để sửa đổi còn kết hợp cả phương thức flattening. Dàn đều các elements trong danh sách Stream.
flatMap() là một function đơn (unary function)
flat Map() là một function đơn (unary function). Function này nhận vào các element (phần tử), trả về một stream.

The flatMap() method replaces a value with a Stream and join all Streams together

Phương thức flatMap() thay thế các giá trị bằng Stream, KẾT HỢP các Stream lại với nhau.

5. Tham khảo

Có gì thắc mắc cứ comment đây nha! - Please feel free to comment here!
Chia sẻ bài viết


Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *