Primeiramente, em vez do método getItens
ficar toda hora verificando se a lista é nula, é melhor inicializar a lista no construtor:
public class CarrinhoCompras {
private List<Item> listaDeItens;
// adicione um construtor na classe
public CarrinhoCompras() {
// inicializa a lista
listaDeItens = new ArrayList<>();
}
// assim, o getter não precisa mais verificar se a lista é null
public Collection<Item> getItens() {
return listaDeItens;
}
}
Remover
Não precisa complicar, você pode remover apenas assim:
public boolean removerItem(Produto produto) {
Iterator<Item> it = listaDeItens.iterator();
while (it.hasNext()) {
Produto p = it.next().getProduto();
if (p.equals(produto)) {
it.remove();
return true; // se já removeu, pode retornar (nem precisa olhar o resto)
}
}
// se chegou aqui é porque não entrou no if acima, ou seja, o produto não existe na lista de itens
return false;
}
public boolean removerItem(int posicaoItem) {
// garantir que a posição existe
if (posicaoItem < 0 || posicaoItem >= listaDeItens.size()) {
return false;
}
listaDeItens.remove(posicaoItem);
return true;
}
Testando:
// cria produtos, etc (igual ao exemplo anterior)
// ...
CarrinhoComprasFactory cf = new CarrinhoComprasFactory();
CarrinhoCompras c = cf.criar("Ricardo");
c.adicionarItem(p, v, 2);
c.adicionarItem(p1, v1, 3);
c.adicionarItem(p2, v2, 1);
System.out.println(c.getItens().size() + " itens no carrinho antes de remover p1: \n");
System.out.println(c.getItens());
System.out.println("--------------------");
if (c.removerItem(1)) {
System.out.println(c.getItens().size() + " itens no carrinho depois de remover p1: \n");
System.out.println(c.getItens());
} else {
System.out.printf("Produto %d (%s) não foi removido porque não estava no carrinho \n", p1.getCodigo(), p1.getDescricao());
}
Saída:
3 itens no carrinho antes de remover p1:
[Item [Produto=Produto [descricao=Leite], Valor Unitario=4.12, Valor=null, Quantidade=2]
, Item [Produto=Produto [descricao=Carne], Valor Unitario=8.24, Valor=null, Quantidade=3]
, Item [Produto=Produto [descricao=Pão], Valor Unitario=1.14, Valor=null, Quantidade=1]
]
--------------------
2 itens no carrinho depois de remover p1:
[Item [Produto=Produto [descricao=Leite], Valor Unitario=4.12, Valor=null, Quantidade=2]
, Item [Produto=Produto [descricao=Pão], Valor Unitario=1.14, Valor=null, Quantidade=1]
]
Criar carrinho
Já o método que cria o carrinho, veja a descrição:
Ou seja, não é para retornar null
. Se um carrinho já existe, então você retorna o que já existe. E se não existe, cria um novo. Assim:
public CarrinhoCompras criar(String identificacaoCliente) {
CarrinhoCompras carrinhoCompras;
if (this.carrinhosDeCompras.containsKey(identificacaoCliente)) {
// se já existe, pega do Map
carrinhoCompras = this.carrinhosDeCompras.get(identificacaoCliente);
} else {
// se não existe, cria um novo e coloca no Map
carrinhoCompras = new CarrinhoCompras();
carrinhosDeCompras.put(identificacaoCliente, carrinhoCompras);
}
return carrinhoCompras;
}
Testando (esse código entra no if
corretamente):
CarrinhoCompras c = cf.criar("Alexandre");
CarrinhoCompras c1 = cf.criar("Isabela");
// criando novo carrinho com mesma identificação
CarrinhoCompras c2 = cf.criar("Alexandre");
if (c.equals(c2)) {
System.out.println("iguais"); // entra no if
} else {
System.out.println("Erro ao criar carrinho");
}
Outras coisas
Tem outras coisas estranhas. Por exemplo:
if (temp.getValorUnitario() == valorUnitario) {
valorUnitario = temp.getValorUnitario();
}
Se os valores são iguais, você faz com que eles sejam iguais. O que vc tentou fazer aqui? O que esse código faz basicamente é:
if (1 == x) {
x = 1;
}
Se x é igual a 1, então x passa a ser 1. Troque x
por valorUnitario
e 1
por temp.getValorUnitario
e veja que não faz sentido.
E em vez de if (!(posicaoDoItem < 0))
, por que não fazer if (posicaoDoItem >= 0)
?
Enfim, pelo que entendi, o método adicionarItem
tem que verificar se um item já existe. Caso exista, adiciona a quantidade e atualiza o valor unitário. Se não existir, adiciona. Sendo assim, dá para simplificar. Na classe Item
adicione um método para atulizar a quantidade e um setter para o valor unitário:
public class Item {
// adicione este método
public void adicionarQuantidade(int qtd) {
this.quantidade += qtd;
}
public void setValorUnitario(BigDecimal valorUnitario) {
this.valorUnitario = valorUnitario;
}
}
E no CarrinhoCompras
mude para:
public void adicionarItem(Produto produto, BigDecimal valorUnitario, int quantidade) {
boolean existe = false;
for (Item item : listaDeItens) {
if (item.getProduto().equals(produto)) {
existe = true;
item.setValorUnitario(valorUnitario);
item.adicionarQuantidade(quantidade);
break; // se já encontrei, não tem porque continuar o for, então posso interrompê-lo
}
}
// se não existe, tem que adicionar
if (!existe) {
listaDeItens.add(new Item(produto, valorUnitario, quantidade));
}
}
Então no teste eu fiz:
c.adicionarItem(p1, v1, 3);
c.adicionarItem(p1, v1, 3);
E no final a quantidade do produto é 6
(porque eu adicionei 3 e depois mais 3).
Outra coisa, por que Item
tem valorUnitario
e valor
? O valor
seria o que? Eu até achei que seria o valor total, mas como já tem o método getValorTotal
, então não sei para que serve esse valor
.