Jak mogę uzyskać ostatni element strumienia lub listy w poniższym kodzie?
Gdzie data.careasjest 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()zListinterfejsem, który jest naprawdę uciążliwe.
Nie widzę żadnego argumentu za brakiem podania metody first()a last()w Listinterfejsie, 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 indexOfna każdym elemencie, co najprawdopodobniej nie jest ogólnie pożądane, ponieważ może to pogorszyć wydajność.
StreamAPI nie jest w pełni porównywalne, LINQponieważ 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.getLastktóry używa Iterable, ale jest zoptymalizowany do pracy zList. Irytacją jest to, że nie magetFirst. OgólnieStreamAPI 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.