Collectors là một lớp- Class cuối cùng mở rộng lớp Đối tượng. Nó cung cấp các thao tác rút gọn, chẳng hạn như thêm các phần tử vào tập hợp, tóm tắt các phần tử theo nhiều tiêu chí khác nhau,… Lớp Java Collectors cung cấp nhiều phương thức khác nhau để xử lý các phần tử.

1. Tạo danh sách: toList ()

Nó được sử dụng để tích lũy các phần tử thành một danh sách. Nó sẽ tạo một danh sách mới (Không thay đổi danh sách hiện tại).

List<Integer> integers = Arrays.asList(1,2,3,4,5,6,6);

integers.stream().map(x -> x*x).collect(Collectors.toList());

// output: [1,4,9,16,25,36,36]

2. toSet ()

Nó được sử dụng để tích lũy các phần tử thành một tập hợp, sẽ loại bỏ tất cả các mục trùng lặp.

List<Integer> integers = Arrays.asList(1,2,3,4,5,6,6);
integers.stream().map(x -> x*x).collect(Collectors.toSet());
// output: [1,4,9,16,25,36]

3. Tạo bộ sưu tập cụ thể: toCollection ()

List<Integer> integers = Arrays.asList(1,2,3,4,5,6,6);
integers
    .stream()
    .filter(x -> x >2)
    .collect(Collectors.toCollection(LinkedList::new));
// output: [3,4,5,6,6]

Ở đây ta thu thập các phần tử lớn hơn 2 từ một danh sách có sẵn.

4. Đếm phần tử: Counting ()

List<Integer> integers = Arrays.asList(1,2,3,4,5,6,6);
Long collect = integers
                   .stream()
                   .filter(x -> x <4)
                   .collect(Collectors.counting());
// output: 3

Tham khảo khoá học Java Spring Boot Full Stack của Techmaster

5. Tìm giá trị nhỏ nhất: minBy ()

Nó sẽ trả về giá trị tối thiểu có trong danh sách

List<Integer> integers = Arrays.asList(1,2,3,4,5,6,6);
List<String> strings = Arrays.asList("alpha","beta","gamma");
integers
    .stream()
    .collect(Collectors.minBy(Comparator.naturalOrder()))
    .get();
// output: 1
strings
   .stream()
   .collect(Collectors.minBy(Comparator.naturalOrder()))
   .get();
// output: alpha

Nó sẽ trả về 1 và alpha, theo thứ tự tự nhiên của kiểu integer và kiểu string

Chúng ta có thể đảo ngược yêu cầu bằng phương thức reverseOrder () để tìm số lớn nhất.

List<Integer> integers = Arrays.asList(1,2,3,4,5,6,6);
List<String> strings = Arrays.asList("alpha","beta","gamma");
integers
    .stream()
    .collect(Collectors.minBy(Comparator.reverseOrder()))
    .get();
// output: 6
strings
   .stream()
   .collect(Collectors.minBy(Comparator.reverseOrder()))
   .get();
// output: gamma

Chúng ta có thể có một bộ so sánh tùy chỉnh cho các object do người dùng xác định.

6. Tìm giá trị lớn nhất: maxBy ()

List<String> strings = Arrays.asList("alpha","beta","gamma");
strings
   .stream()
   .collect(Collectors.maxBy(Comparator.naturalOrder()))
   .get();
// output: gamma

7. partitioningBy ()

Nó được sử dụng để phân chia một danh sách thành 2 danh sách và thêm nó vào bản đồ. Với 1 điều kiện đi kèm, 1 danh sách thoả mãn điều kiện “true” và một danh sách không thoả mãn điều kiện “false”

List<String> strings = Arrays.asList("a","alpha","beta","gamma");
Map<Boolean, List<String>> collect1 = strings
          .stream()
          .collect(Collectors.partitioningBy(x -> x.length() > 2));
// output: {false=[a], true=[alpha, beta, gamma]}

8. Tạo danh sách không thể thay đổi: toUnmodifiableList ()

