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