Depurando o Java 8 Streams com o IntelliJ

Depurando o Java 8 Streams com o IntelliJ

1. Introdução

Desde a introdução do Java 8, muitas pessoas começaram a usar a (nova) funcionalidade de fluxo. Claro, há momentos em que nossas operações de fluxo não funcionam como esperado.

IntelliJ tem, além de seunormal debugging options, uma função de depuração de fluxo dedicada. Neste breve tutorial, vamos explorar esse ótimo recurso.

2. A caixa de diálogo de rastreamento de fluxo

Vamos começar mostrando como abrir a caixa de diálogo Stream Trace. Na barra de ferramentas da janela de depuração, há umTrace Current Stream Chain icon that’s only enabled when our application pauses on a breakpoint inside a stream API call:

The location of the Trace current stream chain icon

Clicar no ícone abrirá a caixa de diálogo Rastreamento de fluxo.

A caixa de diálogo possui dois modos. Vamos dar uma olhada no modo plano no primeiro exemplo. E, no segundo exemplo, mostraremos o modo padrão, que é o modo Split.

3. Exemplos

Agora que apresentamos a funcionalidade de depuração de fluxo no IntelliJ, é hora de trabalhar com alguns exemplos de código.

3.1. Exemplo básico com um fluxo classificado

Vamos começar com um fragmento de código simples para se acostumar com a caixa de diálogo Stream Trace:

int[] listOutputSorted = IntStream.of(-3, 10, -4, 1, 3)
  .sorted()
  .toArray();

Inicialmente. temos um fluxo deint não ordenado. Em seguida, classificamos esse fluxo e o convertemos em uma matriz.

Quando nósview the Stream Trace in Flat Mode, isso nos mostra uma visão geral das etapas que ocorrem:

image

Na extrema esquerda, vemos o fluxo inicial. Ele contémints na ordem em que os escrevemos.

O primeiro conjunto de setas mostra a nova localização de todos os elementos após a classificação. E na extrema direita, vemos nossa produção. Todos os itens aparecem lá em ordem classificada.

Agora que vimos o básico, é hora de um exemplo mais complexo.

3.2. Exemplo usandoflatMap efilter

Este próximo exemplo usaflatMap. Stream.flatMap nos ajuda, por exemplo, a converter uma lista deOptionals em uma lista normal. No próximo exemplo, começamos com uma lista deOptionalCustomers. Em seguida, mapeamos para uma lista deCustomers e aplicamos alguns filtros:

List> customers = Arrays.asList(
    Optional.of(new Customer("John P.", 15)),
    Optional.of(new Customer("Sarah M.", 78)),
    Optional.empty(),
    Optional.of(new Customer("Mary T.", 20)),
    Optional.empty(),
    Optional.of(new Customer("Florian G.", 89)),
    Optional.empty()
);

long numberOf65PlusCustomers = customers
  .stream()
  .flatMap(c -> c
    .map(Stream::of)
    .orElseGet(Stream::empty))
  .mapToInt(Customer::getAge)
  .filter(c -> c > 65)
  .count();

A seguir, vamos ver o Stream Trace no modo Split, que nos dá uma melhor visão geral desse stream.

À esquerda, vemos o fluxo de entrada. A seguir, vemos o mapeamento plano do fluxo deOptional clientes para o fluxo de clientes atuais atuais:

image

Depois disso, mapeamos nosso fluxo de clientes de acordo com a idade:

image

A próxima etapa filtra nosso fluxo de idades para um fluxo superior a 65 anos:

image

Por fim, contamos o número de itens em nosso fluxo de idades:

image

4. Ressalvas

Nos exemplos acima, vimos algumas das possibilidades oferecidas pela caixa de diálogo Rastreamento de fluxo. No entanto, existem alguns detalhes importantes a serem observados. A maioria deles é uma conseqüência direta de como os fluxos funcionam.

Em primeiro lugar,streams always need terminal operations to be executed. Isso não é diferente ao usar a caixa de diálogo Rastreamento de fluxo. Além disso, devemosbe aware of operations that do not consume the entire stream - por exemplo,anyMatch. Nesse caso, ele não mostrará todos os elementos - apenas os elementos que são processados.

Em segundo lugar,be aware that the stream will be consumed. Se declararmosStream separadamente de suas operações, podemos encontrar o erro“Stream has already been operated upon or closed”. Podemos evitar esse erro juntando a declaração do fluxo com seu uso.

5. Conclusão

Neste tutorial rápido, vimos como usar a caixa de diálogo Stream Trace do IntelliJ.

Primeiro, analisamos um caso simples mostrando a classificação e a coleta. Em seguida, analisamos um cenário mais complexo que envolve mapeamento plano, mapeamento, filtragem e contagem.

Por fim, analisamos algumas advertências que poderíamos encontrar ao usar a funcionalidade de depuração de fluxo.

Como sempre, o código-fonte completo do artigo está disponívelover on GitHub.