Questão nº 69
Questão de Tecnologia da Informação · FGV DATAPREV 2024 (nº 69)
Considere o seguinte trecho de código:
List<Integer> numeros = Arrays.asList(1, 2, 3, 4, 5);
Iterator<Integer> iterador = numeros.iterator();
while(iterador.hasNext()) {
for(int i = 0; i < numeros.size(); i++) {
if(i % 2 == 0) {
iterador.remove(i);
}
}
}
Esse código tem por objetivo remover as posições pares de uma lista "números".
Assinale a opção que identifica os problemas com esse código.
- AA remoção de elementos dentro de um laço for deve ser feita usando os métodos next() e remove() do iterador. (alternativa correta)
- BO laço for está mal posicionado, e deveria ser usado antes do laço while para iterar corretamente.
- CO método remove nunca pode ser chamado durante a iteração com um iterador, pois isso sempre resulta em uma exceção.
- DA variável i utilizada no laço for está causando um erro de indexação ao tentar acessar elementos que já foram removidos.
- EO laço while deve ser substituído por um laço for para evitar conflitos com o iterador.
Resposta comentada
Gabarito Alternativa A
Para remover elementos de uma coleção em Java de forma segura enquanto se itera sobre ela, é essencial usar o Iterator da coleção. O Iterator permite percorrer os elementos e, mais importante, removê-los sem causar problemas como a ConcurrentModificationException (exceção de modificação concorrente), que ocorreria se você tentasse modificar a coleção diretamente (por exemplo, usando list.remove(index)) enquanto um Iterator está ativo.
-
(A) Correta: A remoção de elementos usando um
Iteratordeve seguir um padrão específico: primeiro, você chamaiterador.next()para obter o próximo elemento e avançar a posição do iterador. Em seguida, você pode chamariterador.remove()para remover o último elemento retornado pornext(). O métodoiterador.remove()não aceita argumentos (como um índicei). No código fornecido,iterador.remove(i)é um erro de compilação, pois o métodoremove()deIteratornão recebe parâmetros. Além disso, mesmo que fosseiterador.remove(), ele não foi precedido por uma chamada aiterador.next()dentro doforinterno, o que também seria um uso incorreto. A alternativa descreve o método correto, indicando que o código atual está errado. -
(B) Incorreta: O laço
forinterno está de fato mal posicionado e conceitualmente errado para a tarefa, mas a sugestão de movê-lo antes dowhilenão resolve o problema fundamental de como a remoção deve ser feita com um iterador. A lógica de iterar por índice (for(int i = 0; i < numeros.size(); i++)) é incompatível com a iteração porIteratorpara remoção segura. -
(C) Incorreta: Esta afirmação é falsa. O método
Iterator.remove()foi especificamente projetado para ser chamado durante a iteração para remover o elemento atual de forma segura, sem lançarConcurrentModificationException. O problema no código não é queremove()não pode ser chamado, mas sim que está sendo chamado de forma incorreta (com um argumento e semnext()prévio). -
(D) Incorreta: Embora a variável
iseja um índice e a remoção de elementos altere os índices subsequentes (o que causariaIndexOutOfBoundsExceptionse fossenumeros.remove(i)), o código chamaiterador.remove(i). Como explicado na alternativa A, o métodoIterator.remove()não aceita um índice como argumento. Portanto, o problema principal não é um erro de indexação no sentido de acessar uma posição inválida, mas sim um erro de assinatura do método e de uso conceitual doIterator. A armadilha aqui é que o aluno pode se focar nos efeitos de remover por índice em uma lista (ConcurrentModificationExceptionouIndexOutOfBoundsException), mas o código não está removendo por índice da lista, e sim tentando usar oIterator.remove()de forma errada. -
(E) Incorreta: Substituir um laço
whilepor umfor(ou umfor-each) não resolve o problema fundamental de como a remoção é feita. Umfor-eachloop (laçoforaprimorado) não permite a remoção direta de elementos da coleção que está sendo iterada; tentar fazer isso resultaria emConcurrentModificationException. A forma correta de remover elementos durante a iteração é sempre através doIterator.remove().
Fonte: FGV DATAPREV 2024 Analista de Tecnologia da Informação - Arquitetura, Engenharia e Sustentação Tecnológica (Caderno Tipo 1). Reproduzida para fins de estudo.