Erro método com BigDecimal

28 respostas Resolvido
javaprogramação
R

Fala galera. Recentemente eu fiz um teste para uma empresa, uma vaga Java Backend e não fui aprovado. Alguns erros e outras coisas. Mas fiquei na dúvida com o que me foi respondido pelo examinador e gostaria de quem pudesse ajudar. Segue os códigos e depois minha dúvida:
CarrinhoCompras.java

package br.com.improving.carrinho;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class CarrinhoCompras {
	
	private List<Item> listaDeItens; 

  
    public void adicionarItem(Produto produto, BigDecimal valorUnitario, int quantidade) {

    	int posicaoDoItem = -1;
    	
    	for(int i = 0; i < getItens().size() & posicaoDoItem < 0; i++) {
    		
    		Item temp = listaDeItens.get(i);
    		
    		if(temp.getProduto().equals(produto)){
    			
    			posicaoDoItem = i;
    			
    		}    		
    	}
    	
    	try {	    	
    	    if(!(posicaoDoItem < 0)) {
    	    	
    	    	Item temp = listaDeItens.get(posicaoDoItem);
    	    	
    	    	quantidade = temp.getQuantidade() + quantidade;
    	    	
    	    	if (temp.getValorUnitario() == valorUnitario) {
    	    		valorUnitario = temp.getValorUnitario();
    	    	}
    	    	
    	    	//cria novo item e adiciona na lista
    		   Item item = new Item(produto, valorUnitario, quantidade);
    		   
    		   item.setValor(item.getValorTotal());
    		   
    		   listaDeItens.set(posicaoDoItem, temp);
    		   
    	    } else {
    	    	
    	      Item item = new Item(produto, valorUnitario, quantidade);
			 
    	      item.setValor(item.getValorTotal());
    	      
    	      getItens().add(item);
			 }
    	    
    	}   catch(RuntimeException erro) {
    		
    		  erro.getStackTrace();
    		  
    	    }  
    	
    	
    }

    public boolean removerItem(Produto produto) {
    	
    	int posicaoDoItem = -1;
    	
    	//roda pelos itens da lista atras do mesmo
    	for(int i = 0; i < getItens().size() && posicaoDoItem < 0; i++) {
    		
    		Item temp = listaDeItens.get(i);
    		
    		//se encontrar no produto, seta o valor para o item da lista
    		if(temp.getProduto().equals(produto)) {
    			
    			posicaoDoItem = i;
    			
    		}
    	}
    	
    	// se o item estiver na lista, remove pela posicao adicionada anteriormente
    	if(posicaoDoItem > -1) {
    		
    		getItens().remove(posicaoDoItem);
    		
    		return true;
    				
    	} else {
    		
    		return false;
    	}

    }

    public boolean removerItem(int posicaoItem) {
    	try {
    		listaDeItens.remove(posicaoItem);
    		
    		return true;
    		
    	} catch(RuntimeException erro) {
    		
    		return false;
    		
    	}

    }

    public BigDecimal getValorTotal() {
    	
    	//metodos lambda e stream para iterar dentro da lista e somar o valor de todos os itens
    	getItens().stream().forEach(valor -> valor.getValorTotal().plus());
    	
    	return (BigDecimal) getItens();

    }

    public Collection<Item> getItens() {
    	
    	// se lista vazia, cria uma nova
    	if(listaDeItens == null) {
    		
    		listaDeItens = new ArrayList<>();
    	}
    	
    	return listaDeItens;
    	
    }
}

CarrinhoComprasFactory.java

package br.com.improving.carrinho;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CarrinhoComprasFactory {

	private Map<String, CarrinhoCompras> carrinhosDeCompras = new HashMap<>();
	
	public CarrinhoComprasFactory() {
	}


    public CarrinhoCompras criar(String identificacaoCliente) {
    	
    	CarrinhoCompras carrinhoCompras = new CarrinhoCompras();
    	
    	if(!(carrinhosDeCompras.containsKey(identificacaoCliente))) {
    		
    		carrinhosDeCompras.put(identificacaoCliente, carrinhoCompras);

    		
    	} else {
    		
    		carrinhoCompras = null;    		
    		
    	}
    	
    	return carrinhoCompras;

    }

    public BigDecimal getValorTicketMedio() {

    	List<CarrinhoCompras> carrinhoComprasMedio = new ArrayList<>(this.carrinhosDeCompras.values());
    	    	
        BigDecimal valorTicketMedio = (BigDecimal) valorTicket(carrinhoComprasMedio);
        
        return valorTicketMedio.setScale(2, RoundingMode.HALF_EVEN);
        
    }


    public boolean invalidar(String identificacaoCliente) {
    	
    	try {
    		
    		carrinhosDeCompras.remove(identificacaoCliente);
    		
    		return true;
    		
    	    }
    	
    	    catch(RuntimeException erro) {
    	    	
    		 return false;
    	}

    }
    
    private Object valorTicket(List<CarrinhoCompras> carrinhos) {
        carrinhos.stream().forEach(s -> s.getValorTotal().plus().divide(new BigDecimal(carrinhos.size())));
        return carrinhos;
    }
    
    @Override
    public String toString() {
    	return "Cliente: " + carrinhosDeCompras;
    }
    
}

Item.java

package br.com.improving.carrinho;

import java.math.BigDecimal;


public class Item {

    private Produto produto;
    private BigDecimal valorUnitario;
    private int quantidade;
    private BigDecimal valor;


    public Item(Produto produto, BigDecimal valorUnitario, int quantidade) {
    	
    	this.produto = produto;
    	this.valorUnitario = valorUnitario;
    	this.quantidade = quantidade;
    	
    }

