Novo stream, comparador e coletor na goiaba 21

Novo stream, comparador e coletor na goiaba 21

1. Introdução

Este artigo é o primeiro da série sobre os novos recursos lançados com a versão 21 da biblioteca do Google Guava. Discutiremos as classes recém-adicionadas e algumas mudanças importantes em relação às versões anteriores do Guava.

Mais especificamente, discutiremos adições e mudanças no pacotecommon.collect.

Guava 21 introduz algumas funcionalidades novas e úteis no pacotecommon.collect; vamos dar uma olhada rápida em alguns desses novos utilitários e como podemos aproveitá-los ao máximo.

2. Streams

Estamos todos entusiasmados com a última adição dejava.util.stream.Stream no Java 8. Bem, o Guava agora está fazendo bom uso de fluxos e fornece o que a Oracle pode ter perdido.

Streams é uma classe de utilitário estático, com alguns utilitários muito necessários para lidar com fluxos Java 8.

2.1. Streams.stream()

A classeStreams fornece quatro maneiras de criar fluxos usandoIterable,Iterator,OptionaleCollection.

Porém, a criação de stream usandoCollection está obsoleta, pois é fornecida pelo Java 8 pronto para uso:

List numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Stream streamFromCollection = Streams.stream(numbers);
Stream streamFromIterator = Streams.stream(numbers.iterator());
Stream streamFromIterable = Streams.stream((Iterable) numbers);
Stream streamFromOptional = Streams.stream(Optional.of(1));

A classeStreams também fornece sabores comOptionalDouble,OptionalLong eOptionalInt. Esses métodos retornam um fluxo contendo apenas esse elemento, caso contrário, o fluxo vazio:

LongStream streamFromOptionalLong = Streams.stream(OptionalLong.of(1));
IntStream streamFromOptionalInt = Streams.stream(OptionalInt.of(1));
DoubleStream streamFromOptionalDouble = Streams.stream(OptionalDouble.of(1.0));

2.2. Streams.concat()

A classeStreams fornece métodos para conciliar mais de um fluxo homogêneo.

Stream concatenatedStreams = Streams.concat(streamFromCollection, streamFromIterable,streamFromIterator);

A funcionalidadeconcat vem em alguns sabores -LongStream,IntStreameDoubleStream.

2.3. Streams.findLast()

Streams tem um método utilitário para encontrar o último elemento no fluxo usando o métodofindLast().

Este método retorna o último elemento ouOptional.empty() se o fluxo não houver elementos no fluxo:

List integers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Optional lastItem = Streams.findLast(integers.stream());

O métodofindLast() funciona paraLongStream,IntStreameDoubleStream.

2.4. Streams.mapWithIndex()

Usando o métodomapWithIndex(), cada elemento do fluxo carrega informações sobre sua respectiva posição (índice):

mapWithIndex( Stream.of("a", "b", "c"), (str, index) -> str + ":" + index)

Isso retornaráStream.of(“a:0″,”b:1″,”c:2”).

O mesmo pode ser obtido comIntStream,LongStreameDoubleStream usandomapWithIndex() sobrecarregado.

2.5. Streams.zip()

Para mapear os elementos correspondentes de dois fluxos usando alguma função, basta usar o método zip deStreams:

Streams.zip(
  Stream.of("candy", "chocolate", "bar"),
  Stream.of("$1", "$2","$3"),
  (arg1, arg2) -> arg1 + ":" + arg2
);

Isso retornaráStream.of(“candy:$1″,”chocolate:$2″,”bar:$3”);

O fluxo resultante será apenas o menor dos dois fluxos de entrada; se um fluxo for mais longo, seu elemento extra será ignorado.

3. Comparators

A classe GuavaOrdering está obsoleta e na fase de exclusão nas versões mais recentes. A maioria das funcionalidades da classeOrdering já está incluída no JDK 8.

O Guava apresentaComparators para fornecer recursos adicionais deOrdering que ainda não são fornecidos pelas bibliotecas padrão Java 8.

Vamos dar uma olhada rápida nisso.

3.1. Comparators.isInOrder()

Este método retorna verdadeiro se cada elemento no Iterable for maior ou igual ao anterior, conforme especificado porComparator:

List integers = Arrays.asList(1,2,3,4,4,6,7,8,9,10);
boolean isInAscendingOrder = Comparators.isInOrder(
  integers, new AscedingOrderComparator());

3.2. Comparators.isInStrictOrder()

Muito semelhante ao métodoisInOrder(), mas mantém estritamente a condição, o elemento não pode ser igual ao anterior, deve ser maior que. O código anterior retornará false para este método.

3.3. Comparators.lexicographical()

Esta API retorna uma nova instânciaComparator - que classifica em ordem lexicográfica (dicionário) comparando os elementos correspondentes aos pares. Internamente, ele cria uma nova instância deLexicographicalOrdering<S>().

4. MoreCollectors

MoreCollectors contém algunsCollectors muito úteis que não estão presentes em Java 8java.util.stream.Collectors e não estão associados ao tipocom.google.common.

Vamos revisar alguns deles.

4.1. MoreCollectors.toOptional()

Aqui,Collector converte um fluxo contendo zero ou um elemento em umOptional:

List numbers = Arrays.asList(1);
Optional number = numbers.stream()
  .map(e -> e * 2)
  .collect(MoreCollectors.toOptional());

Se o fluxo contém mais de um elemento - o coletor lançaráIllegalArgumentException.

4.2. MoreCollectors.onlyElement()

Com esta API, oCollector pega um fluxo contendo apenas um elemento e retorna o elemento; se o fluxo contém mais de um elemento, ele lançaIllegalArgumentException ou se o fluxo contém zero elemento, ele lançaNoSuchElementException.

5. Interners.InternerBuilder

Esta é uma classe de construtor interna paraInterners já existente na biblioteca Guava. Ele fornece algum método útil para definir o nível de simultaneidade e o tipo (fraco ou forte) deInterner que você prefere:

Interners interners = Interners.newBuilder()
  .concurrencyLevel(2)
  .weak()
  .build();

6. Conclusão

Neste artigo rápido, exploramos a funcionalidade recém-adicionada emcommon.collect package do Guava 21.

O código deste artigo pode ser encontradoon Github, como sempre.