Como contar elementos duplicados na matriz

Como contar elementos duplicados na matriz

1. Visão geral

Neste breve tutorial, veremos algumas maneiras diferentes de contar os elementos duplicados em umArrayList.

2. Loop comMap.put()

Nosso resultado esperado seria um objetoMap, que contém todos os elementos da lista de entrada como chaves e a contagem de cada elemento como valor.

A solução mais direta para conseguir isso seria percorrer a lista de entrada e para cada elemento:

  • seresultMap contém o elemento, incrementamos um contador em 1

  • caso contrário, nósput uma nova entrada do mapa(element, 1) para o mapa

public  Map countByClassicalLoop(List inputList) {
    Map resultMap = new HashMap<>();
    for (T element : inputList) {
        if (resultMap.containsKey(element)) {
            resultMap.put(element, resultMap.get(element) + 1L);
        } else {
            resultMap.put(element, 1L);
        }
    }
    return resultMap;
}

This implementation has the best compatibility, comoit works for all modern Java versions.

A seguir, vamos criar uma lista de entrada para testar o método:

private List INPUT_LIST = Lists.list(
  "expect1",
  "expect2", "expect2",
  "expect3", "expect3", "expect3",
  "expect4", "expect4", "expect4", "expect4");

E agora vamos verificar:

private void verifyResult(Map resultMap) {
    assertThat(resultMap)
      .isNotEmpty().hasSize(4)
      .containsExactly(
        entry("expect1", 1L),
        entry("expect2", 2L),
        entry("expect3", 3L),
        entry("expect4", 4L));
}

Vamos reutilizar este equipamento de teste para o resto de nossas abordagens.

3. Loop comMap.compute()

A solução na seção anterior tem a melhor compatibilidade, no entanto, parece um pouco demorada.

Desde o JDK 8, o método útilhttps://docs.oracle.com/javase/8/docs/api/java/util/Map.html#compute-K-java.util.function.BiFunction- foi introduzido na interfaceMap. Podemos usar este método para simplificar a verificação decontainsKey():

public  Map countByClassicalLoopWithMapCompute(List inputList) {
    Map resultMap = new HashMap<>();
    for (T element : inputList) {
        resultMap.compute(element, (k, v) -> v == null ? 1 : v + 1);
    }
    return resultMap;
}

4. API StreamCollectors.toMap()

Como já falamos sobre o JDK 8, não vamos esquecer a poderosa API Stream. Graças à API Stream, podemos resolver o problema de uma maneira muito compacta.

O coletortoMap() nos ajuda a converter a lista de entrada em umMap:

public  Map countByStreamToMap(List inputList) {
    return inputList.stream().collect(Collectors.toMap(Function.identity(), v -> 1L, Long::sum));
}

OtoMap() é umconvenient collector, o que pode nos ajudar a transformar o fluxo em diferentes implementações deMap.

5. API de streamCollectors.groupingBy() eCollectors.counting()

Exceto paratoMap(), nosso problema pode ser resolvido por dois outros coletores,groupingBy()ecounting():

public  Map countByStreamGroupBy(List inputList) {
    return inputList.stream().collect(Collectors.groupingBy(k -> k, Collectors.counting()));
}

O uso adequado deJava 8 Collectors torna nossos códigos compactos e fáceis de ler.

6. Conclusão

Neste artigo rápido, ilustramos várias maneiras de calcular a contagem de elementos duplicados em uma lista.

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