Việc giảm bình thường có nghĩa là kết hợp hai giá trị bất biến như int, double, v.v. và tạo ra một giá trị mới; đó là một sự giảm thiểu bất biến . Ngược lại, phương pháp thu thập được thiết kế để biến đổi một thùng chứa để tích lũy kết quả mà nó được cho là tạo ra.
Để minh họa vấn đề, giả sử bạn muốn đạt được Collectors.toList()
bằng cách sử dụng một cách giảm đơn giản như
List<Integer> numbers = stream.reduce(
new ArrayList<Integer>(),
(List<Integer> l, Integer e) -> {
l.add(e);
return l;
},
(List<Integer> l1, List<Integer> l2) -> {
l1.addAll(l2);
return l1;
});
Điều này là tương đương với Collectors.toList()
. Tuy nhiên, trong trường hợp này bạn đột biến List<Integer>
. Như chúng ta biết ArrayList
là không an toàn luồng, cũng không an toàn để thêm / xóa giá trị khỏi nó trong khi lặp lại, do đó bạn sẽ có ngoại lệ đồng thời ArrayIndexOutOfBoundsException
hoặc bất kỳ loại ngoại lệ nào (đặc biệt là khi chạy song song) khi bạn cập nhật danh sách hoặc trình kết hợp cố gắng hợp nhất các danh sách vì bạn đang thay đổi danh sách bằng cách tích lũy (thêm) các số nguyên vào danh sách đó. Nếu bạn muốn làm cho chủ đề này an toàn, bạn cần phải vượt qua một danh sách mới mỗi lần sẽ làm giảm hiệu suất.
Ngược lại, các Collectors.toList()
công trình trong một thời trang tương tự. Tuy nhiên, nó đảm bảo an toàn luồng khi bạn tích lũy các giá trị vào danh sách. Từ tài liệu cho collect
phương pháp :
Thực hiện thao tác giảm có thể thay đổi trên các phần tử của luồng này bằng Collector. Nếu luồng song song và Collector đồng thời và luồng không được sắp xếp hoặc collector không được sắp xếp, thì việc giảm đồng thời sẽ được thực hiện. Khi được thực hiện song song, nhiều kết quả trung gian có thể được khởi tạo, điền và hợp nhất để duy trì sự cô lập của các cấu trúc dữ liệu có thể thay đổi. Do đó, ngay cả khi được thực thi song song với các cấu trúc dữ liệu không an toàn luồng (như ArrayList), không cần đồng bộ hóa bổ sung để giảm song song.
Để trả lời câu hỏi của bạn:
Khi nào bạn sẽ sử dụng collect()
vs reduce()
?
nếu bạn có giá trị bất biến như ints
, doubles
, Strings
sau đó giảm bình thường làm việc tốt. Tuy nhiên, nếu bạn phải reduce
nói các giá trị của mình List
(cấu trúc dữ liệu có thể thay đổi) thì bạn cần sử dụng collect
phương pháp giảm đột biến với phương thức.