¿Cómo puedo obtener el último elemento de una secuencia o lista en el siguiente código?
¿Dónde data.careas
está 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?
Como puede ver, conseguir el primer elemento, con un cierto filter
, no es difícil.
Sin embargo, obtener el último elemento en una sola línea es un verdadero dolor:
- Parece que no puedo obtenerlo directamente de a
Stream
. (Solo tendría sentido para flujos finitos) - También parece que no puede obtener cosas como
first()
ylast()
desde laList
interfaz, lo cual es realmente una molestia.
No veo ningún argumento para no proporcionar un método first()
y last()
en la List
interfaz, ya que los elementos allí están ordenados y, además, se conoce el tamaño.
Pero según la respuesta original: ¿Cómo obtener el último elemento de un finito Stream
?
Personalmente, esto es lo más cercano que pude conseguir:
int lastIndex = data.careas.stream()
.filter(c -> c.bbox.orientationHorizontal)
.mapToInt(c -> data.careas.indexOf(c)).max().getAsInt();
CArea last = data.careas.get(lastIndex);
Sin embargo, implica el uso de un indexOf
en cada elemento, lo que probablemente no es lo que generalmente desea, ya que puede afectar el rendimiento.
Stream
API no es completamente comparable LINQ
ya que ambas se realizan en un paradigma muy diferente. No es peor ni mejor, simplemente es diferente. Y definitivamente, algunos métodos están ausentes no porque los desarrolladores de Oracle sean incompetentes o malos :)
Iterables.getLast
que lleva Iterable pero está optimizado para trabajarList
. Una manía es que no tienegetFirst
. LaStream
API en general es horriblemente anal, omitiendo muchos métodos de conveniencia. LINQ de C #, por restricción, se complace en proporcionar.Last()
e incluso.Last(Func<T,Boolean> predicate)
, aunque también admite infinitos Enumerables.