Nó được sử dụng để tạo danh sách “chỉ đọc". Bất kỳ cố gắng thực hiện thay đổi nào trong danh sách này sẽ dẫn đến UnsupportedOperationException.

List <String> string = Arrays.asList ("alpha", "beta", "gamma");
Danh sách <String> collect2 = string
.suối()
.collect (Collectors.toUnmodifiableList ());
// đầu ra: ["alpha", "beta", "gamma"]

9. Tạo tập hợp không thể thay đổi: toUnmodifiableSet ()

Mọi cố gắng thực hiện thay đổi trong Set này sẽ dẫn đến UnsupportedOperationException

List<String> strings = Arrays.asList("alpha","beta","gamma","alpha");
Set<String> readOnlySet = strings
       .stream()
       .sorted()
       .collect(Collectors.toUnmodifiableSet());
// output: ["alpha","beta","gamma"]

10. Kết hợp phần tử: joining()

Collectors có thể được sử dụng để tạo một chuỗi bằng cách kết hợp tất cả các phần tử của một bộ sưu tập, có hoặc không có bất kỳ dấu phân cách, hậu tố và tiền tố nào.

List<String> strings = Arrays.asList("alpha","beta","gamma");
String collect3 = strings
     .stream()
     .distinct()
     .collect(Collectors.joining(","));
// output: alpha,beta,gamma
String collect4 = strings
     .stream()
     .map(s -> s.toString())
     .collect(Collectors.joining(",","[","]"));
// output: [alpha,beta,gamma]

Trong ví dụ đầu tiên, chúng tôi đang nối chuỗi có dấu phân cách (“,”) và trong ví dụ thứ hai, chúng tôi truyền giá trị của tiền tố và hậu tố là dấu [ và ].

11. averagingLong()

Tìm giá trị trung bình của tập hợp các “Long values”

Lưu ý: Nó sẽ trả về giá trị Double, không phải giá trị Long

List<Long> longValues = Arrays.asList(100l,200l,300l);
Double d1 = longValues
    .stream()
    .collect(Collectors.averagingLong(x -> x * 2));
// output: 400.0

12.AveragegingInt ()

Tính giá trị trung bình của một tập hợp các giá trị nguyên.

Lưu ý: Nó sẽ trả về giá trị Double, không phải giá trị nguyên.

List<Integer> integers = Arrays.asList(1,2,3,4,5,6,6);
Double d2 = integers
    .stream()
    .collect(Collectors.averagingInt(x -> x*2));
// output: 7.714285714285714

13.AveragegingDouble ()

Tìm giá trị trung bình của tập hợp các giá trị số thực

List<Double> doubles = Arrays.asList(1.1,2.0,3.0,4.0,5.0,5.0);
Double d3 = doubles
    .stream()
    .collect(Collectors.averagingDouble(x -> x));
// output: 3.35

14. toMap()

Tạo map từ các giá trị của một Collection

List<String> strings = Arrays.asList("alpha","beta","gamma");
Map<String,Integer> map = strings
       .stream()
       .collect(Collectors
          .toMap(Function.identity(),String::length));
// output: {alpha=5, beta=4, gamma=5}

15. Xử lý các mục trùng lặp của danh sách trong khi tạo Map

Một danh sách có thể chứa các giá trị trùng lặp, vì vậy nếu chúng ta muốn tạo một map ngoài danh sách và muốn sử dụng các giá trị danh sách làm key của Map thì chúng ta cần giải quyết các key trùng lặp. Vì một Map chỉ chứa các key duy nhất, chúng ta có thể sử dụng trình so sánh để làm điều đó.

List<String> strings = Arrays.asList("alpha","beta","gamma","beta");
Map<String,Integer> map = strings
        .stream()
        .collect(Collectors
          .toMap(Function.identity(),String::length,(i1,i2) -> i1));
// output: {alpha=5, gamma=5, beta=4}

Ở đây, Function.identity () đang trỏ đến giá trị của list và i1, i2 là giá trị của các key trùng lặp. Vì vậy, chúng ta có thể giữ một giá trị duy nhất, ở đây chúng tôi đang chọn i1 nhưng chúng tôi có thể tính toán bất kỳ thứ gì bằng cách sử dụng hai giá trị này như thêm chúng, so sánh và chọn giá trị lớn hơn, v.v.