    public Produto getProduto() {
    	
    	return this.produto;
    }
    
    public void setValor(BigDecimal valor) {
	
    	this.valor = valor;
	}

    public BigDecimal getValorUnitario() {
    	
    	return this.valorUnitario;
    }

    public int getQuantidade() {
    	
    	return this.quantidade;
    }

    public BigDecimal getValorTotal() {
    	
    	BigDecimal valorTotalItem;
    	
    	BigDecimal vt = new BigDecimal(quantidade);
    	
    	valorTotalItem = vt.multiply(valorUnitario);
    	
    	return valorTotalItem;

    }
    
    @Override
    public String toString() {
        return "Item [Produto=" + produto + ", Valor Unitario=" + valorUnitario + ", Valor=" + valor + ", Quantidade=" + quantidade + "]\n";
    }
}

Produto.java

package br.com.improving.carrinho;

import java.util.Objects;


public class Produto {

    private Long codigo;
    private String descricao;

 
    public Produto(Long codigo, String descricao) {
    	this.codigo = codigo;
    	this.descricao = descricao;
    }

    public Long getCodigo() {
    	
    	return codigo;
    }

    public String getDescricao() {
    	
    	return descricao;
    }
    
    @Override
    public String toString() {
        return "Produto [descricao=" + descricao + "]";
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Produto)) return false;
        Produto produto = (Produto) o;
        return getCodigo().equals(produto.getCodigo()) &&
                getDescricao().equals(produto.getDescricao());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getCodigo(), getDescricao());
    }
}

TesteCarrinho.java

package br.com.improving.carrinho;

import java.math.BigDecimal;

public class TesteCarrinho {

	public static void main(String[] args) {

		BigDecimal v = new BigDecimal("4.12");
		BigDecimal v1 = new BigDecimal("8.24");
		BigDecimal v2 = new BigDecimal("1.14");
		
		BigDecimal v3 = new BigDecimal("3.12");
		BigDecimal v4 = new BigDecimal("5.24");
		BigDecimal v5 = new BigDecimal("2.50");
		BigDecimal v6 = new BigDecimal("6.51");
		
		Produto p = new Produto(1L, "Leite");
		Produto p1 = new Produto(1L, "Carne");
		Produto p2 = new Produto(1L, "Pão");
		
		Produto p3 = new Produto(1L, "Arroz");
		Produto p4 = new Produto(1L, "Feijão");
		Produto p5 = new Produto(1L, "Água");
		Produto p6 = new Produto(1L, "Salsicha");
			
		CarrinhoCompras c = new CarrinhoCompras();
		CarrinhoCompras c1 = new CarrinhoCompras();
		CarrinhoComprasFactory cf = new CarrinhoComprasFactory();
		CarrinhoComprasFactory cf1 = new CarrinhoComprasFactory();
		
		System.out.println(cf.criar("Ricardo"));
		System.out.println(cf.toString());
		//System.out.println(cf.invalidar("Ricardo"));
		System.out.println(" ");
		//System.out.println(cf.toString());
		System.out.println(cf1.criar("Pâmela"));
		System.out.println(cf1.toString());
		
		c.adicionarItem(p, v, 2);
		c.adicionarItem(p1, v1, 3);
		c.adicionarItem(p1, v1, 3);
		c.adicionarItem(p2, v2, 1);
		
		//carrinho 2
		c1.adicionarItem(p3, v3, 2);//arroz
		c1.adicionarItem(p4, v4, 3);//feijao
		c1.adicionarItem(p4, v4, 3);//feijao indice 2
		c1.adicionarItem(p5, v5, 1);//agua
		c1.adicionarItem(p6, v6, 3);//salsicha
		
		//c.removerItem(p1);
		c1.removerItem(p4);
		//c1.removerItem(3);
		
		
		System.out.println("Quantidade de itens: " + c.getItens().size());
		
		System.out.println("Lista itens no carrinho: \n");
		System.out.println(c.getItens());
		
		//imprimir carrinho 2
		System.out.println("Quantidade de itens: " + c1.getItens().size());
		
		System.out.println("Lista itens no carrinho: \n");
		System.out.println(c1.getItens());
		
		cf.getValorTicketMedio();
		cf1.getValorTicketMedio();
		/*AQUI O ERRO
		 * Exception in thread "main" java.lang.ClassCastException: class java.util.ArrayList cannot be cast to class java.math.BigDecimal (java.util.ArrayList and java.math.BigDecimal are in module java.base of loader 'bootstrap')
	at br.com.improving.carrinho.CarrinhoCompras.getValorTotal(CarrinhoCompras.java:155)
	at br.com.improving.carrinho.CarrinhoComprasFactory.lambda$0(CarrinhoComprasFactory.java:92)
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
	at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
	at br.com.improving.carrinho.CarrinhoComprasFactory.valorTicket(CarrinhoComprasFactory.java:92)
	at br.com.improving.carrinho.CarrinhoComprasFactory.getValorTicketMedio(CarrinhoComprasFactory.java:60)
	at br.com.improving.carrinho.TesteCarrinho.main(TesteCarrinho.java:68)
	* 
	*/
	}

}

No erro acima desse TesteCarrinho.java diz que não dá para converter BigDecimal para List. E ja tentei mudar para Double mas também não consegui. É possível fazer isso? Imprimir esse valor vindo dessa lista? Tem mais alguma coisa errada nesse método?
Uma outra: na resposta da empresa me disseram que Lista não é uma estrutura de dados indicada para esse tipo de aplicação. Mas penso que Pilha também não seria (problema para remover um item do meio por exemplo) e talvez árvore binária ou um grafo não seria bom também. Isso procede? Uma lista ser ruim para esse tipo de aplicação? Talvez um HashMap?
Desde já obrigado a todos que puderem responder. Já fui dispensado do processo. Até.

