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.careaslà 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ừListgiao 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 Listgiao 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 indexOftrê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.
StreamAPI không hoàn toàn có thể so sánh được LINQvì 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.getLastcó 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ácStreamAPI 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.