Bạn có thể chuyển đổi chức năng này để một chức năng kết hợp, như được giải thích trong this answer tại ví dụ về List.hashCode()
. Sự khác biệt chỉ nằm trong hệ số (2
so với 31
) và giá trị bắt đầu (1
so với 0
).
Nó có thể được thích nghi với nhiệm vụ của bạn, đó là đặc biệt dễ dàng khi bạn có một đầu vào truy cập ngẫu nhiên giống như một String
:
Function<String, Integer> f =
s -> IntStream.range(0, s.length()).map(i -> s.charAt(i)<<(s.length()-i-1)).sum();
Điều này thậm chí sẽ chạy song song, nhưng nó không chắc rằng bạn đã bao giờ gặp phải như vậy khổng lồ chuỗi mà một đánh giá song song cung cấp một lợi ích. Vì vậy, những gì còn lại, đó là hầu hết mọi người có thể xem xét giải pháp này ít có thể đọc được hơn một for
vòng lặp đơn giản ...
Lưu ý rằng giải pháp trên thể hiện một hành vi tràn khác nhau, ví dụ nếu String
có hơn 32 char
s, do với việc sử dụng toán tử shift thay vì nhân với hai.
Việc sửa chữa cho vấn đề này làm cho các giải pháp hiệu quả hơn:
Function<String, Integer> f = s ->
IntStream.range(Math.max(0, s.length()-32), s.length())
.map(i -> s.charAt(i)<<(s.length()-i-1)).sum();
Nếu chuỗi có hơn 32 char
s, nó chỉ xử lý 32 char
s cuối cùng, đó là đã đủ để tính toán kết quả tương tự như chức năng ban đầu của bạn.
Bạn không thể. Chỉ cần sử dụng một vòng lặp goold cũ. –
Bạn đang nói về hàm 'f' hoặc' (a, b) -> 2 * a + b'? nếu nó là 'f', tôi nghĩ rằng nó an toàn để sử dụng nó trong bất kỳ luồng song song nào; nếu nó là '(a, b) -> 2', nó cũng sẽ ổn vì tôi không thấy lý do nào để làm:' s.chars(). parallel(). reduce (0, (a, b) - > 2 * a + b) ' –