28 Respostas

H

Claro que não vai funcionar. BigDecimal e Double são números, List é um conjunto de dados. São tipos incompatíveis, e no método getValorTotal vc tenta converter um pro outro diretamente:

return (BigDecimal) getItens();

Como getItens() retorna a lista, e ela não é um tipo compatível com BigDecimal, então dá erro.

Na verdade este método está estranho. O que vc esperava fazer com esta linha?

getItens().stream().forEach(valor -> valor.getValorTotal().plus())

Pelo comentário, a ideia era somar o valor total dos itens, então assim não vai funcionar também. Pra que complicar? Faça o simpes:

public BigDecimal getValorTotal() {
    BigDecimal total = BigDecimal.ZERO;
    for (Item item: getItens()) {
        total = total.add(item.getValorTotal());
    }
    return total;
}

Se quiser muito usar stream, pode fazer:

public BigDecimal getValorTotal() {
    return getItens().stream().map(Item::getValorTotal).reduce(BigDecimal.ZERO, BigDecimal::add);
}

Pode ser que tenha erros similares em outros lugares (por exemplo, valorTicket retorna carrinhos, que é uma lista, mas o método deveria retornar BigDecimal, então vai dar o mesmo erro, etc). O resto não sei avaliar, porque não tem o enunciado do teste…

R

O enunciado da função public BigDecimal getValorTicketMedio() é o que segue:

/**
     * Retorna o valor do ticket médio no momento da chamada ao método.
     * O valor do ticket médio é a soma do valor total de todos os carrinhos de compra dividido
     * pela quantidade de carrinhos de compra.
     * O valor retornado deverá ser arredondado com duas casas decimais, seguindo a regra:
     * 0-4 deve ser arredondado para baixo e 5-9 deve ser arredondado para cima.
     *
     * @return BigDecimal
     */

aqui getItens().stream().forEach(valor -> valor.getValorTotal().plus()) é pra somar tudo que tem na lista, e esse valor vai para a função do getTicketMedio() para retornar o BIgDecimal.
Acredito que com stream e lambda facilita muito a vida. Mas obrigado, vou tentar o que vc passou. Abraços.

R

O erro esta nessa função (public BigDecimal getValorTicketMedio()) e aí a pergunta:

  • Como então retornar o valor total dos itens da lista em BigDecimal sem dar o erro, já que o cast não funciona?
    Obrigado.
R

Cara ([hugokotsubo]), queria compartilhar uma ideia para esse metodo do ticketMedio… e ver se vc pode me ajudar.
Seria assim:

  • a função valorTicket recebe uma lista de carrinhos do tipo CarrinhoCompras
  • dai soma o valor de todos os itens de carrinho por carrinho e guarda numa variavel VALORTOTAL
  • depois divide pela quantidade de carrinhos e retorna o valor em BigDecimal
  • por fim passa esse valor para a função ticketMedio e retorna o valor já com o ajuste das casas decimais.

Só estou estudando isso para ver se é possível por em prática… se puder me ajudar…agradeço. Obrigado mais uma vez

S

getItens retorna um Collection<Item>, um Collection jamais será um BigDecimal.

H
Solucao aceita

Isso aqui não está somando nada. Veja na documentação do método plus que ele não faz o que vc está pensando. O que ele faz é: para um BigDecimal cujo valor numérico é n, ele só retorna o equivalente a +n (ou seja, na prática ele retorna o mesmo valor). Ele não soma nada.

Como eu já disse, se quisesse somar usando stream, seria algo como:

public BigDecimal getValorTotal() {
    return getItens().stream().map(Item::getValorTotal).reduce(BigDecimal.ZERO, BigDecimal::add);
}

Mas eu ainda prefiro o for simples que eu sugeri acima. Streams são legais, mas se não souber o que está fazendo, não adianta nada, pode ficar até pior. Tente fazer o simples funcionar primeiro (eu acho o for mais simples sim, e se for o caso, mudar pra stream depois fica mais fácil).


Nesse caso, bastaria fazer:

public BigDecimal getValorTicketMedio() {
    BigDecimal total = BigDecimal.ZERO;
    for (CarrinhoCompras carrinho : this.carrinhosDeCompras.values()) {
        total = total.add(carrinho.getValorTotal());
    }
    return total.divide(BigDecimal.valueOf(this.carrinhosDeCompras.size()), 2, RoundingMode.HALF_UP);
}

Veja que o método divide já recebe o scale (coloquei 2, para duas casas decimais) e o modo de arredondamento.


Claro, também daria pra fazer com stream:

public BigDecimal getValorTicketMedio() {
    BigDecimal total = this.carrinhosDeCompras.values().stream().map(CarrinhoCompras::getValorTotal).reduce(BigDecimal.ZERO, BigDecimal::add);
    return total.divide(BigDecimal.valueOf(this.carrinhosDeCompras.size()), 2, RoundingMode.HALF_UP);
}

Mas não sei se ficou realmente “melhor”. Vai da opinião de cada um…

R

Cara com o for simples funcionou. Mas no TesteCarrinhos.java eu adiciono 2 carrinhos mas e quando chama o método só retorna 0. Mas parou de aparecer o erro. Acho que preciso “criar” uma quantidade de carrinhos, e adicioná-los num Map<>() talvez e depois aplicar o metodo do ticketMedio. Mas obrigado por ajudar.

R

