Làm cách nào để lấy phần tử cuối cùng của luồng hoặc danh sách trong đoạn mã sau?
Đâu data.careas
là List<CArea>
:
CArea first = data.careas.stream()
.filter(c -> c.bbox.orientationHorizontal).findFirst().get();
CArea last = data.careas.stream()
.filter(c -> c.bbox.orientationHorizontal)
.collect(Collectors.toList()).; //how to?
Như bạn có thể thấy để có được yếu tố đầu tiên, với một số yếu tố nhất định filter
, không khó.
Tuy nhiên, nhận được phần tử cuối cùng trong một lớp lót là một nỗi đau thực sự:
- Có vẻ như tôi không thể lấy nó trực tiếp từ a
Stream
. (Nó chỉ có ý nghĩa đối với các luồng hữu hạn) - Có vẻ như bạn không thể nhận được những thứ như
first()
vàlast()
từList
giao diện, đó thực sự là một điều khó khăn.
Tôi không thấy bất kỳ đối số nào về việc không cung cấp một first()
và last()
phương thức trong List
giao diện, vì các phần tử trong đó, được sắp xếp theo thứ tự và hơn nữa kích thước cũng được biết đến.
Nhưng theo câu trả lời ban đầu: Làm thế nào để lấy phần tử cuối cùng của một hữu hạn Stream
?
Cá nhân, đây là gần nhất tôi có thể nhận được:
int lastIndex = data.careas.stream()
.filter(c -> c.bbox.orientationHorizontal)
.mapToInt(c -> data.careas.indexOf(c)).max().getAsInt();
CArea last = data.careas.get(lastIndex);
Tuy nhiên, nó liên quan đến việc sử dụng một indexOf
trên mọi phần tử, điều mà bạn thường không muốn vì nó có thể làm giảm hiệu suất.
Stream
API không hoàn toàn có thể so sánh được LINQ
vì cả hai đều được thực hiện trong một mô hình rất khác nhau. Nó không tệ hơn hay tốt hơn mà chỉ là khác biệt. Và chắc chắn một số phương pháp vắng mặt không phải vì các nhà phát triển oracle không đủ năng lực hoặc xấu tính :)
Iterables.getLast
có thể lặp lại được nhưng được tối ưu hóa để hoạt độngList
. Một con vật cưng là nó không cógetFirst
. CácStream
API nói chung là khủng khiếp hậu môn, bỏ qua rất nhiều phương pháp tiện lợi. LINQ của C #, theo ràng buộc, rất sẵn lòng cung cấp.Last()
và thậm chí.Last(Func<T,Boolean> predicate)
, mặc dù nó cũng hỗ trợ các Enumerables vô hạn.