Determinar se todos os elementos são iguais em uma lista Java

Determinar se todos os elementos são iguais em uma lista Java

1. Visão geral

Neste tutorial rápido, descobriremos como determinar se todos os elementos em aList são iguais.

Também veremos a complexidade de tempo de cada solução usando a notação Big O, dando-nos o pior cenário.

2. Exemplo

Vamos supor que temos as três listas a seguir:

notAllEqualList = Arrays.asList("Jack", "James", "Sam", "James");
emptyList = Arrays.asList();
allEqualList = Arrays.asList("Jack", "Jack", "Jack", "Jack");

Nossa tarefa é propor diferentes soluções que retornemtrue apenas paraemptyListeallEqualList.

3. Loop básico

Primeiro, é verdade que para todos os elementos serem iguais, todos eles têm que ser iguais ao primeiro elemento. Vamos aproveitar isso em um loop:

public boolean verifyAllEqualUsingALoop(List list) {
    for (String s : list) {
        if (!s.equals(list.get(0)))
            return false;
    }
    return true;
}

Isso é bom porque, embora a complexidade do tempo sejaO(n), muitas vezes pode sair mais cedo.

4. HashSet

Também podemos usar umHashSet uma vez que todos os seus elementos são distintos. If we convert a List to a HashSet and the resulting size is less than or equal to 1, then we know that all elements in the list are equal:

public boolean verifyAllEqualUsingHashSet(List list) {
    return new HashSet(list).size() <= 1;
}

Convertendo um tempoList to HashSet costs O(n) enquantocalling size takes O(1). Assim, ainda temos uma complexidade de tempo total deO(n).

5. APICollections

Outra solução é usar o métodofrequency(Collection c, Object o) doCollections API. This method returns the number of elements in a Collection c matching an Object o.

Portanto, se o resultado da frequência for igual ao tamanho da lista, sabemos que todos os elementos são iguais:

public boolean verifyAllEqualUsingFrequency(List list) {
    return list.isEmpty() || Collections.frequency(list, list.get(0)) == list.size();
}

Semelhante às soluções anteriores, a complexidade do tempo éO(n), pois internamente,Collections.frequency() usa loop básico.

6. Streams

OStream API in Java 8 nos dá ainda mais maneiras alternativas de detectar se todos os itens em uma lista são iguais.

6.1. distinct()

Vejamos uma solução particular que usa o métododistinct() .

Para verificar se todos os elementos de uma lista são iguais,we count the distinct elements of its stream:

public boolean verifyAllEqualUsingStream(List list) {
    return list.stream()
      .distinct()
      .count() <= 1;
}

Se a contagem desse fluxo for menor ou igual a 1, todos os elementos são iguais e retornamostrue.

O custo total da operação éO(n),, que é o tempo gasto para percorrer todos os elementos do fluxo.

6.2. allMatch()

O métodoallMatch() da APIStream fornece uma solução perfeita para determinar se todos os elementos deste fluxo correspondem ao predicado fornecido:

public boolean verifyAllEqualAnotherUsingStream(List list) {
    return list.isEmpty() || list.stream()
      .allMatch(list.get(0)::equals);
}

Semelhante ao exemplo anterior usando fluxos, este tem uma complexidade de tempo deO(n), que é o tempo para percorrer todo o fluxo.

7. Bibliotecas de terceiros

Se estivermos presos em uma versão anterior do Java e não pudermos usar a API Stream,we can make use of third-party libraries such as Google Guava and Apache Commons.

Aqui, temos duas soluções muito semelhantes, iterando uma lista de elementos e combinando-a com o primeiro elemento. Assim, podemos calcular facilmente a complexidade do tempo emO(n).

7.1. Dependências do Maven

Para usar qualquer um deles, podemos adicionarguava oucommons-collections4, respectivamente, ao nosso projeto:


    com.google.guava
    guava
    23.0

    org.apache.commons
    commons-collections4
    4.1

7.2. Google Guava

In Google Guava, the static method Iterables.all() retornatrue se todos os elementos da lista satisfizerem o predicado:

public boolean verifyAllEqualUsingGuava(List list) {
    return Iterables.all(list, new Predicate() {
        public boolean apply(String s) {
            return s.equals(list.get(0));
        }
    });
}

7.3. Apache Commons

Da mesma forma, a bibliotecaApache Commons também fornece uma classe de utilitárioIterableUtils com um conjunto de métodos de utilitário estáticos para operar em instâncias deIterable.

Em particular, o método estáticoIterableUtils.matchesAll() retornatrue se todos os elementos da lista satisfizerem o predicado:

public boolean verifyAllEqualUsingApacheCommon(List list) {
    return IterableUtils.matchesAll(list, new org.apache.commons.collections4.Predicate() {
        public boolean evaluate(String s) {
            return s.equals(list.get(0));
        }
    });
}

8. Conclusão

Neste artigo, aprendemos diferentes maneiras de verificar se todos os elementos emList são iguais, começando com a funcionalidade Java simples e, em seguida, mostrando maneiras alternativas usando a APIStream e as bibliotecas de terceirosGoogle Guava eApache Commons.

Também aprendemos que cada uma das soluções nos dá a mesma complexidade de tempo deO(n). No entanto, cabe a nós escolher o melhor de acordo com como e onde será usado.

E certifique-se de verificar o conjunto completo de amostrasover on GitHub.