Hướng Dẫn Bắt Đầu Với Gatherers Trong Java
Giới thiệu
Gatherers là một tính năng mạnh mẽ trong Java Stream, cho phép bạn xử lý dữ liệu một cách linh hoạt hơn so với các phương thức như map hay filter. Trong bài viết này, chúng ta sẽ khám phá Gatherers, cách sử dụng chúng và một số ví dụ thực tế.
Gatherers là gì?
Gatherer là một loại operator cho phép bạn:
- Phát sinh không, một hoặc nhiều đầu ra cho mỗi đầu vào.
- Giữ trạng thái thay đổi trong quá trình xử lý.
- Dừng sớm khi cần thiết.
- Định nghĩa cách hoạt động trong các stream song song.
Hãy nghĩ về nó như một operator tùy chỉnh có thể cắm vào cho các stream.
Các Gatherers có sẵn trong Java
Java cung cấp một số Gatherers sẵn có:
Gatherers.windowFixed(n)– chia thành danh sách gồm n phần tử.Gatherers.windowSliding(n)– cửa sổ trượt của n phần tử.Gatherers.scan(identity, op)– tổng chạy (prefix sums).Gatherers.fold(...)– tích lũy thành một kết quả cho mỗi nhóm.Gatherers.mapConcurrent(...)– ánh xạ bất đồng bộ với kiểm soát đồng thời.
Ví dụ 1: Cửa sổ trượt
java
import java.util.List;
import java.util.stream.Gatherers;
public class SlidingWindowExample {
public static void main(String[] args) {
List<Integer> data = List.of(1, 2, 3, 4, 5);
data.stream()
.gather(Gatherers.windowSliding(3))
.forEach(System.out::println);
// Kết quả:
// [1, 2, 3]
// [2, 3, 4]
// [3, 4, 5]
}
}
Ví dụ 2: Tổng tiền tố
java
import java.util.List;
import java.util.stream.Gatherers;
public class PrefixSumExample {
public static void main(String[] args) {
List<Integer> numbers = List.of(1, 2, 3, 4);
numbers.stream()
.gather(Gatherers.scan(0, Integer::sum))
.forEach(System.out::println);
// Kết quả: 0, 1, 3, 6, 10
}
}
Ví dụ 3: Ánh xạ song song
java
import java.util.stream.Gatherers;
public class ConcurrentMapExample {
public static void main(String[] args) {
var data = java.util.stream.IntStream.range(1, 10).boxed();
data.gather(Gatherers.mapConcurrent(4, x -> {
System.out.println("Đang xử lý " + x + " trong " + Thread.currentThread());
return x * x;
})).forEach(System.out::println);
}
}
Khi nào nên sử dụng Gatherers?
- Khi các thao tác stream có sẵn không đủ.
- Đối với cửa sổ trượt, distinct-by, bộ lọc tùy chỉnh hoặc các thao tác tích lũy.
- Khi bạn muốn cải thiện hiệu suất bằng cách gộp nhiều bước thành một.
Tóm tắt
Gatherers giống như các operator tùy chỉnh cho các stream. Bắt đầu với các Gatherers có sẵn, và khi bạn đã quen, hãy chuyển sang viết các Gatherers của riêng mình.
Best Practices
- Giữ trạng thái tối thiểu — tránh chiếm nhiều bộ nhớ.
- Sử dụng
combinernếu bạn muốn hỗ trợ stream song song. - Trả về
falsetrongintegratorđể dừng sớm. - Gộp các gatherers cho các pipeline phức tạp (ví dụ: cửa sổ → lọc → dừng).
Câu hỏi thường gặp
Q: Gatherers có thể sử dụng cho loại dữ liệu nào?
A: Gatherers có thể xử lý bất kỳ loại dữ liệu nào mà bạn có thể chuyển đổi thành stream.
Q: Có cần biết gì đặc biệt khi sử dụng Gatherers không?
A: Bạn cần nắm rõ cách hoạt động của các phương thức và cách quản lý trạng thái để tận dụng tối đa sức mạnh của Gatherers.
Kết luận
Gatherers trong Java mang lại sức mạnh và tính linh hoạt cho việc xử lý dữ liệu. Hãy bắt đầu với các Gatherers có sẵn và dần dần khám phá cách tạo các Gatherers tùy chỉnh cho nhu cầu riêng của bạn. Hãy thử nghiệm và chia sẻ những gì bạn học được!