Neste artigo, veremos um novo coletor introduzido no Java 12. Esse novo recurso não foi anunciado no JEP oficial, pois era uma solicitação de alteração secundária com o título "
Criar Coletor, que mescla os resultados de outros dois coletores ". Ele foi projetado para combinar resultados de dois coletores.
Tudo interessante - sob o corte
Se você ainda não sabe o que são colecionadoresColetores são classes especiais usadas para converter um fluxo em outra estrutura de dados. Por exemplo, na
list
:
list = Stream.of(1,2,3).collect(Collectors.toList());
Este é um exemplo inútil, porque cria um novo fluxo e o transforma imediatamente. Pensa-se mostrar o uso de colecionadores
A documentação
Clique aqui para ver os
Collectors#teeing
. De acordo com a documentação oficial:
“... retorna um coletor composto por dois coletores subordinados. Cada elemento transferido para o coletor resultante é processado pelos dois coletores subordinados e, em seguida, seus resultados são combinados usando uma função especial que os conecta ao resultado final. ”
O original"... retorna um coletor que é composto de dois coletores a jusante. Cada elemento passado ao coletor resultante é processado pelos dois coletores a jusante, e seus resultados são mesclados usando a função de mesclagem especificada no resultado final."
Cabeçalho do método:
static <T, R1, R2, R> Collector<T, ?, R> teeing( Collector<? super T, ?, R1> downstream1, Collector<? super T, ?, R2> downstream2, BiFunction<? super R1, ? super R2, R> merger)
Fato interessante
Este é um
tee (tee do inglês):

Teeing
veio de um tee. De acordo com a Wikipedia, "um tee é o acessório mais comum (conectando parte de um oleoduto, aprox. Translator) usado para combinar [ou dividir] um fluxo de fluido (neste caso, queremos dizer fluxos, fluxo - fluxo / fluxo / fluxo, tradutor de comentários)".
Outros nomes foram sugeridos: dividir (dividir em 2 partes), duplexar, bifurcar (dividir), replicador, fanout (dividir), tocar, descompactar, collectionToBothAndThen, biCollecting, expandindo (extension), bifurcação, etc.
Todas as alternativas classificadas pelos desenvolvedores do Core podem ser encontradas aqui .
Exemplos de uso
Eu compilei três exemplos de uso de código com diferentes níveis de complexidade.
Lista de convidados
Extraímos dois tipos diferentes de informações da lista de objetos no fluxo. Cada hóspede deve aceitar o convite e pode liderar a família. Queremos saber
quem confirmou a reserva e o
número total de participantes (incluindo convidados e familiares).
var result = Stream.of(
Convidado class Guest { private String name; private boolean participating; private Integer participantsNumber; public Guest(String name, boolean participating, Integer participantsNumber) { this.name = name; this.participating = participating; this.participantsNumber = participantsNumber; } public boolean isParticipating() { return participating; } public Integer getParticipantsNumber() { return participantsNumber; } }
Participação em eventos class EventParticipation { private List<String> guestNameList; private Integer totalNumberOfParticipants; public EventParticipation(List<String> guestNameList, Integer totalNumberOfParticipants) { this.guestNameList = guestNameList; this.totalNumberOfParticipants = totalNumberOfParticipants; } @Override public String toString() { return "EventParticipation { " + "guests = " + guestNameList + ", total number of participants = " + totalNumberOfParticipants + " }"; }}
Filtrar nomes em duas listas diferentes
Neste exemplo, dividimos o fluxo de nomes em duas listas de acordo com o filtro.
var result = Stream.of("Devoxx", "Voxxed Days", "Code One", "Basel One", "Angular Connect") .collect(Collectors.teeing(
Contar e adicionar um fluxo de números
Você pode ter visto um exemplo semelhante aparecendo em blogs que combinam soma e contagem para obter a média. Este exemplo não requer
Teeing
e você pode simplesmente usar o
AverageInt
e um coletor simples.
O exemplo a seguir usa funções de
Teeing
para retornar dois valores:
var result = Stream.of(5, 12, 19, 21) .collect(Collectors.teeing(
Resultado class Result { private Long count; private Integer sum; public Result(Long count, Integer sum) { this.count = count; this.sum = sum; } @Override public String toString() { return "{" + "count=" + count + ", sum=" + sum + '}'; }}
Possível armadilha
Map.Entry
Muitos exemplos usam o
Map.Entry
para armazenar o resultado de uma
BiFunction
. Por favor, não faça isso porque você não pode armazenar o último argumento no
Map
. Não há nenhum objeto padrão no Java Core para armazenar dois valores - você precisará criá-lo.
Tudo sobre os novos recursos do Java 12
Você pode encontrar mais informações e fatos interessantes sobre o Java 12 nesta
apresentação .
Colecionáveis de sucesso!