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.