Đối với những người yêu thích lập trình Java, việc sử dụng các phương thức trong lớp Collectors là một kỹ năng cần thiết để xử lý dữ liệu hiệu quả hơn. Dưới đây là 20 phương pháp phổ biến trong Collectors mà bạn nên biết.
Chuyển đổi thành danh sách: toList()
Dùng để tích lũy các phần tử vào một danh sách. Nó tạo ra một danh sách mới mà không làm thay đổi danh sách hiện tại.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 6);
numbers.stream().map(x -> x * x).collect(Collectors.toList());
// Kết quả: [1, 4, 9, 16, 25, 36, 36]
Chuyển đổi thành tập hợp: toSet()
Dùng để tích lũy các phần tử vào một tập hợp, loại bỏ các phần tử trùng lặp.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 6);
numbers.stream().map(x -> x * x).collect(Collectors.toSet());
// Kết quả: [1, 4, 9, 16, 25, 36]
Tạo tập hợp cụ thể: toCollection()
Cho phép tích lũy các phần tử vào một kiểu tập hợp cụ thể.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 6);
numbers.stream().filter(x -> x > 2).collect(Collectors.toCollection(LinkedList::new));
// Kết quả: [3, 4, 5, 6, 6]
Đếm số lượng phần tử: counting()
Dùng để đếm số lượng phần tử thỏa mãn điều kiện.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 6);
Long count = numbers.stream().filter(x -> x < 4).collect(Collectors.counting());
// Kết quả: 3
Tìm giá trị nhỏ nhất: minBy()
Trả về phần tử nhỏ nhất trong danh sách dựa trên so sánh tự nhiên.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 6);
List<String> words = Arrays.asList("alpha", "beta", "gamma");
numbers.stream().collect(Collectors.minBy(Comparator.naturalOrder())).get();
// Kết quả: 1
words.stream().collect(Collectors.minBy(Comparator.naturalOrder())).get();
// Kết quả: alpha
// Sử dụng reverseOrder để đảo ngược
numbers.stream().collect(Collectors.minBy(Comparator.reverseOrder())).get();
// Kết quả: 6
words.stream().collect(Collectors.minBy(Comparator.reverseOrder())).get();
// Kết quả: gamma
Tìm giá trị lớn nhất: maxBy()
Tương tự như minBy nhưng tìm giá trị lớn nhất.
List<String> words = Arrays.asList("alpha", "beta", "gamma");
words.stream().collect(Collectors.maxBy(Comparator.naturalOrder())).get();
// Kết quả: gamma
Phân nhóm theo điều kiện: partitioningBy()
Chia danh sách thành hai phần dựa trên điều kiện, mỗi phần được lưu trong một Map với key là true hoặc false.
List<String> words = Arrays.asList("a", "alpha", "beta", "gamma");
Map<Boolean, List<String>> result = words.stream().collect(Collectors.partitioningBy(x -> x.length() > 2));
// Kết quả: {false=[a], true=[alpha, beta, gamma]}
Tạo danh sách chỉ đọc: toUnmodifiableList()
Tạo một danh sách không thể chỉnh sửa, bất kỳ thay đổi nào đều dẫn đến lỗi.
List<String> words = Arrays.asList("alpha", "beta", "gamma");
List<String> readOnlyList = words.stream().collect(Collectors.toUnmodifiableList());
// Kết quả: ["alpha", "beta", "gamma"]
Tạo tập hợp chỉ đọc: toUnmodifiableSet()
Tạo một tập hợp không thể chỉnh sửa và loại bỏ phần tử trùng lặp.
List<String> words = Arrays.asList("alpha", "beta", "gamma", "alpha");
Set<String> readOnlySet = words.stream().sorted().collect(Collectors.toUnmodifiableSet());
// Kết quả: ["alpha", "beta", "gamma"]
Nối chuỗi: joining()
Kết nối các phần tử của danh sách thành một chuỗi.
List<String> words = Arrays.asList("alpha", "beta", "gamma");
String joined = words.stream().distinct().collect(Collectors.joining(","));
// Kết quả: alpha,beta,gamma
String joinedWithBrackets = words.stream().map(s -> s.toString()).collect(Collectors.joining(",", "[", "]"));
// Kết quả: [alpha,beta,gamma]
Tính trung bình cho Long: averagingLong()
Tính giá trị trung bình của một danh sách số Long.
List<Long> values = Arrays.asList(100L, 200L, 300L);
Double avg = values.stream().collect(Collectors.averagingLong(x -> x * 2));
// Kết quả: 400.0
Tính trung bình cho Integer: averagingInt()
Tính giá trị trung bình của một danh sách số Integer.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 6);
Double avg = numbers.stream().collect(Collectors.averagingInt(x -> x * 2));
// Kết quả: 7.714285714285714
Tính trung bình cho Double: averagingDouble()
Tính giá trị trung bình của một danh sách số Double.
List<Double> values = Arrays.asList(1.1, 2.0, 3.0, 4.0, 5.0, 5.0);
Double avg = values.stream().collect(Collectors.averagingDouble(x -> x));
// Kết quả: 3.35
Tạo Map từ danh sách: toMap()
Tạo một Map từ các phần tử trong danh sách.
List<String> words = Arrays.asList("alpha", "beta", "gamma");
Map<String, Integer> map = words.stream().collect(Collectors.toMap(Function.identity(), String::length));
// Kết quả: {alpha=5, beta=4, gamma=5}
Xử lý trùng lặp khi tạo Map
Khi có phần tử trùng lặp, bạn có thể chỉ định cách xử lý chúng bằng cách cung cấp hàm hợp nhất.
List<String> words = Arrays.asList("alpha", "beta", "gamma", "beta");
Map<String, Integer> map = words.stream().collect(Collectors.toMap(Function.identity(), String::length, (i1, i2) -> i1));
// Kết quả: {alpha=5, gamma=5, beta=4}
Tổng số nguyên: summingInt()
Tính tổng các số nguyên trong danh sách.
List<String> words = Arrays.asList("alpha", "beta", "gamma");
Integer totalLength = words.stream().collect(Collectors.summingInt(String::length));
// Kết quả: 18
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 6);
Integer sum = numbers.stream().collect(Collectors.summingInt(x -> x));
// Kết quả: 27
Tổng số thực: summingDouble()
Tính tổng các số thực trong danh sách.
List<Double> values = Arrays.asList(1.1, 2.0, 3.0, 4.0, 5.0, 5.0);
Double sum = values.stream().collect(Collectors.summingDouble(x -> x));
// Kết quả: 20.1
Tổng số dài: summingLong()
Tính tổng các số dài trong danh sách.
List<Long> values = Arrays.asList(100L, 200L, 300L);
Long sum = values.stream().collect(Collectors.summingLong(x -> x));
// Kết quả: 600
Tổng hợp thống kê cho số nguyên: summarizingInt()
Cung cấp thông tin tổng quan về danh sách số nguyên như trung bình, tối thiểu, tối đa, tổng và số lượng.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 6);
IntSummaryStatistics stats = numbers.stream().collect(Collectors.summarizingInt(x -> x));
// Kết quả: IntSummaryStatistics{count=7, sum=27, min=1, average=3.857143, max=6}
stats.getAverage(); // 3.857143
stats.getMax(); // 6
stats.getMin(); // 1
stats.getCount(); // 7
stats.getSum(); // 27
Phân nhóm theo thuộc tính: groupingBy()
Tạo một Map từ danh sách dựa trên một thuộc tính cụ thể.
List<String> words = Arrays.asList("alpha", "beta", "gamma");
Map<Integer, List<String>> grouped = words.stream().collect(Collectors.groupingBy(String::length));
// Kết quả: {4=[beta], 5=[alpha, gamma]}
// Chỉ định kiểu danh sách trong Map
Map<Integer, LinkedList<String>> groupedWithList = words.stream().collect(Collectors.groupingBy(String::length, Collectors.toCollection(LinkedList::new)));
// Kết quả: {4=[beta], 5=[alpha, gamma]}