Jak mogę uzyskać ostatni element strumienia lub listy w poniższym kodzie?
Gdzie data.careas
jest 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?
Jak widać zdobycie pierwszego elementu, z pewnym filter
, nie jest trudne.
Jednak uzyskanie ostatniego elementu w jednolinijce to prawdziwy ból:
- Wygląda na to, że nie mogę go uzyskać bezpośrednio z pliku
Stream
. (Miałoby to sens tylko w przypadku skończonych strumieni) - Wydaje się również, że nie można dostać rzeczy, jak
first()
ilast()
zList
interfejsem, który jest naprawdę uciążliwe.
Nie widzę żadnego argumentu za brakiem podania metody first()
a last()
w List
interfejsie, ponieważ elementy tam są uporządkowane, a ponadto znany jest rozmiar.
Ale zgodnie z pierwotną odpowiedzią: jak uzyskać ostatni element skończonego Stream
?
Osobiście jest to najbliższe, jakie mogłem uzyskać:
int lastIndex = data.careas.stream()
.filter(c -> c.bbox.orientationHorizontal)
.mapToInt(c -> data.careas.indexOf(c)).max().getAsInt();
CArea last = data.careas.get(lastIndex);
Jednak wymaga to użycia indexOf
na każdym elemencie, co najprawdopodobniej nie jest ogólnie pożądane, ponieważ może to pogorszyć wydajność.
Stream
API nie jest w pełni porównywalne, LINQ
ponieważ oba są wykonywane w zupełnie innym paradygmacie. Nie jest gorzej ani lepiej, jest po prostu inaczej. I zdecydowanie brakuje niektórych metod nie dlatego, że
Iterables.getLast
który używa Iterable, ale jest zoptymalizowany do pracy zList
. Irytacją jest to, że nie magetFirst
. OgólnieStream
API jest strasznie analne, pomijając wiele wygodnych metod. C # LINQ, przez constrast, z przyjemnością zapewnia,.Last()
a nawet.Last(Func<T,Boolean> predicate)
, mimo że obsługuje również nieskończone Enumerables.