tôi tự hỏi là có một thay thế choNhận n phần tử cuối cùng từ dòng
List<X> lastN = all.subList(Math.max(0, all.size() - n), all.size());
với stream sử dụng?
tôi tự hỏi là có một thay thế choNhận n phần tử cuối cùng từ dòng
List<X> lastN = all.subList(Math.max(0, all.size() - n), all.size());
với stream sử dụng?
Bạn có thể viết một nhà sưu tập tùy chỉnh như thế này:
public static <T> Collector<T, ?, List<T>> lastN(int n) {
return Collector.<T, Deque<T>, List<T>>of(ArrayDeque::new, (acc, t) -> {
if(acc.size() == n)
acc.pollFirst();
acc.add(t);
}, (acc1, acc2) -> {
while(acc2.size() < n && !acc1.isEmpty()) {
acc2.addFirst(acc1.pollLast());
}
return acc2;
}, ArrayList<T>::new);
}
Và sử dụng nó như thế này:
List<String> lastTen = input.stream().collect(lastN(10));
Bạn không cần phải viết 'ArrayList
@Holger, trước tiên tôi viết 'ArrayList :: new', nhưng Eclipse đã hiển thị cảnh báo về hàm tạo không được kiểm tra. Vâng, có lẽ đó là một vấn đề ECJ cụ thể. –
Điều thú vị là, 'ArrayDeque :: new' sẽ được hưởng lợi từ một nhân chứng kiểu, khi sử dụng' ArrayDeque
Sử dụng Stream.skip()
Trả về một dòng gồm các yếu tố còn lại của dòng này sau khi loại bỏ các yếu tố n đầu tiên của dòng. Nếu luồng này chứa ít hơn n phần tử thì luồng trống sẽ được trả lại.
all.stream().skip(Math.max(0, all.size() - n)).forEach(doSomething);
Trong trường hợp dòng có kích thước không rõ, có lẽ không có cách nào xung quanh tiêu thụ toàn bộ dòng và đệm n
yếu tố cuối cùng gặp cho đến nay. Bạn có thể làm điều này bằng cách sử dụng một số loại deque, hoặc một vòng đệm chuyên dụng tự động duy trì kích thước tối đa của nó (xem this related question cho một số triển khai).
public static <T> List<T> lastN(Stream<T> stream, int n) {
Deque<T> result = new ArrayDeque<>(n);
stream.forEachOrdered(x -> {
if (result.size() == n) {
result.pop();
}
result.add(x);
});
return new ArrayList<>(result);
}
Tất cả những hoạt động (size
, pop
, add
) nên có độ phức tạp của O (1), vì vậy mức độ phức tạp tổng thể cho một dòng với chiều dài (không rõ) n sẽ O (n).
Tôi không nghĩ rằng đây là thường có thể với suối, như kích thước của một dòng suối có thể không được biết đến là một ưu tiên, hoặc thậm chí nó có thể là vô hạn. Và nếu bạn tạo luồng từ danh sách, chỉ cần sử dụng danh sách phụ, như bạn đã làm. –
@tobias_k OP dường như có một danh sách hữu hạn tuy nhiên ... – Puce
Nếu bạn đã có một danh sách, sau đó 'subList' là con đường để đi. Sau đó, bạn có thể sao chép, truyền trực tuyến, bất kỳ điều gì bạn muốn. –