Como posso obter o último elemento de um fluxo ou lista no código a seguir?
Onde data.careas
está um 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 você pode ver, pegar o primeiro elemento, com uma certa filter
, não é difícil.
No entanto, obter o último elemento em uma linha é uma verdadeira dor:
- Parece que não posso obtê-lo diretamente de a
Stream
. (Só faria sentido para fluxos finitos) - Também parece que você não pode obter coisas como
first()
elast()
daList
interface, o que é realmente uma dor.
Não vejo nenhum argumento para não fornecer um método first()
e last()
na List
interface, pois os elementos lá são ordenados e, além disso, o tamanho é conhecido.
Mas de acordo com a resposta original: Como obter o último elemento de um finito Stream
?
Pessoalmente, isso é o mais próximo que consegui:
int lastIndex = data.careas.stream()
.filter(c -> c.bbox.orientationHorizontal)
.mapToInt(c -> data.careas.indexOf(c)).max().getAsInt();
CArea last = data.careas.get(lastIndex);
No entanto, envolve o uso de um indexOf
em todos os elementos, o que geralmente você não deseja, pois pode prejudicar o desempenho.
Stream
A API não é totalmente comparável, LINQ
já que ambas são feitas em um paradigma muito diferente. Não é pior ou melhor, é apenas diferente. E, definitivamente, alguns métodos estão ausentes, não porque os desenvolvedores de oráculos sejam incompetentes ou mesquinhos :)
Iterables.getLast
que leva Iterable, mas é otimizado para funcionarList
. Uma implicância é que ele não temgetFirst
. AStream
API em geral é terrivelmente anal, omitindo muitos métodos de conveniência. O LINQ do C #, por contraste, tem o prazer de fornecer.Last()
e até mesmo.Last(Func<T,Boolean> predicate)
, embora ofereça suporte a Enumerables infinitos também.