Teste prático Java

Pessoal, após sugestões resolvi postar esse teste aqui também para obter uma resposta mais ampla.
Trata-se de um teste prático em Java que fui reprovado e gostaria de saber se vocês me ajudam a achar a solução, pois virou questão de honra agora.
Se puderem ajudar ficarei muito agradecido para servir de lição a não cometer mais os mesmos erros…
Seguem as classes anexas, o procedimento encontra-se na classe Main…

Nos itens 1 e 2: Estão interessados em saber se você sabe usar a classe BigDecimal. Se você não sabe usar, recomendo a leitura de:

No item 3, estão interessados em ver seu uso de Collections. Uma das formas de fazer totalizações como essa é através de maps. Foi assim que você resolveu?

Agradeço a ajuda ViniGodoy. Sei que tenho que usar o BigDecimal pela precisão e Collections mas não sei como implementá-los. Se puder resolver o teste e me enviar a solução ficaria muito agradecido.

Cara, dificilmente alguém aqui no GUJ vai te dar a resposta simplesmente porque você pediu.

Já que virou questão de honra pra você, por que você não tenta resolver, e quando empacar em alguma coisa ou tiver alguma dúvida específica, volta a postar aqui?

Rodrigo,
Calma colega, não precisa agir dessa maneira, apenas pedi uma ajuda. Se você não podia ou não tinha capacidade para ajudar bastava não se pronunciar. Só não concordo contigo quando você afirma que dificilmente alguém irá me ajudar porque simplesmente pedi, você não representa todos neste forum e se pedi ajuda é porque já tentei resolver o problema e não consegui, por este motivo perdi a vaga e gostaria de saber onde foi meu erro.
Conheci muita gente na área de TI nesses 22 anos de carreira, essas pessoas achavam que seriam os melhores profissionais do mundo somente por não transmitirem seus conhecimentos aos colegas e deterem informação, só esqueciam que um dia aprenderam com alguém e este alguém teve paciência e sabedoria para ensiná-lo. Não digo que este seja seu caso, mas um problema que infelizmente minimiza o respeito em nossa área frente as demais e transforma o ego de pessoas comuns, achando que são semi-deus e esquecendo-se de suas raízes.
Obrigado pela atenção.

De maneira nenhuma, João.

A única coisa que eu digo é que eu já estou aqui nesse fórum faz um tempo, e com esse tempo eu consegui ver como as coisas funcionam. O que você pediu não foi uma ajuda, foi uma implementação pronta, e isso, raramente eu vejo por aqui.

As pessoas que participam do fórum, separam um tempo do dia delas pra vir aqui ajudar quem puderem ajudar, como já vi o Vini fazer inúmeras vezes. E ainda digo, quando ele vê o esforço da pessoa que pede ajuda, que é mostrado por exemplos de código, tentativas e/ou uma descrição do que fez, ele responde muito bem, respostas muito completas e fundamentadas, nesse caso ele até te mostra o que falta no seu código.

Se você disse que já tentou resolver, não seria um problema dizer aqui o que você fez, não é mesmo?

O que eu te disse foi simplesmente uma dica, porque o que você pediu vai até contra as regras do fórum, mas se você se ofendeu peço desculpas.

Grande abraço!

[quote=Rodrigo Sasaki]Cara, dificilmente alguém aqui no GUJ vai te dar a resposta simplesmente porque você pediu.

Já que virou questão de honra pra você, por que você não tenta resolver, e quando empacar em alguma coisa ou tiver alguma dúvida específica, volta a postar aqui?[/quote]
+1

Se é questão de honra pra você, então você quem deveria resolver. Nós podemos ajudar, mas você precisa fazer a sua parte (que vai muito mais além do que pedir o dever de casa).

Já andei olhando a classe BigDecimal. Veja algumas coisas que escrevi no link:

http://agorandroid.blogspot.com.br/2012/04/java-valores-monetarios-float-double-e.html