16. Tính tổng các giá trị nguyên: summingInt ()

VD1: Không phải lúc nào cũng là tính tổng của tập hợp ban đầu, như trong ví dụ dưới đây, chúng tôi đang sử dụng danh sách các chuỗi và trước tiên, chúng tôi chuyển đổi mỗi chuỗi thành một số nguyên bằng với độ dài của nó và sau đó cộng tất cả các độ dài chuỗi

List<String> strings = Arrays.asList("alpha","beta","gamma");
Integer collect4 = strings
      .stream()
      .collect(Collectors.summingInt(String::length));
// output: 18

hoặc VD2: Tính tổng giá trị của list số nguyên trực tiếp

List<Integer> integers = Arrays.asList(1,2,3,4,5,6,6);
Integer sum = integers
    .stream()
    .collect(Collectors.summingInt(x -> x));
// output: 27

17. Tính tổng các giá trị Double: summingDouble ()

Tương tự như tính tổng các số nguyên, chỉ khác là nó được sử dụng cho các giá trị Double

List<Double>  doubleValues = Arrays.asList(1.1,2.0,3.0,4.0,5.0,5.0);
Double sum = doubleValues
     .stream()
     .collect(Collectors.summingDouble(x ->x));
// output: 20.1

18. Tính tổng các giá trị Long : summingLong ()

Tương tự như hai giá trị Integer, Double, summingLong () được sử dụng để tính tổng giá trị Long hoặc int. Chúng ta cũng có thể sử dụng summinglong () cho các giá trị int, nhưng chúng ta không thể sử dụng summingInt () cho các giá trị Long. Nó dựa trên khái niệm định kiểu, khả năng ép kiểu.

List<Long> longValues = Arrays.asList(100l,200l,300l);
Long sum = longValues
    .stream()
    .collect(Collectors.summingLong(x ->x));
// output: 600

19. SummaryInt ()

Nó cung cấp tất cả các giá trị hoạt động số học của các giá trị có trong Collection như giá trị trung bình của tất cả các giá trị, giá trị nhỏ nhất, giá trị lớn nhất, số lượng và tổng của tất cả các giá trị.

List<Integer> integers = Arrays.asList(1,2,3,4,5,6,6);
IntSummaryStatistics stats = integers
          .stream()
          .collect(Collectors.summarizingInt(x -> x ));
//output: IntSummaryStatistics{count=7, sum=27, min=1, average=3.857143, max=6}

Bây giờ chúng ta có thể trích xuất các giá trị khác nhau bằng cách sử dụng các phương thức get như:

stats.getAverage();   // 3.857143
stats.getMax();       // 6
stats.getMin();       // 1
stats.getCount();     // 7
stats.getSum();       // 27

20. Phương thức GroupingBy: groupingBy ()

GroupingBy () là một phương thức nâng cao để tạo một Map từ bất kỳ bộ sưu tập nào khác. Bản thân nó là một chủ đề rất rộng lớn mà chúng ta sẽ đề cập trong blog tiếp theo. Bây giờ hãy cứ quan tâm tới kết quả ví dụ dưới đây:

List<String> strings = Arrays.asList("alpha","beta","gamma");
Map<Integer, List<String>> collect = strings
          .stream()
          .collect(Collectors.groupingBy(String::length));
// output: {4=[beta], 5=[alpha, gamma]}

Nó sẽ tạo độ dài chuỗi làm key và danh sách các chuỗi có độ dài đó làm giá trị.

List<String> strings = Arrays.asList("alpha","beta","gamma");
Map<Integer, LinkedList<String>> collect1 = strings
            .stream()
            .collect(Collectors.groupingBy(String::length,
                Collectors.toCollection(LinkedList::new)));
// output: {4=[beta], 5=[alpha, gamma]}

Ở đây, chúng ta đã chỉ định loại danh sách mình muốn trong Map (danh sách được liên kết).
Chúc các bạn học vui !
Bài dịch từ Medium