Come posso ottenere l'ultimo elemento di uno stream o di un elenco nel codice seguente?
Dov'è data.careas
un 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?
Come puoi vedere ottenere il primo elemento, con un certo filter
, non è difficile.
Tuttavia, ottenere l'ultimo elemento in una battuta è un vero dolore:
- Sembra che non sia possibile ottenerlo direttamente da un file
Stream
. (Avrebbe senso solo per flussi finiti) - Sembra inoltre che non è possibile ottenere le cose come
first()
elast()
dallaList
interfaccia, che è davvero un dolore.
Non vedo alcun argomento per non fornire un metodo first()
e nell'interfaccia, poiché gli elementi in essa sono ordinati e inoltre la dimensione è nota.last()
List
Ma secondo la risposta originale: come ottenere l'ultimo elemento di un finito Stream
?
Personalmente, questo è il massimo che potrei ottenere:
int lastIndex = data.careas.stream()
.filter(c -> c.bbox.orientationHorizontal)
.mapToInt(c -> data.careas.indexOf(c)).max().getAsInt();
CArea last = data.careas.get(lastIndex);
Tuttavia implica l'uso di un indexOf
su ogni elemento, che molto probabilmente non si desidera in genere in quanto può compromettere le prestazioni.
Stream
L'API non è completamente paragonabile a LINQ
poiché entrambe sono realizzate in un paradigma molto diverso. Non è peggio o meglio, è solo diverso. E sicuramente alcuni metodi sono assenti non perché gli sviluppatori di Oracle siano incompetenti o cattivi :)
Iterables.getLast
che accetta Iterable ma è ottimizzato per funzionareList
. Un problema domestico è che non hagetFirst
. L'Stream
API in generale è orribilmente anale, omettendo molti metodi di convenienza. LINQ di C #, per contrasto, è felice di fornire.Last()
e persino.Last(Func<T,Boolean> predicate)
, anche se supporta anche Enumerable infiniti.