Muito Obrigado pela força A H Gusukama e ViniGodoy. E ao puxão de orelha pelos demais… :wink:
Olhei o que o A H Gusukama escreveu e me ajudou muito.
Realizei a implementação da 1ª e 2ª questão, o código segue anexo.
Quem puder realmente ajudar com críticas construtivas avaliando se minha implementação está correta e fazendo suas considerações, eu realmente agradeço.
Depois envio a implementação das demais classes.

Olá João, crie o hábito de fazer pequenos programas para testar e consolidar conhecimentos.

Segue um programinha de exemplo para testar a classe BigDecimal, basta retirar o comentário (//) que está nas opções de arredondamento e testar cada opção.

import java.math.BigDecimal;
import java.math.RoundingMode;

public class TesteBigDecimal {

	    public static void main(String[] args) {

//	    	RoundingMode rm = RoundingMode.CEILING;
//	    	RoundingMode rm = RoundingMode.DOWN;
//       	RoundingMode rm = RoundingMode.FLOOR;
//        	RoundingMode rm = RoundingMode.HALF_DOWN;
//	    	RoundingMode rm = RoundingMode.HALF_EVEN;
//	    	RoundingMode rm = RoundingMode.HALF_UP;
//	    	RoundingMode rm = RoundingMode.UP;
	    	
	    	System.out.println("Rounding Mode = " + rm);
	    	BigDecimal bd = new BigDecimal("-10.004");
	    	System.out.println("Valor             = " + bd);
	    	bd = bd.setScale(2, rm);
	    	System.out.println("Valor arredondado = " + bd);
	    	
	    	bd = new BigDecimal("-10.005");
	    	System.out.println("Valor             = " + bd);
	    	bd = bd.setScale(2, rm);
	    	System.out.println("Valor arredondado = " + bd);
	    	
	    	bd = new BigDecimal("-10.006");
	    	System.out.println("Valor             = " + bd);
	    	bd = bd.setScale(2, rm);
	    	System.out.println("Valor arredondado = " + bd);
	    	
	    	bd = new BigDecimal("10.004");
	    	System.out.println("Valor             = " + bd);
	    	bd = bd.setScale(2, rm);
	    	System.out.println("Valor arredondado = " + bd);
	    	
	    	bd = new BigDecimal("10.005");
	    	System.out.println("Valor             = " + bd);
	    	bd = bd.setScale(2, rm);
	    	System.out.println("Valor arredondado = " + bd);
	    	
	    	bd = new BigDecimal("10.006");
	    	System.out.println("Valor             = " + bd);
	    	bd = bd.setScale(2, rm);
	    	System.out.println("Valor arredondado = " + bd);
	    	
	    }
	
}

Muito obrigado A H Gusukuma! Acredito que agora esteja correto. Após utilizar sua classe teste percebi que o arredondamento correto neste caso é o HALP_UP, e não o CEILING, como estava fazendo erroneamente.
Agora estou tentando fazer as questões 03 e 04, mas estou já a 01 semana nelas e não saiu nada ainda…Tá difícil, mas não vou desistir e se puder continuar ajudando eu agradeço muito.

Algumas observações sobre o código:
Não se deve alterar o valor de uma variável a ser retornado em um get , pode-se eventualmente mudar o formato, devolver uma cópia, etc.

No caso do ItemPedido, você está mudando a escala no valorTotal e fazendo o cálculo do valorUnitário. O recomendado é você deixar essas variáveis com os valores corretos. O que se deve considerar é em que ou qual momento se deve fazer isso. No caso do valorTotal ele é setado, então esse deve ser o momento para fazer o arredondamento.
No caso do valorUnitario, ele é o resultado de um cálculo entre o valorTotal e a quantidade, então você deve tratar o valorUnitario nesses dois momentos. Você faz o cálculo nos dois métodos, ou, faz em um e indica que o valorUnitario está inválido (e que precisa ser calculado) no outro.
Outra coisa, o setValorUnitario não deveria existir ou não ser público, já que é calculado.

As outras questões você deve dar uma estudada em Arrays e coleções como indicou o ViniGodoy.

[quote=A H Gusukuma]Algumas observações sobre o código:
Não se deve alterar o valor de uma variável a ser retornado em um get , pode-se eventualmente mudar o formato, devolver uma cópia, etc.

No caso do ItemPedido, você está mudando a escala no valorTotal e fazendo o cálculo do valorUnitário. O recomendado é você deixar essas variáveis com os valores corretos. O que se deve considerar é em que ou qual momento se deve fazer isso. No caso do valorTotal ele é setado, então esse deve ser o momento para fazer o arredondamento.
No caso do valorUnitario, ele é o resultado de um cálculo entre o valorTotal e a quantidade, então você deve tratar o valorUnitario nesses dois momentos. Você faz o cálculo nos dois métodos, ou, faz em um e indica que o valorUnitario está inválido (e que precisa ser calculado) no outro.
Outra coisa, o setValorUnitario não deveria existir ou não ser público, já que é calculado.

As outras questões você deve dar uma estudada em Arrays e coleções como indicou o ViniGodoy.
[/quote]

A H Gusukuma, fiz as alterações solicitadas, poderia verificar se estão corretas? Segue implementação abaixo. Obrigado mais uma vez.

public class ItemPedido {
private String cnpjCliente;
private String usuarioSolicitante;
private String codigoItem;
private int quantidade;
private BigDecimal valorTotal;
private BigDecimal valorUnitario;

public BigDecimal getValorTotal() {
    //retur valorTotal.round(new MathContext(2, RoundingMode.CEILING));
    //return valorTotal.setScale(2,RoundingMode.HALF_UP);
    return valorTotal;
}

public void setValorTotal(BigDecimal valorTotal) {
    //this.valorTotal = valorTotal;
    this.valorTotal = valorTotal.setScale(2,RoundingMode.HALF_UP);
    this.valorUnitario = valorTotal.divide(new BigDecimal(this.quantidade)).setScale(2,RoundingMode.HALF_UP);
}

public BigDecimal getValorUnitario() {
    //return this.valorUnitario.divide(new BigDecimal(this.quantidade)).round(new MathContext(2,RoundingMode.HALF_UP));
    //return this.valorUnitario.divide(new BigDecimal(this.quantidade)).setScale(2,RoundingMode.HALF_UP);
    return valorUnitario;
}


public int getQuantidade() {
        return quantidade;
}

public void setQuantidade(int quantidade) {
        this.quantidade = quantidade;
        this.valorUnitario = valorTotal.divide(new BigDecimal(this.quantidade)).setScale(2,RoundingMode.HALF_UP);
}

}

Está ok, ou quase…
Como o cálculo do valorUnitario é realizado duas vezes, o melhor é colocar o cálculo em um método private e chamá-lo nos dois pontos. O motivo é para evitar, no momento de uma manutenção, ter que alterar em dois lugares, ou se esquecer de alterar em um ou outro.
O mesmo raciocínio deve ser aplicado na classe Pedido.

[quote=A H Gusukuma]Está ok, ou quase…
Como o cálculo do valorUnitario é realizado duas vezes, o melhor é colocar o cálculo em um método private e chamá-lo nos dois pontos. O motivo é para evitar, no momento de uma manutenção, ter que alterar em dois lugares, ou se esquecer de alterar em um ou outro.
O mesmo raciocínio deve ser aplicado na classe Pedido.

[/quote]

Entendi perfeitamente A H Gusukuma, com isso evitamos redundância de códig! Muito boa sua dica…
O “x” da questão agora é saber se implementei corretamente o que foi pedido…rs
Seguem as classes Pedido e ItemPedido alteradas.

package modelo;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;

public class ItemPedido {
private String cnpjCliente;
private String usuarioSolicitante;
private String codigoItem;
private int quantidade;
private BigDecimal valorTotal;
private BigDecimal valorUnitario;
private BigDecimal calculaValorUnitario;

private BigDecimal calculaValorUnitario() {
    return calculaValorUnitario.divide(new BigDecimal(this.quantidade)).setScale(2,RoundingMode.HALF_UP);
}
    
public BigDecimal getValorTotal() {
    //retur valorTotal.round(new MathContext(2, RoundingMode.CEILING));
    //return valorTotal.setScale(2,RoundingMode.HALF_UP);
    return valorTotal;
}

public void setValorTotal(BigDecimal valorTotal) {
    //this.valorTotal = valorTotal;
    this.valorTotal = valorTotal.setScale(2,RoundingMode.HALF_UP);
    //this.valorUnitario = valorTotal.divide(new BigDecimal(this.quantidade)).setScale(2,RoundingMode.HALF_UP);
    this.valorUnitario = calculaValorUnitario();
    
}

public BigDecimal getValorUnitario() {
    //return this.valorUnitario.divide(new BigDecimal(this.quantidade)).round(new MathContext(2,RoundingMode.HALF_UP));
    //return this.valorUnitario.divide(new BigDecimal(this.quantidade)).setScale(2,RoundingMode.HALF_UP);
    return valorUnitario;
}

public String getCnpjCliente() {
        return cnpjCliente;
}

public void setCnpjCliente(String cnpjCliente) {
        this.cnpjCliente = cnpjCliente;
}

public String getUsuarioSolicitante() {
        return usuarioSolicitante;
}

public void setUsuarioSolicitante(String usuarioSolicitante) {
        this.usuarioSolicitante = usuarioSolicitante;
}

public String getCodigoItem() {
        return codigoItem;
}

public void setCodigoItem(String codigoItem) {
        this.codigoItem = codigoItem;
}

public int getQuantidade() {
        return quantidade;
}

public void setQuantidade(int quantidade) {
        this.quantidade = quantidade;
        //this.valorUnitario = valorTotal.divide(new BigDecimal(this.quantidade)).setScale(2,RoundingMode.HALF_UP);
        this.valorUnitario = calculaValorUnitario();
}

}

package modelo;

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

public class Pedido {
private String cnpjCliente;
private String usuarioSolicitante;
private List itens = new ArrayList<>();
private BigDecimal valorTotal;

public BigDecimal getValorTotal() {
    //return valorTotal.round(new MathContext(2, RoundingMode.CEILING));
    //return valorTotal.setScale(2,RoundingMode.HALF_UP);
    return valorTotal;
}

public void setValorTotal(BigDecimal valorTotal) {
    this.valorTotal = valorTotal.setScale(2,RoundingMode.HALF_UP);
}

public String getCnpjCliente() {
        return cnpjCliente;
}

public void setCnpjCliente(String cnpjCliente) {
        this.cnpjCliente = cnpjCliente;
}

public String getUsuarioSolicitante() {
        return usuarioSolicitante;
}

public void setUsuarioSolicitante(String usuarioSolicitante) {
        this.usuarioSolicitante = usuarioSolicitante;
}

public List<ItemPedido> getItens() {
        return itens;
}

public void setItens(List<ItemPedido> itens) {
        this.itens = itens;
}

}

No ItemPedido, você criou mais uma variável (calculaValorUnitario), não necessário, e como ela nem foi inicializada vai dar erro. Usa o valorTotal no lugar.

[quote=A H Gusukuma]No ItemPedido, você criou mais uma variável (calculaValorUnitario), não necessário, e como ela nem foi inicializada vai dar erro. Usa o valorTotal no lugar.
[/quote]

Que burro, dá zero pra ele! rs…

Seguem as classes novamente amigo, e muito obrigado pela paciência até o momento. Está sendo muito complicado quebrar o paradigma de linguagens procedurais e entender orientação a objetos, mas com suas dicas e testes como este estou aprendendo com os erros.
Assim que concluir esta parte, irei para a 2ª e 3ª questão do teste, e pra ser bem sincero não sem nem como começar…

package modelo;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class ItemPedido {
private String cnpjCliente;
private String usuarioSolicitante;
private String codigoItem;
private int quantidade;
private BigDecimal valorTotal;
private BigDecimal valorUnitario;

private BigDecimal calculaValorUnitario() {
    return valorTotal.divide(new BigDecimal(this.quantidade)).setScale(2,RoundingMode.HALF_UP);
}
    
public BigDecimal getValorTotal() {
    //retur valorTotal.round(new MathContext(2, RoundingMode.CEILING));
    //return valorTotal.setScale(2,RoundingMode.HALF_UP);
    return valorTotal;
}

public void setValorTotal(BigDecimal valorTotal) {
    //this.valorTotal = valorTotal;
    this.valorTotal = valorTotal.setScale(2,RoundingMode.HALF_UP);
    //this.valorUnitario = valorTotal.divide(new BigDecimal(this.quantidade)).setScale(2,RoundingMode.HALF_UP);
    this.valorUnitario = calculaValorUnitario();
    
}

public BigDecimal getValorUnitario() {
    //return this.valorUnitario.divide(new BigDecimal(this.quantidade)).round(new MathContext(2,RoundingMode.HALF_UP));
    //return this.valorUnitario.divide(new BigDecimal(this.quantidade)).setScale(2,RoundingMode.HALF_UP);
    return valorUnitario;
}

public String getCnpjCliente() {
        return cnpjCliente;
}

public void setCnpjCliente(String cnpjCliente) {
        this.cnpjCliente = cnpjCliente;
}

public String getUsuarioSolicitante() {
        return usuarioSolicitante;
}

public void setUsuarioSolicitante(String usuarioSolicitante) {
        this.usuarioSolicitante = usuarioSolicitante;
}

public String getCodigoItem() {
        return codigoItem;
}

public void setCodigoItem(String codigoItem) {
        this.codigoItem = codigoItem;
}

public int getQuantidade() {
        return quantidade;
}

public void setQuantidade(int quantidade) {
        this.quantidade = quantidade;
        //this.valorUnitario = valorTotal.divide(new BigDecimal(this.quantidade)).setScale(2,RoundingMode.HALF_UP);
        this.valorUnitario = calculaValorUnitario();
}

}

package modelo;

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

public class Pedido {
private String cnpjCliente;
private String usuarioSolicitante;
private List itens = new ArrayList<>();
private BigDecimal valorTotal;

public BigDecimal getValorTotal() {
    //return valorTotal.round(new MathContext(2, RoundingMode.CEILING));
    //return valorTotal.setScale(2,RoundingMode.HALF_UP);
    return valorTotal;
}

public void setValorTotal(BigDecimal valorTotal) {
    this.valorTotal = valorTotal.setScale(2,RoundingMode.HALF_UP);
}

public String getCnpjCliente() {
        return cnpjCliente;
}

public void setCnpjCliente(String cnpjCliente) {
        this.cnpjCliente = cnpjCliente;
}

public String getUsuarioSolicitante() {
        return usuarioSolicitante;
}

public void setUsuarioSolicitante(String usuarioSolicitante) {
        this.usuarioSolicitante = usuarioSolicitante;
}

public List<ItemPedido> getItens() {
        return itens;
}

public void setItens(List<ItemPedido> itens) {
        this.itens = itens;
}

}

Pessoal, alguém mais poderia ajudar?

Olá, qual o material que está usando para estudar Java? Qual a linguagem que programa?
Pergunto isso para entender melhor as suas dificuldades e poder ajudar você encontrar a solução do problema.