Teria como resolver isso? Pegar os valores do getItens() e somá-los e retornar o BigDecimal? Obrigado pela ajuda!

H

Pelo que entendi, CarrinhoComprasFactory tem um Map com vários carrinhos. Sendo assim, não faz sentido ter mais de um factory, pois apenas um já teria todos os carrinhos.

Vc tem que entender a lógica que vc mesmo criou, entendi por cima que seria algo como:

  • criar um CarrinhoComprasFactory
  • o factory cria os carrinhos, usando o método criar
  • cada um desses carrinhos tem seus produtos

Ou seja:

// cria a factory
CarrinhoComprasFactory cf = new CarrinhoComprasFactory();
// cria os carrinhos
CarrinhoCompras c = cf.criar("Ricardo");
CarrinhoCompras c1 = cf.criar("Pâmela");

// adiciona os itens nos carrinhos
c.adicionarItem(p, v, 2);
c.adicionarItem(p1, v1, 3);
c.adicionarItem(p1, v1, 3);
c.adicionarItem(p2, v2, 1);

c1.adicionarItem(p3, v3, 2);//arroz
c1.adicionarItem(p4, v4, 3);//feijao
c1.adicionarItem(p4, v4, 3);//feijao indice 2
c1.adicionarItem(p5, v5, 1);//agua
c1.adicionarItem(p6, v6, 3);//salsicha

System.out.println("Quantidade de itens: " + c.getItens().size());

System.out.println("Lista itens no carrinho: \n");
System.out.println(c.getItens());

//imprimir carrinho 2
System.out.println("Quantidade de itens: " + c1.getItens().size());

System.out.println("Lista itens no carrinho: \n");
System.out.println(c1.getItens());

System.out.println(cf.getValorTicketMedio());

Saída:

Quantidade de itens: 3
Lista itens no carrinho: 

[Item [Produto=Produto [descricao=Leite], Valor Unitario=4.12, Valor=8.24, Quantidade=2]
, Item [Produto=Produto [descricao=Carne], Valor Unitario=8.24, Valor=24.72, Quantidade=3]
, Item [Produto=Produto [descricao=Pão], Valor Unitario=1.14, Valor=1.14, Quantidade=1]
]
Quantidade de itens: 4
Lista itens no carrinho: 

[Item [Produto=Produto [descricao=Arroz], Valor Unitario=3.12, Valor=6.24, Quantidade=2]
, Item [Produto=Produto [descricao=Feijão], Valor Unitario=5.24, Valor=15.72, Quantidade=3]
, Item [Produto=Produto [descricao=Água], Valor Unitario=2.50, Valor=2.50, Quantidade=1]
, Item [Produto=Produto [descricao=Salsicha], Valor Unitario=6.51, Valor=19.53, Quantidade=3]
]
39.05
R

Cara muito obrigado. Pensar MUITO rápido as vezes chega em coisas inimagináveis. Bora tentar outras vagas. Codar! []´s

R

Bom dia.
Cara… sei que encerrei esse tópico (se for o caso eu inicio um novo) mas… vc poderia me ajudar com duas outras coisas? (se possível!)
Tem essa função chamada “public boolean removerItem(Produto produto)” que é para remover um item da lista do carrinho pelo produto cadastrado, que é assim:

/**
     * Permite a remoção do item que representa este produto do carrinho de compras.
     *
     * @param produto
     * @return Retorna um boolean, tendo o valor true caso o produto exista no carrinho de compras e false
     * caso o produto não exista no carrinho.
     */
    public boolean removerItem(Produto produto) {
    	
    	int posicaoDoItem = -1;
    	
    	//roda pelos itens da lista atras do mesmo
    	for(int i = 0; i < getItens().size() && posicaoDoItem < 0; i++) {
    		
    		Item temp = listaDeItens.get(i);
    		
    		//se encontrar no produto, seta o valor para o item da lista
    		if(temp.getProduto().equals(produto)) {
    			
    			posicaoDoItem = i;
    			
    		}
    	}
    	
    	// se o item estiver na lista, remove pela posicao adicionada anteriormente
    	if(posicaoDoItem > -1) {
    		
    		getItens().remove(posicaoDoItem);
    		
    		return true;
    				
    	} else {
    		
    		return false;
    	}
    }

… e ele não esta removendo.
E também é possível remover pelo índice na lista, com essa função:

/**
     * Permite a remoção do item de acordo com a posição.
     * Essa posição deve ser determinada pela ordem de inclusão do produto na 
     * coleção, em que zero representa o primeiro item.
     *
     * @param posicaoItem
     * @return Retorna um boolean, tendo o valor true caso o produto exista no carrinho de compras e false
     * caso o produto não exista no carrinho.
     */
    public boolean removerItem(int posicaoItem) {
    	try {
    		listaDeItens.remove(posicaoItem);
    		
    		return true;
    		
    	} catch(RuntimeException erro) {
    		
    		return false;
    		
    	}

    }

… que não vai também. Não sei porque, porque se mandar listar o índice ele mostra onde produto tal esta e qual seu índice. Mas também não remove. No Teste eu executo para adicionar o item e depois remover pelo produto, mas ele aparece na lista de itens.

E a outra coisa é nesse método de criação do CarrinhoComprasFactory, " public CarrinhoCompras criar(String identificacaoCliente)". Segue a descrição e o código:

