Como obter o último elemento de um fluxo em Java?
1. Visão geral
A API JavaStream foi o principal recurso da versão Java 8. Streams representam sequências de objetos avaliadas lentamente e fornecem uma API rica, fluente e monádica.
Neste artigo, daremos uma olhada rápida nas maneiras de obter o último elemento de aStream.. Lembre-se de quedue to the nature of streams, it’s not a natural operation. Sempre certifique-se de que você não está trabalhando com infinitoStreams.
2. Usando a APIReduce
Reduce, simplesmente, reduz o conjunto de elementos em aStream a um único elemento.
Neste caso, vamos reduzir o conjunto de elementos para obter o último elemento emStream.. Lembre-se de quethis method will only return deterministic results for sequential Streams.
Vamos usarList dos valores deString, obterStream deListe reduzir:
List valueList = new ArrayList<>();
valueList.add("Joe");
valueList.add("John");
valueList.add("Sean");
Stream stream = valueList.stream();
stream.reduce((first, second) -> second)
.orElse(null);
Aqui, o fluxo é reduzido para um nível em que fica apenas o último elemento. Se o fluxo estiver vazio, ele retornará um valornull.
2. Usando a função Ignorar
A outra maneira de obter o último elemento do fluxo éby skipping all the elements before it. Isso pode ser alcançado usando a funçãoSkip da classeStream. Lembre-se de que, neste caso, estamos consumindoStream duas vezes, portanto, há algum impacto claro no desempenho.
Vamos criar umList de valores de string e usar sua funçãosize para determinar quantos elementos pular para chegar ao último elemento.
Aqui está o código de exemplo obtendo o último elemento usandoskip:
List valueList = new ArrayList();
valueList.add("Joe");
valueList.add("John");
valueList.add("Sean");
long count = valueList.stream().count();
Stream stream = valueList.stream();
stream.skip(count - 1).findFirst().get();
“Sean” acaba sendo o último elemento.
4. Obtendo o último elemento de um fluxo infinito
Tentar obter o último elemento do fluxo infinito levaria a uma sequência infinita de avaliação realizada em elementos infinitos. Tantoskipereduce não voltarão da execução da avaliação, a menos que limitemos o fluxo infinito a um número específico de elementos usando a operaçãolimit.
Aqui está o código de exemplo em que pegamos um fluxo infinito e tentamos obter o último elemento:
Stream stream = Stream.iterate(0, i -> i + 1);
stream.reduce((first, second) -> second).orElse(null);
Consequentemente, o stream não voltará da avaliação e terminará emhalting the execution of the program.
5. Conclusão
Vimos maneiras diferentes de obter o último elemento deStream usando APIsreduceeSkip. Também analisamos por que isso não é possível com fluxos infinitos.
Vimos que obter o último elemento de aStream não é fácil em comparação com obtê-lo de outras estruturas de dados. Isso ocorre devido à natureza preguiçosa deStreams que não são avaliados a menos que a função de terminal seja chamada ewe never know if the currently evaluated element is the last one.
Trechos de código podem ser encontradosover on GitHub.