Como posso obter o último elemento de um fluxo ou lista no código a seguir?
Onde data.careasestá 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()daListinterface, o que é realmente uma dor.
Não vejo nenhum argumento para não fornecer um método first()e last()na Listinterface, 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 indexOfem todos os elementos, o que geralmente você não deseja, pois pode prejudicar o desempenho.
StreamA API não é totalmente comparável, LINQjá 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.getLastque leva Iterable, mas é otimizado para funcionarList. Uma implicância é que ele não temgetFirst. AStreamAPI 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.