Duvida sobre excluir objeto

Estou aprendendo Collections e surgiu algumas dúvidas,

1 - Eu vi exemplo percorrendo a lista de objeto com Iterator, e usando o for tradicional, qual a diferença?
2 - Se eu tenho um método chamado remover removerPorDescricao(String nome), para conseguir remover elemento pela descrição do meu objeto, eu preciso criar o equals e hashCode?

Depende. Se vc só quer percorrer a lista, o for é mais direto:

for (TipoDoObjeto obj : lista) {
    // faz algo com obj
}

Um Iterator permite que se façam outras operações durante o loop. Por exemplo, remover elementos enquanto itera sobre a lista:

Iterator<TipoDoObjeto> it = lista.iterator();
while (it.hasNext()) {
    TipoDoObjeto obj = it.next();
    if (deveRemover(obj)) {
        it.remove();
    }
}

Se usarmos o for, não funciona:

for (TipoDoObjeto obj: lista) {
    if (deveRemover(obj)) {
        lista.remove(obj);
    }
}

O código acima dá erro: java.util.ConcurrentModificationException. Uma lista só pode ser modificada durante o loop se usarmos Iterator.


Quanto a necessidade de criar equals e hashCode, depende do que vc está fazendo. O primeiro serve para comparar duas instâncias e dizer se elas são iguais, o segundo é usado para quando o objeto é inserido em estruturas cujas implementações usam tabelas de hash (como HashMap, HashSet, etc - ver mais aqui).

O que acontece é que, para que tudo funcione corretamente, a recomendação é que estes dois métodos sejam implementados segundo certas regras. Mas se vc precisa ou não implementá-los, depende de como está usando a classe.

3 curtidas

Só um adendo: O Iterator não é a única opção, é possível remover elementos da lista usando um for “tradicional”, se começarmos do último índice até o primeiro, evitando o Exception, pois não se tenta acessar o elemento que já foi removido. Algo como:

List<String> lista = new ArrayList<String>();

lista.add("Um");
lista.add("Dois");
lista.add("Tres");
lista.add("Quatorze");

String itemARemover = "Tres";

int tamanho = lista.size();

for (int i = tamanho - 1; i >= 0; i--) {
  if (lista.get(i).equals(itemARemover)){
    lista.remove(i);
  }
}

Não sei quanta diferença faz em desempenho, mas é uma operação bem comum, e uma opção caso a linguagem não suporte algo similar à Iterators.

Rodando: 84FnG9 - Online Java Compiler & Debugging Tool - Ideone.com

Abraços.

1 curtida

Não precisa. Como a descrição é uma String, tudo o que vc precisa fazer é uma comparação simples de strings.

Eu fiz um exemplo:

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class Main {
  public static void main(String... args) {
    var carrinho = new CarrinhoDeCompras();

    carrinho.adicionarProduto(new Produto("xxx", "aaa"));
    carrinho.adicionarProduto(new Produto("yyy", "bbb"));
    carrinho.adicionarProduto(new Produto("zzz", "ccc"));

    carrinho.removerPorDescricao("aaa");

    carrinho.imprimirListaDeProdutos();
  }
}

class CarrinhoDeCompras {
  private final List<Produto> produtos = new ArrayList<>();

  void imprimirListaDeProdutos() {
    this.produtos.forEach(produto -> System.out.println(">>> " + produto.nome));
  }

  void adicionarProduto(Produto produto) {
    this.produtos.add(produto);
  }

  void removerPorDescricao(String descricao) {
    this.produtos.removeIf(produto -> Objects.equals(produto.descricao, descricao));
  }
}

class Produto {
  final String nome;
  final String descricao;

  Produto(String nome, String descricao) {
    this.nome = nome;
    this.descricao = descricao;
  }
}

As respostas dos colegas são válidas, por isso, no meu exemplo, usei mais uma forma de se fazer a remoção que é usando o método removeIf. Internamente o método removeIf usa um iterator para fazer a remoção.

3 curtidas

obrigado pela ajuda!

1 curtida