Як я можу отримати останній елемент потоку чи списку в наступному коді?
Де 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інтерфейсу, який насправді біль.
Я не бачу жодного аргументу щодо не надання a 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 взагалі жахливо анальний, опускаючи безліч зручних методів. C # 's LINQ, звичайно, радий надавати.Last()і навіть.Last(Func<T,Boolean> predicate), хоча він також підтримує нескінченні перелічі.