Как я могу получить последний элемент потока или списка в следующем коде?
Где data.careas
находится 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?
Как видите, получить первый элемент filter
не сложно.
Однако получение последнего элемента в однострочнике - настоящая боль:
- Кажется, я не могу получить его напрямую от
Stream
. (Это имело бы смысл только для конечных потоков) - Также кажется, что вы не можете получить что-то вроде
first()
иlast()
изList
интерфейса, что действительно неприятно.
Я не вижу никаких аргументов для не обеспечивая first()
и last()
метод в List
интерфейсе, как элементы в наличии, упорядочены, и , кроме того размер известен.
Но согласно первоначальному ответу: как получить последний элемент конечного Stream
?
Лично мне это ближе всего:
int lastIndex = data.careas.stream()
.filter(c -> c.bbox.orientationHorizontal)
.mapToInt(c -> data.careas.indexOf(c)).max().getAsInt();
CArea last = data.careas.get(lastIndex);
Однако это подразумевает использование для indexOf
каждого элемента, что, скорее всего, вам обычно не нужно, поскольку это может снизить производительность.
Stream
API нельзя полностью сопоставить с ним, LINQ
поскольку оба выполнены в совершенно другой парадигме. Это не хуже и не лучше, это просто другое. И определенно некоторые методы отсутствуют не потому, что разработчики оракула некомпетентны или
Iterables.getLast
который использует Iterable, но оптимизирован для работыList
. Любимая мозоль в том, что этого нетgetFirst
.Stream
API вообще ужасно анальный, опуская множество удобных методов. LINQ C #, напротив, рад предоставить.Last()
и даже.Last(Func<T,Boolean> predicate)
, хотя он также поддерживает бесконечные перечисления.