Introdução
Neste laboratório, você aprenderá como verificar se uma lista contém todos os elementos de outra lista em Java. Esta é uma tarefa fundamental ao trabalhar com coleções e entender as relações entre conjuntos de dados.
Exploraremos o método containsAll() eficiente fornecido pelo framework Java Collections para uma verificação rápida de subconjunto. Para solidificar sua compreensão, você também aprenderá como realizar essa verificação manualmente usando um loop. Finalmente, testaremos o comportamento desses métodos com casos extremos, incluindo listas vazias e nulas, para garantir um código robusto.
Usar containsAll() para Verificação de Subconjunto
Nesta etapa, exploraremos como verificar se uma lista é um subconjunto de outra usando o método containsAll() em Java. Esta é uma tarefa comum ao trabalhar com coleções, e containsAll() fornece uma maneira conveniente de realizar essa verificação.
Primeiro, vamos criar um novo arquivo Java chamado SubsetCheck.java em seu diretório ~/project. Você pode fazer isso usando o explorador de arquivos WebIDE à esquerda. Clique com o botão direito na área ~/project, selecione "Novo Arquivo" e digite SubsetCheck.java.
Agora, abra o arquivo SubsetCheck.java no editor e adicione o seguinte código:
import java.util.ArrayList;
import java.util.List;
public class SubsetCheck {
public static void main(String[] args) {
// Create the main list
List<String> mainList = new ArrayList<>();
mainList.add("Apple");
mainList.add("Banana");
mainList.add("Cherry");
mainList.add("Date");
// Create a potential subset list
List<String> subList = new ArrayList<>();
subList.add("Banana");
subList.add("Cherry");
// Check if subList is a subset of mainList using containsAll()
boolean isSubset = mainList.containsAll(subList);
// Print the result
System.out.println("Main List: " + mainList);
System.out.println("Sub List: " + subList);
System.out.println("Is subList a subset of mainList? " + isSubset);
// Create another list that is not a subset
List<String> anotherList = new ArrayList<>();
anotherList.add("Banana");
anotherList.add("Grape"); // Grape is not in mainList
// Check if anotherList is a subset of mainList
boolean isAnotherSubset = mainList.containsAll(anotherList);
// Print the result for the second check
System.out.println("\nAnother List: " + anotherList);
System.out.println("Is anotherList a subset of mainList? " + isAnotherSubset);
}
}
Vamos detalhar o código:
- Importamos
ArrayListeListdo pacotejava.utilpara trabalhar com listas. - Criamos dois objetos
ArrayList:mainListesubList. - Adicionamos alguns elementos de string a ambas as listas.
- A parte chave é
mainList.containsAll(subList). Este método verifica semainListcontém todos os elementos presentes emsubList. Ele retornatruese contiver, efalsecaso contrário. - Armazenamos o resultado em uma variável booleana
isSubsete o imprimimos. - Em seguida, criamos
anotherListque contém um elemento não presente emmainListe realizamos a mesma verificação para ver o resultado quando não é um subconjunto.
Salve o arquivo SubsetCheck.java (Ctrl+S ou Cmd+S).
Agora, abra o Terminal na parte inferior do WebIDE. Certifique-se de estar no diretório ~/project. Caso contrário, use o comando cd ~/project.
Compile o código Java usando o comando javac:
javac SubsetCheck.java
Se não houver erros de compilação, você deverá ver um arquivo SubsetCheck.class criado no diretório ~/project.
Finalmente, execute o programa Java compilado usando o comando java:
java SubsetCheck
Você deverá ver uma saída semelhante a esta:
Main List: [Apple, Banana, Cherry, Date]
Sub List: [Banana, Cherry]
Is subList a subset of mainList? true
Another List: [Banana, Grape]
Is anotherList a subset of mainList? false
Esta saída confirma que subList é de fato um subconjunto de mainList porque todos os seus elementos estão presentes em mainList, enquanto anotherList não é um subconjunto porque "Grape" não está em mainList.
Verificar com Loop Manual
Na etapa anterior, usamos o método containsAll() conveniente para verificar um subconjunto. Embora containsAll() seja eficiente, é útil entender como você realizaria essa verificação manualmente usando um loop. Isso aprofundará sua compreensão de como os métodos de coleção podem funcionar internamente.
Vamos adicionar um novo método ao nosso arquivo SubsetCheck.java para realizar a verificação de subconjunto manualmente. Abra ~/project/SubsetCheck.java no editor WebIDE.
Adicione o seguinte método dentro da classe SubsetCheck, mas fora do método main:
// Method to manually check if subList is a subset of mainList
public static boolean isSubsetManual(List<String> mainList, List<String> subList) {
// Iterate through each element in the subList
for (String element : subList) {
// If the mainList does NOT contain the current element from subList,
// then subList is not a subset, and we can return false immediately.
if (!mainList.contains(element)) {
return false;
}
}
// If we have checked all elements in subList and found them all in mainList,
// then subList is a subset.
return true;
}
Este novo método isSubsetManual recebe duas listas como entrada. Em seguida, ele percorre cada element em subList. Dentro do loop, ele verifica se mainList contém o element atual usando o método contains(). Se encontrar até mesmo um elemento em subList que não está em mainList, ele sabe imediatamente que subList não é um subconjunto e retorna false. Se o loop terminar sem encontrar nenhum elemento em subList que esteja faltando em mainList, significa que todos os elementos estão presentes, e o método retorna true.
Agora, vamos chamar este novo método de nosso método main para comparar seu resultado com containsAll(). Modifique o método main em SubsetCheck.java para incluir chamadas para isSubsetManual:
import java.util.ArrayList;
import java.util.List;
public class SubsetCheck {
public static void main(String[] args) {
// Create the main list
List<String> mainList = new ArrayList<>();
mainList.add("Apple");
mainList.add("Banana");
mainList.add("Cherry");
mainList.add("Date");
// Create a potential subset list
List<String> subList = new ArrayList<>();
subList.add("Banana");
subList.add("Cherry");
// Check if subList is a subset of mainList using containsAll()
boolean isSubsetContainsAll = mainList.containsAll(subList);
// Check if subList is a subset of mainList using manual loop
boolean isSubsetManualCheck = isSubsetManual(mainList, subList);
// Print the result
System.out.println("Main List: " + mainList);
System.out.println("Sub List: " + subList);
System.out.println("Is subList a subset of mainList (containsAll)? " + isSubsetContainsAll);
System.out.println("Is subList a subset of mainList (manual check)? " + isSubsetManualCheck);
// Create another list that is not a subset
List<String> anotherList = new ArrayList<>();
anotherList.add("Banana");
anotherList.add("Grape"); // Grape is not in mainList
// Check if anotherList is a subset of mainList using containsAll()
boolean isAnotherSubsetContainsAll = mainList.containsAll(anotherList);
// Check if anotherList is a subset of mainList using manual loop
boolean isAnotherSubsetManualCheck = isSubsetManual(mainList, anotherList);
// Print the result for the second check
System.out.println("\nAnother List: " + anotherList);
System.out.println("Is anotherList a subset of mainList (containsAll)? " + isAnotherSubsetContainsAll);
System.out.println("Is anotherList a subset of mainList (manual check)? " + isAnotherSubsetManualCheck);
}
// Method to manually check if subList is a subset of mainList
public static boolean isSubsetManual(List<String> mainList, List<String> subList) {
// Iterate through each element in the subList
for (String element : subList) {
// If the mainList does NOT contain the current element from subList,
// then subList is not a subset, and we can return false immediately.
if (!mainList.contains(element)) {
return false;
}
}
// If we have checked all elements in subList and found them all in mainList,
// then subList is a subset.
return true;
}
}
Salve o arquivo SubsetCheck.java modificado.
Agora, compile o código atualizado no Terminal:
javac SubsetCheck.java
E execute o programa novamente:
java SubsetCheck
Você deverá ver uma saída semelhante a esta, mostrando que tanto o método containsAll() quanto nosso método de loop manual produzem os mesmos resultados:
Main List: [Apple, Banana, Cherry, Date]
Sub List: [Banana, Cherry]
Is subList a subset of mainList (containsAll)? true
Is subList a subset of mainList (manual check)? true
Another List: [Banana, Grape]
Is anotherList a subset of mainList (containsAll)? false
Is anotherList a subset of mainList (manual check)? false
Esta etapa demonstra que você pode obter o mesmo resultado que containsAll() iterando pelo potencial subconjunto e verificando a presença de cada elemento na lista principal. Embora containsAll() seja geralmente preferido por sua concisão e possíveis otimizações de desempenho na biblioteca Java, a compreensão da abordagem manual é valiosa para o aprendizado.
Testar com Listas Vazias e Nulas
Nesta etapa, exploraremos como o método containsAll() e nosso método de verificação manual se comportam ao lidar com listas vazias e valores null. Entender esses casos extremos é importante para escrever um código robusto.
Abra o arquivo ~/project/SubsetCheck.java no editor WebIDE. Adicionaremos mais casos de teste ao método main.
Modifique o método main para incluir verificações com listas vazias e uma lista null:
import java.util.ArrayList;
import java.util.List;
public class SubsetCheck {
public static void main(String[] args) {
// Create the main list
List<String> mainList = new ArrayList<>();
mainList.add("Apple");
mainList.add("Banana");
mainList.add("Cherry");
mainList.add("Date");
// Create a potential subset list
List<String> subList = new ArrayList<>();
subList.add("Banana");
subList.add("Cherry");
// Check if subList is a subset of mainList using containsAll()
boolean isSubsetContainsAll = mainList.containsAll(subList);
// Check if subList is a subset of mainList using manual loop
boolean isSubsetManualCheck = isSubsetManual(mainList, subList);
// Print the result
System.out.println("Main List: " + mainList);
System.out.println("Sub List: " + subList);
System.out.println("Is subList a subset of mainList (containsAll)? " + isSubsetContainsAll);
System.out.println("Is subList a subset of mainList (manual check)? " + isSubsetManualCheck);
// Create another list that is not a subset
List<String> anotherList = new ArrayList<>();
anotherList.add("Banana");
anotherList.add("Grape"); // Grape is not in mainList
// Check if anotherList is a subset of mainList using containsAll()
boolean isAnotherSubsetContainsAll = mainList.containsAll(anotherList);
// Check if anotherList is a subset of mainList using manual loop
boolean isAnotherSubsetManualCheck = isSubsetManual(mainList, anotherList);
// Print the result for the second check
System.out.println("\nAnother List: " + anotherList);
System.out.println("Is anotherList a subset of mainList (containsAll)? " + isAnotherSubsetContainsAll);
System.out.println("Is anotherList a subset of mainList (manual check)? " + isAnotherSubsetManualCheck);
// --- Test with Empty Lists ---
// Create an empty list
List<String> emptyList = new ArrayList<>();
// Check if emptyList is a subset of mainList
boolean isEmptySubsetContainsAll = mainList.containsAll(emptyList);
boolean isEmptySubsetManualCheck = isSubsetManual(mainList, emptyList);
System.out.println("\nEmpty List: " + emptyList);
System.out.println("Is emptyList a subset of mainList (containsAll)? " + isEmptySubsetContainsAll);
System.out.println("Is emptyList a subset of mainList (manual check)? " + isEmptySubsetManualCheck);
// Check if mainList is a subset of emptyList (should be false unless mainList is also empty)
boolean isMainSubsetEmptyContainsAll = emptyList.containsAll(mainList);
boolean isMainSubsetEmptyManualCheck = isSubsetManual(emptyList, mainList);
System.out.println("Is mainList a subset of emptyList (containsAll)? " + isMainSubsetEmptyContainsAll);
System.out.println("Is mainList a subset of emptyList (manual check)? " + isMainSubsetEmptyManualCheck);
// --- Test with Null List ---
// Create a null list
List<String> nullList = null;
// Check with nullList using containsAll()
System.out.println("\nNull List: " + nullList);
try {
boolean isNullSubsetContainsAll = mainList.containsAll(nullList);
System.out.println("Is nullList a subset of mainList (containsAll)? " + isNullSubsetContainsAll);
} catch (NullPointerException e) {
System.out.println("Checking with nullList using containsAll() resulted in: " + e);
}
// Check with nullList using manual loop
try {
boolean isNullSubsetManualCheck = isSubsetManual(mainList, nullList);
System.out.println("Is nullList a subset of mainList (manual check)? " + isNullSubsetManualCheck);
} catch (NullPointerException e) {
System.out.println("Checking with nullList using manual check resulted in: " + e);
}
}
// Method to manually check if subList is a subset of mainList
public static boolean isSubsetManual(List<String> mainList, List<String> subList) {
// Add a check for null subList in the manual method
if (subList == null) {
throw new NullPointerException("Sub list cannot be null for manual check.");
}
// Iterate through each element in the subList
for (String element : subList) {
// If the mainList does NOT contain the current element from subList,
// then subList is not a subset, and we can return false immediately.
if (!mainList.contains(element)) {
return false;
}
}
// If we have checked all elements in subList and found them all in mainList,
// then subList is a subset.
return true;
}
}
Adicionamos seções para testar com uma emptyList e uma nullList. Observe que, para os testes nullList, envolvemos as chamadas em blocos try-catch. Isso ocorre porque tentar chamar métodos em um objeto null (como mainList.containsAll(nullList)) resultará em uma NullPointerException. Nosso método manual também precisa lidar com o caso em que subList é null, então adicionamos uma verificação no início de isSubsetManual.
Salve o arquivo SubsetCheck.java modificado.
Compile o código atualizado no Terminal:
javac SubsetCheck.java
E execute o programa novamente:
java SubsetCheck
Você deverá ver uma saída semelhante a esta:
Main List: [Apple, Banana, Cherry, Date]
Sub List: [Banana, Cherry]
Is subList a subset of mainList (containsAll)? true
Is subList a subset of mainList (manual check)? true
Another List: [Banana, Grape]
Is anotherList a subset of mainList (containsAll)? false
Is anotherList a subset of mainList (manual check)? false
Empty List: []
Is emptyList a subset of mainList (containsAll)? true
Is emptyList a subset of mainList (manual check)? true
Is mainList a subset of emptyList (containsAll)? false
Is mainList a subset of emptyList (manual check)? false
Null List: null
Checking with nullList using containsAll() resulted in: java.lang.NullPointerException
Checking with nullList using manual check resulted in: java.lang.NullPointerException: Sub list cannot be null for manual check.
Na saída, observe o seguinte:
- Uma lista vazia é considerada um subconjunto de qualquer lista (incluindo outra lista vazia). Tanto
containsAll()quanto nosso método manual identificam isso corretamente. - Uma lista não vazia não é um subconjunto de uma lista vazia.
- Passar uma lista
nullparacontainsAll()ou nosso método manual (sem uma verificação nula) resulta em umaNullPointerException. Isso destaca a importância de lidar com valoresnullpotenciais em seu código.
Esta etapa conclui nossa exploração da verificação de subconjuntos em listas Java. Você aprendeu como usar o método containsAll() integrado, como realizar a verificação manualmente e como esses métodos se comportam com listas vazias e nulas.
Resumo
Neste laboratório, aprendemos como verificar se uma lista contém todos os elementos de outra lista em Java. Nos concentramos principalmente no uso do método containsAll() conveniente fornecido pela interface Collection.
Demonstramos como usar containsAll() com listas de exemplo e observamos seu comportamento para casos de subconjunto e não subconjunto. Este método oferece uma maneira concisa e eficiente de realizar esta tarefa comum de comparação de listas.



