Как я могу получить последний элемент потока или списка в следующем коде?
Где 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каждого элемента, что, скорее всего, вам обычно не нужно, поскольку это может снизить производительность.
StreamAPI нельзя полностью сопоставить с ним, LINQпоскольку оба выполнены в совершенно другой парадигме. Это не хуже и не лучше, это просто другое. И определенно некоторые методы отсутствуют не потому, что разработчики оракула некомпетентны или
Iterables.getLastкоторый использует Iterable, но оптимизирован для работыList. Любимая мозоль в том, что этого нетgetFirst.StreamAPI вообще ужасно анальный, опуская множество удобных методов. LINQ C #, напротив, рад предоставить.Last()и даже.Last(Func<T,Boolean> predicate), хотя он также поддерживает бесконечные перечисления.