Como obter o último elemento de um fluxo em Java?

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.