/**
     * Cria e retorna um novo carrinho de compras para o cliente passado como parâmetro.
     *
     * Caso  exista um carrinho de compras para o cliente passado como parâmetro, este carrinho deverá ser retornado.
     *
     * @param identificacaoCliente
     * @return CarrinhoCompras
     */
    public CarrinhoCompras criar(String identificacaoCliente) {
    	
    	CarrinhoCompras carrinhoCompras = new CarrinhoCompras();
    	
    	if(!(carrinhosDeCompras.containsKey(identificacaoCliente))) {
    		
    		carrinhosDeCompras.put(identificacaoCliente, carrinhoCompras);

    		
    	} else {
    		
    		carrinhoCompras = null;    		
    		
    	}
    	
    	return carrinhoCompras;

    }

E para isso eu crio um HashMap antes para verificar se tem já carrinho com essa String de identificação, mas não verifica…

private Map<String, CarrinhoCompras> carrinhosDeCompras = new HashMap<>();

e se eu fizer assim:

CarrinhoComprasFactory cf = new CarrinhoComprasFactory();

		//add carrinhos na factory
		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("Mesmo nome retorna null");
		} else {
			System.out.println("Erro ao criar carrinho");
		}

Ele retorna só “Erro ao criar carrinho”. Ou seja mesmo com a mesma identificação ele cria, e não deveria (deveria retornar como null). Teria como me ajudar? Estou com esse quebra-cabeça que tá dureza… Se puder agradeço. Se precisar de outro tópico, o abro. E desde já obrigado. Mais uma vez.

H

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.

R

Esse “valor” era uma tentativa de artificio técnico para resolver a questão do valor unitário. Ficou e e esqueci de tirar na criação do post. Erro de conferência da minha parte.

R

Olha… muito obrigado por revisar todo meu código. Eu nunca trabalhei com carteira assinada, ou mesmo com contrato em uma software house ou empresa grande… depois das faculdades e pós e cursos estou tentando sair dessa vida de funcionário público para tentar vaga como estagiário ou júnior ou sei-lá-o-que dentro de programação… mas sem o feeling é meio difícil… Pensar e colocar em código é complicado. Mais uma vez obrigado. Sei que devo ter torrado sua paciência. Até mais!

R

… então… a ideia dessa parte vem daqui:

/**
     * Permite a adição de um novo item no carrinho de compras.
     *
     * Caso o item  exista no carrinho para este mesmo produto, as seguintes regras deverão ser seguidas:
     * - A quantidade do item deverá ser a soma da quantidade atual com a quantidade passada como parâmetro.
     * - Se o valor unitário informado for diferente do valor unitário atual do item, o novo valor unitário do item deverá ser
     * o passado como parâmetro.
     *
     * Devem ser lançadas subclasses de RuntimeException caso não seja possível adicionar o item ao carrinho de compras.
     *
     * @param produto
     * @param valorUnitario
     * @param quantidade
     */

da função public void adicionarItem(Produto produto, BigDecimal valorUnitario, int quantidade)

A princípio de acordo com o que precisava na descrição, estava funcionando… mas agora vou por na ponto do lápis para ver. Obrigado, de novo : ) !!!

H

Então o que eu fiz acima está certo. Talvez só precise ajustar o detalhe do valor unitário mudar apenas se ele for diferente do item:

public void adicionarItem(Produto produto, BigDecimal valorUnitario, int quantidade) {
    boolean existe = false;
    for (Item item : listaDeItens) {
        if (item.getProduto().equals(produto)) {
            existe = true;
            if (item.getValorUnitario() != valorUnitario) { // se o valor mudou, altera o item
                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));
    }
}
R

uma dúvida… quando ele pede assim:

* Devem ser lançadas subclasses de RuntimeException caso não seja possível adicionar o item ao carrinho de compras.

na função public void adicionarItem(Produto produto, BigDecimal valorUnitario, int quantidade)
precisa de um try-catch para conseguir usar as tais subclasses de RuntimeException, certo?

S

Não, se é para LANÇAR a exceção então você vai por um throw

H

Bom, o método que eu fiz acima está tão simples que não sei qual tipo de exceção poderia ser lançada (talvez NullPointerException em alguma situação específica).

Enfim, talvez seja interessante incluir alguma validação. Por exemplo, se a quantidade for negativa, não faz sentido adicionar o item, então poderia ser algo assim:

public void adicionarItem(Produto produto, BigDecimal valorUnitario, int quantidade) {
    if (produto == null) {
        throw new IllegalArgumentException("Produto não pode ser nulo");
    }
    if (valorUnitario == null || valorUnitario.compareTo(BigDecimal.ZERO) <= 0) {
        throw new IllegalArgumentException("Valor unitário deve ser maior que zero");
    }
    if (quantidade <= 0) {
        throw new IllegalArgumentException("Quantidade deve ser maior que zero");
    }

    boolean existe = false;
    for (Item item : listaDeItens) {
        if (item.getProduto().equals(produto)) {
            existe = true;
            item.setValor(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));
    }
}

Ou seja, se algum dado for inválido, ele não adiciona o item (inventei as regras da minha cabeça, tem que ver se tem algum outro requisito dizendo o que pode ou não ser adicionado).

Quanto ao try/catch, vc usa na hora de adicionar algo:

CarrinhoCompras c = // cria o carrinho

try {
    c.adicionarItem(produto, valor, quantidade);
} catch (IllegalArgumentException e) {
    System.out.println("Erro ao adicionar: " + e.getMessage());
}
R

Uma pergunta… nas restrições ele diz assim na classe Produto:

/**
 * Classe que representa um produto que pode ser adicionado
 * como item ao carrinho de compras.
 *
 * Importante: Dois produtos são considerados iguais quando ambos possuem o mesmo 
 * código.
 */

e na função adicionarItem do CarrinhoCompras só fala para checar se o item já estiver ali, então fazer isso aqui:

**if (item.getProduto().getCodigo().equals(produto.getCodigo()))** {
            	
                existe = true;
               
                if (item.getValorUnitario() != valorUnitario) {
                	
                item.setValorUnitario(valorUnitario);
                
                }
                
                item.adicionarQuantidade(quantidade);
                
                break; 
            }
        }

não vai adicionar produtos com códigos iguais, certo? Vai adicionar só códigos diferentes… ou estou errado?

H

Se o produto já está na lista de itens, ele só atualiza a quantidade e valor do item.

R

Entendi. É que estava criando produtos assim:

Produto p1 = new Produto(1L, "Leite");
Produto p2 = new Produto(1L, "Leite em pó");

E estava cadastrando ambos mesmo com código igual (no caso esse Long 1L)… é que fui ver essa restrição do mesmo código agora. Dai na hora de puxar o getItens() tá lá os 2 produtos cadastrados

[Item [Produto=Leite, Código=1, Valor Unitario=19.99, Quantidade=4]
[Item [Produto=Leite em pó, Código=1, Valor Unitario=9.99, Quantidade=2]

e embora descrições diferentes (Leite e Leite em pó) no adicionarItem() se estiver adicionando DOIS PRODUTOS EXATEMENTE IGUAIS

c.adicionarItem(p2, v2, 1);//pão
c.adicionarItem(p2, v2, 1);//pão denovo

ele atualiza a quantidade e seta o valorUnitário do parâmetro, mas se for CÓDIGO IGUAL PRODUTO DIFERENTE

Produto p2 = new Produto(4L, "Pão");
Produto p2a = new Produto(4L, "Pão");//mesmo nome e código

c.adicionarItem(p2, v2, 3);
c.adicionarItem(p2a, v8, 2);//chama pão com mesmo código e descrição, valor e quant diferente

ele add os com códigos iguais

Item [Produto=Pão, Código=4, Valor Unitario=1.14, Quantidade=3]
Item [Produto=Pão, Código=4, Valor Unitario=14.99, Quantidade=2]//esse é o p2a

Mas se forem EXATAMENTE IGUAIS ele só atualiza. Obrigado.

R

Man… desculpe te importunar novamente… tô ficando loko aqui… mas tem como checar antes de adicionar o item na lista pela função adicionarItem() (ou por outro lugar) se tem códigos iguais? Porque eu fiz isso aqui na parte que vc organizou:

if (item.getProduto().getCodigo().equals(produto.getCodigo()))

e se tiver mesmo código, ele não adiciona, PORÉM ele seta o valor do item seguinte e aumenta a quantidade com a do item seguinte (como era pra fazer mesmo) gerando erro no valor total e quantidade. É possível ver se os códigos dos produtos são iguais e se forem não cadastrar se de fato o produto já estiver la, só arrumar valor e quantidade, mas esse ponto dos códigos iguais lançando a exceção dentro do if, tipo para tudo… obrigado por toda a ajuda.

H

Coloca o código completo do método e como vc está testando

R

Classe CarrinhoComprars.java

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
 * Classe que representa o carrinho de compras de um cliente.
 */
public class CarrinhoCompras {
	
	private List<Item> itens;
	
	public CarrinhoCompras() {
		
		itens = new ArrayList<>();
		
	}

    /**
     * Permite a adição de um novo item no carrinho de compras.
     *
     * Caso o item já exista no carrinho para este mesmo produto, as seguintes regras deverão ser seguidas:
     * - A quantidade do item deverá ser a soma da quantidade atual com a quantidade passada como parâmetro.
     * - Se o valor unitário informado for diferente do valor unitário atual do item, o novo valor unitário do item deverá ser
     * o passado como parâmetro.
     *
     * Devem ser lançadas subclasses de RuntimeException caso não seja possível adicionar o item ao carrinho de compras.
     *
     * @param produto
     * @param valorUnitario
     * @param quantidade
     */
    public void adicionarItem(Produto produto, BigDecimal valorUnitario, int quantidade) {


    	if (produto == null) {
            throw new IllegalArgumentException("Produto não pode ser nulo");
        }
    	
        if (valorUnitario == null || valorUnitario.compareTo(BigDecimal.ZERO) <= 0) {
            throw new IllegalArgumentException("Valor unitário deve ser maior que zero");
        }
        if (quantidade <= 0) {
            throw new IllegalArgumentException("Quantidade deve ser maior que zero");
        }
        
    	boolean existe = false;
    	
        for (Item item : itens) {
        	
        	//if (item.getProduto().equals(produto)) {
            if (item.getProduto().getCodigo().equals(produto.getCodigo())) {
            	
                existe = true;
                               
                if (item.getValorUnitario() != valorUnitario) {
                	
                item.setValorUnitario(valorUnitario);
                
                }
                
                item.adicionarQuantidade(quantidade);
                
                break; 
            }
        }

        if (!existe) {
        	
        	itens.add(new Item(produto, valorUnitario, quantidade));
        }  

    }

    /**
     * Permite a remoção do item que representa este produto do carrinho de compras.
     *
     * @param produto
     * @return Retorna um boolean, tendo o valor true caso o produto exista no carrinho de compras e false
     * caso o produto não exista no carrinho.
     */
    public boolean removerItem(Produto produto) {
    	
    	Iterator<Item> it = itens.iterator();
    
    	while(it.hasNext()) {
    		
    		Produto p = it.next().getProduto();
    		
    		if(p.equals(produto)) {
    			
    			it.remove();
    			
    			return true;
    		}
    	}
    	return false;
    }

    /**
     * Permite a remoção do item de acordo com a posição.
     * Essa posição deve ser determinada pela ordem de inclusão do produto na 
     * coleção, em que zero representa o primeiro item.
     *
     * @param posicaoItem
     * @return Retorna um boolean, tendo o valor true caso o produto exista no carrinho de compras e false
     * caso o produto não exista no carrinho.
     */
    public boolean removerItem(int posicaoItem) {
    	
    	if(posicaoItem < 0 || posicaoItem >= itens.size()) {
    		
    		return false;
    		
    	}
    	
    	itens.remove(posicaoItem);
    	
    	return true;

    }

    /**
     * Retorna o valor total do carrinho de compras, que deve ser a soma dos valores totais
     * de todos os itens que compõem o carrinho.
     *
     * @return BigDecimal
     */
    public BigDecimal getValorTotal() {

    	BigDecimal total = BigDecimal.ZERO;
  	  
  	  	for(Item item: getItens()) {
  	  
  	  		total = total.add(item.getValorTotal());
  	  
  	  }
  	  
  	  return total;
    }

    /**
     * Retorna a lista de itens do carrinho de compras.
     *
     * @return itens
     */
    public Collection<Item> getItens() {

    	return itens;
    }
}

Main.java

import java.math.BigDecimal;

public class Main {

	public static void main(String[] args) {

		//cria a factory
		CarrinhoComprasFactory cf = new CarrinhoComprasFactory();

		//add carrinhos na factory
		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("Mesmo nome retorna null");
		} else {
			System.out.println("Erro ao criar carrinho");
		}
		
		//System.out.println(c2.getIdentificacaoCliente());
		if (c2 == null) {
			System.out.println("Carrinho já criado");
		} else {
			System.out.println("Criado");
		}
				
		BigDecimal v = new BigDecimal("4.12");
		BigDecimal v1 = new BigDecimal("8.24");
		BigDecimal v2 = new BigDecimal("1.14");
		
		BigDecimal v3 = new BigDecimal("3.12");
		BigDecimal v4 = new BigDecimal("5.24");
		BigDecimal v5 = new BigDecimal("2.50");
		BigDecimal v6 = new BigDecimal("6.51");
		BigDecimal v7 = new BigDecimal("19.99");
		BigDecimal v8 = new BigDecimal("14.99");
		
		
		Produto p = new Produto(1L, "Leite");//item 0
		Produto p1 = new Produto(2L, "Carne");//item 1
		Produto p2 = new Produto(3L, "Pão");//item 2
		Produto p2a = new Produto(3L, "Pão de Sal");//mesmo nome e código, mas poderia colocar só código iguais
		//p2 e p2a mesmo código 3L
		Produto p3 = new Produto(5L, "Arroz");
		Produto p4 = new Produto(6L, "Feijão");
		Produto p5 = new Produto(7L, "Água");
		Produto p6 = new Produto(8L, "Salsicha");
		Produto p7 = new Produto(9L, "Sabão em pó");
		
		//carrinho C
		c.adicionarItem(p, v, 2);//leite
		c.adicionarItem(p1, v1, 3);//carne v1=4.12
		c.adicionarItem(p1, v3, 3);//erro deve dar aqui - carne denovo v3=3.12 TEM QUE FICAR COM ESSE VALOR
		c.adicionarItem(p2, v2, 2);//pão
		c.adicionarItem(p2, v2, 2);//pão denovo
		c.adicionarItem(p2a, v8, 2);//chama pão de sal código igual do pão pra ver o erro
		c.adicionarItem(p7, v7, 2);//sabao em pó
		//c.removerItem(p3);

		
		//carrinho C1
		c1.adicionarItem(p3, v3, 2);//arroz
		c1.adicionarItem(p3, v3, 1);//mais um arroz com 2 + 1 = 3 quantidade
		c1.adicionarItem(p4, v4, 3);//feijao
		c1.adicionarItem(p4, v4, 2);//feijao indice 2
		c1.adicionarItem(p5, v5, 1);//agua
		c1.adicionarItem(p6, v6, 3);//salsicha
		
		
		//c.removerItem(3);
		//c1.removerItem(p6);
		
		//imprimir carrinho C
		
		System.out.println("Carrinho C");
		System.out.println("Quantidade de itens: " + c.getItens().size());
		System.out.println("Lista itens no carrinho: \n");
		System.out.println(c.getItens());
		
		c.removerItem(3);//removendo sabão em pó
		System.out.println("Lista itens no carrinho depois de removido um item: \n");
		System.out.println(c.getItens());
		//c.removerItem(p7);
		//System.out.println("Carrinho C");
		//System.out.println("Quantidade de itens depois de removido algum item: " + c.getItens().size());
		//System.out.println("Lista itens no carrinho: \n");
		//System.out.println(c.getItens());
		
		//imprimir carrinho C1
		System.out.println("Carrinho C1");
		System.out.println("Quantidade de itens: " + c1.getItens().size());
		System.out.println("Lista itens no carrinho: \n");
		System.out.println(c1.getItens());

		c1.removerItem(p6);//removendo salsicha
		System.out.println("Lista itens no carrinho depois de removido um item: \n");
		System.out.println(c1.getItens());
		//c.removerItem(3);
		
		
		System.out.println(" ");
		System.out.println("Valor total dos itens do carrinho C: R$ "+c.getValorTotal());
		System.out.println("Valor total dos itens do carrinho C1: R$ "+c1.getValorTotal());
		
		System.out.println("Valor ticket medio dos carrinhos: R$ " + cf.getValorTicketMedio());
		/*
		System.out.println(c.getItens().size() + " itens no carrinho antes de remover p7: \n");
		System.out.println(c.getItens());

		System.out.println("--------------------");
		if (c.removerItem(p7)) {
		    System.out.println(c.getItens().size() + " itens no carrinho depois de remover p7: \n");
		    System.out.println(c.getItens());
		} else {
		    System.out.printf("Produto Código %d (%s) não foi removido porque não estava no carrinho \n", p7.getCodigo(), p7.getDescricao());
		}
		
		System.out.println("Depois de removido itens, valor ticketMedio muda \n");
		System.out.println("Valor ticket medio dos carrinhos: R$ " + cf.getValorTicketMedio());*/
		
		
		if(cf.invalidar("Alexandre")) {
			System.out.println("Invalidado");
		} else {
			System.out.println("Não invalidado");
		}
		
		if(cf.invalidar("Isabela")) {
			System.out.println("invalido e removido");
		} else {
			System.out.println("Não removido");
		}
			
		if(cf.invalidar("A")) {
			System.out.println("Invalido e removido");
		} else {
			System.out.println("Não invalido e não removido");
		}
		
		if(cf.invalidar("b")) {
			System.out.println("Invalido e removido");
		} else {
			System.out.println("Não invalido e não removido");
		}
	}
}

Ta aí! Obrigado!

H
c.adicionarItem(p1, v3, 3);//erro deve dar aqui - carne denovo v3=3.12 TEM QUE FICAR COM ESSE VALOR

Depois dessa linha, o valor do produto é 3.12, como deveria ser. A descrição diz que é para atualizar o valor, e é isso que ele faz.

c.adicionarItem(p2a, v8, 2);//chama pão de sal código igual do pão pra ver o erro

Aqui também não dá erro. Como o código é o mesmo, ele atualizar o valor para 14.99 e adiciona a quantidade.

Não entendi qual o problema. Não tem erro nenhum.

R

Boa tarde… desculpe te incomodar novamente. Estou pensando num ponto aqui, gostaria de saber se é possível e se tem como vc me ajudar. Estava pensando num modo de quando for remover um produto pelo removerItem(Produto produto) ele percorrer todos os carrinhos instanciados e se encontrar um produto com mesmo código, remover de todos os carrinhos.Eu pensei nissaqui:

public List<Produto> encontrarProdutosIguais(CarrinhoCompras carrinhoCompras) {
    	  
    	List<Produto> produtosIguais = new ArrayList<>();
    	  
    	for (Item item : carrinhoCompras.getItens()) {
    	  
    		Produto produtoAtual = item.getProduto();
    	   
    		boolean produtoJaEncontrado = false;
    	    
    		for (Produto produtoIgual : produtosIguais) {
    	     
    			if (produtoAtual.equals(produtoIgual)) {
    	     
    	    	  produtoJaEncontrado = true;
    	     
    	    	  break;
    	     
    			}
    	    }
    		
    	    if (!produtoJaEncontrado) {
    	     
    	    	produtosIguais.add(produtoAtual);
    	   
    	    }

Mas não ta indo. Adicionei esse método no CarrinhoCompras dentro do removerItem(Produto produto) mas só remove do carrinho que eu especifico, mais ou menos assim:

CarrinhoComprasFactory cf = new CarrinhoComprasFactory();

				//add carrinhos na factory
				CarrinhoCompras c = cf.criar("Cliente1");
				CarrinhoCompras c1 = cf.criar("Cliente2");

				Produto p1 = new Produto(2L, "Carne");
				Produto p2 = new Produto(3L, "Pão");
                                Produto p3 = new Produto(3L, "Pão de Sal");

                c.adicionarItem(p2, v2, 2);
                c.adicionarItem(p7, v5, 2);

                c1.adicionarItem(p3, v6, 2);
                c1.adicionarItem(p7, v7, 2);

//e se eu chamo para c1.removerItem(p7)
//só remove do c1, e fica lá no carrinho c

é possível percorrer todos os carrinhos criados com o código acima, e remover produtos com o código igual de todos os carrinhos?

Obrigado.

S

Você pode modificar o seu método removerItem dessa forma:

public boolean removerItem(Produto produto) {
    List<Item> itensIguais = new ArrayList<>();
    for (Item item : itens) {
    	Produto p = item.getProduto();
    	if (p.equals(produto)) {
    		itensIguais.add(item);
    	}
    }
    itens.removeAll(itensIguais);
    return !itensIguais.isEmpty();
}

Aí crie um método estático na classe CarrinhoCompras que permita remover os itens de vários carrinhos de uma só vez:

public static void removerItem(Produto produto, CarrinhoCompras... carrinhos) {
    for (CarrinhoCompras carrinho : carrinhos) {
        carrinho.removerItem(produto);
    }
}

Então, no seu main você pode fazer assim:

CarrinhoComprasFactory cf = new CarrinhoComprasFactory();

CarrinhoCompras c1 = cf.criar("Cliente1");
CarrinhoCompras c2 = cf.criar("Cliente2");

Produto p1 = new Produto(2L, "Carne");
Produto p2 = new Produto(3L, "Pão");
Produto p3 = new Produto(3L, "Pão de Sal");

c1.adicionarItem(p2, v2, 2);
c1.adicionarItem(p7, v5, 2);

c2.adicionarItem(p3, v6, 2);
c2.adicionarItem(p7, v7, 2);

CarrinhoCompras.removerItem(p7, c1, c2);

Tenho uma pergunta: Porque você tem uma CarrinhoComprasFactory sendo que seu CarrinhoCompras possui um construtor padrão público e não implementa nenhuma interface?

Criado 19 de janeiro de 2023
Ultima resposta 4 de fev. de 2023
Respostas 28
Participantes 3