If dentro do for

como faço para evitar o if dentro do for?

por exemplo eu tenho um carrinho cheio de itens… e esse item tem preço e quantidade

ai eu crio um totalizador, faço um for varrendo o carrinho inteiro e calculando…
valorTotal += pedido.getValorLiquido() == null ? 0L : pedido.getValorLiquido();

obs.: nesse caso eu preciso verificar se não é null… pois são pedidos importados de outro sistema e pode vim null… infelizmente não tem como colocar 9

Qual é o seu preconceito com o if dentro do for?

Cuidado com o Estatuto da Igualdade Racial, que ele está em vigor faz 2 anos há :slight_smile:

Não há problemas em ter um if dentro do for.

não tenho preconceito com nada… só acho que fica um código feio…

Ouvi dizer que isso atrasa o pipeline, parece que ele para a instrução pois não sabe se vai cair no if ou no else… sei lá, não tenho muita informação sobre o assunto, acho que seria um assunto legal a ser discutido…

[quote=entanglement]Qual é o seu preconceito com o if dentro do for?

Cuidado com o Estatuto da Igualdade Racial, que ele está em vigor faz 2 anos há :slight_smile:

Não há problemas em ter um if dentro do for. [/quote]

Concordo, não vejo problemas em ter if dentro do for, muitas vezes é inevitável.

[quote=alandiniz]não tenho preconceito com nada… só acho que fica um código feio…

Ouvi dizer que isso atrasa o pipeline, parece que ele para a instrução pois não sabe se vai cair no if ou no else… sei lá, não tenho muita informação sobre o assunto, acho que seria um assunto legal a ser discutido… [/quote]

Acho que você precisa primeiramente se preocupar se o código está certo, e depois se a pipeline fica “stalled” ou não devido a um erro de previsão do “branch predictor” do processador.

Na verdade, não é um “if” a mais ou a menos que vai fazer diferença.

Eu já percebi que em Java esse tipo de efeito é desprezível.

Faz mais diferença, em termos de “cache evictions” e outras coisas mais chatas, se seu código é bem ou mal estruturado.

Código do tipo “linguição”, cheio de código “copy & paste”, tende a ocupar mais bytecodes, que são traduzidos para mais código binário, que por sua vez acabam ocupando mais espaço em cache de código no processador. Mas como o tamanho do cache varia de processador para processador, o que é ótimo em um processador pode não ser em outro.

[quote=alandiniz]como faço para evitar o if dentro do for?

por exemplo eu tenho um carrinho cheio de itens… e esse item tem preço e quantidade

ai eu crio um totalizador, faço um for varrendo o carrinho inteiro e calculando…
valorTotal += pedido.getValorLiquido() == null ? 0L : pedido.getValorLiquido();

obs.: nesse caso eu preciso verificar se não é null… pois são pedidos importados de outro sistema e pode vim null… infelizmente não tem como colocar 9[/quote]

Se o objeto pedido é de outro sistema, realmente não tem o que fazer. É por isso que vc nunca deve usar um objeto de outro sistema que vc não controla no seu sistema (Isolamento). Então, neste cenário uma opção é modificar o ponto onde vc recebe o pedido e usar uma classe sua. Ai, como a classe é sua, vc terá que copiar da outra, durante a copia vc faz o if de null. Tudo bem que é o mesmo if, no mesmo for, mas é feito apenas uma vez. A partir dai vc usa o seu objeto que já tem a regra certa.

Outra opção é não copiar o objeto, mas criar um decorador. Isso possibilita que vc reimplemente o método “getValorLiquido” para retornar sempre um objeto e nunca null.
Tudo bem que é o mesmo if, mas está encapsulado. A diferença é que vc realiza o if uma vez, preservando o resultado após o primeiro if. algo assim
( o decorator pode ser feito automaticamente no eclipse)


public PedidoDecorator extends Pedido {
        
       private Pedido original; 
       private Double valor = Double.valueOf(0) ;

        public PedidoDecorator  (Pedido original){
                  this.original = original;

                  if ( original.getValorLiquido() != null){
                        this.valor =original.getValorLiquido();
                  }
         }

   /// etc.. o resto dos métodos

        public Double getValorLiquido () {
            return valor;

        }

}

Assim vc muda na contrução e não no for. Também seria relevante o quanto esse for se repete no sistema.
Se o pedido é do seu sistema, inicie a variável com zero e no set não permita null. Se for passaod null, reseta para zero.

Fora isso, não ha como.
O if dentro do for é ruim de fato e seria melhor não precisar dele, mas vc pode agradecer à incompetencia do programador que teve a ideia de enviar null num Double.

Muito obrigado Sérgio e entanglement;

Realmente muitas vezes não temos como fugir do famoso if… mais podemos usar ele uma vez;

Hum? Muitas vezes você não pode retornar um “double” simples e sim um Double (podendo este assumir o valor de null) porque o problema pede explicitamente isso.

E é por isso que em .NET existe o tipo “double?” (abreviatura de Nullable<System.Double> ) justamente para levar esse caso em conta.

Por exemplo, em uma planilha Excel você pode ter números faltando (nesse caso é o “null”) e números zero.

Na hora de calcular a média desses números, você ter algo que retorna 0 para indicar um número faltando é um erro.

o problema é que já vem de software de terceiros com null

este é só mais um caso

Hum? Muitas vezes você não pode retornar um “double” simples e sim um Double (podendo este assumir o valor de null) porque o problema pede explicitamente isso.

E é por isso que em .NET existe o tipo “double?” (abreviatura de Nullable<System.Double> ) justamente para levar esse caso em conta.

Por exemplo, em uma planilha Excel você pode ter números faltando (nesse caso é o “null”) e números zero.

Na hora de calcular a média desses números, você ter algo que retorna 0 para indicar um número faltando é um erro. [/quote]

fico mt grato pela sua explanação.

é sério!

Estava lendo os posts, e qdo cheguei nesse “quoted”, me senti um pouco deprimido, pelo fato de ja ter usado a abordagem de retornar null, justamente pra não retornar um “falso Zero”.

mas logo recuperei minha auto estima.

e sobre a questão estética. acho q ternário ficou até bonitinho.

Uma vez caímos em uma discussão aqui no trabalho se daria para se programar sem um único if no código.
Até dá, mas o esforço não compensa.

Eu acho que o código deve seguir a especificação.

Se a especificação estiver em forma de uma tabela de casos, por exemplo (o que não é incomum), é melhor ter isso representado o mais parecido possível dentro do código, para que seja fácil bater a especificação com a codificação.

olha até da, mas acho que se alguem fizer isso, merece parar no tdwtf

for(objeto obj: lista)
{
 try
 {
   soma += obj.getInt();
 }
 catch (NullPointerException e){}
}

Lindo não ?

[quote=alandiniz]não tenho preconceito com nada… só acho que fica um código feio…

Ouvi dizer que isso atrasa o pipeline, parece que ele para a instrução pois não sabe se vai cair no if ou no else… sei lá, não tenho muita informação sobre o assunto, acho que seria um assunto legal a ser discutido… [/quote]

Não existe influência nenhuma. O que faz o programa correr rápido é ele possuir menor número de instruções.

Isso é um mito descarado:

Atring s = x==z? "a" : "b";

gera o mesmo bytecode

if(x==z){ s = "a"; }else{ s="b; }

Dá uma lida nesse artigo. O autor acredita também que o jit pode otimizar o ternário melhor que o if else…mas os bytecodes são iguais. Se são iguais não existe segredo.

http://www.enigmastation.com/2010/03/26/java-surgery-ifsnull-st-vs-ssnullts/

Hum? Muitas vezes você não pode retornar um “double” simples e sim um Double (podendo este assumir o valor de null) porque o problema pede explicitamente isso.

E é por isso que em .NET existe o tipo “double?” (abreviatura de Nullable<System.Double> ) justamente para levar esse caso em conta.

Por exemplo, em uma planilha Excel você pode ter números faltando (nesse caso é o “null”) e números zero.

Na hora de calcular a média desses números, você ter algo que retorna 0 para indicar um número faltando é um erro. [/quote]

fico mt grato pela sua explanação.

é sério!

Estava lendo os posts, e qdo cheguei nesse “quoted”, me senti um pouco deprimido, pelo fato de ja ter usado a abordagem de retornar null, justamente pra não retornar um “falso Zero”.

mas logo recuperei minha auto estima.

e sobre a questão estética. acho q ternário ficou até bonitinho.[/quote]

Bom, vcs os dois podem se continuar enganando e afagando vosso ego achando que é certo que um numero possa ser null quando é usando em contas. Eu perfiro não cometer esse erro.

Existem várias opções para tratar isto. Desde usar default value até não usar Double e sim um Value Object proprio para tratar casos especiais. (Se o cara colocar NaN na importação, vc aceita? Não né ?)

Não existe essa de “falso zero” . Se o campo é esperado intervir em um calculo ele deve existir. Caso contrário um valor deve ser atribuido quando ele não existe ou não está disponivel. O fato do banco gravar null, não significa que a entidade tem que entender null quando fizer as contas (por isso o value object próprio tem vantagens porque vc pode condificar uma instancia no padrão NullObject e fazer com que as operações matemáticas saibam trabalhar com estte valor.

Portanto, o fato de usar Double porque a info vem do banco ou de outro sistema que permite nulls apenas porque double não aceita terceiro estado não é razão o bastante. Se vc criou o sistema, se vc definiu o campo, vc não deveria ter usado Double ou não deveria ter deixado ser null. E mais, em questões de dinheiro todo o mundo sabe ( ou deveria saber, afinal não estamos mais nos anos 80) que usar double/Double para representar dinheiro é fria. É por isso que existe o padrão Money.

Para quem ainda tem dúvidas, pesquise sobre Tiny Types e Strong Typing. É sempre melhor vc controlar objetos e não null (afinal é Orientação a Objetos , não Orientação a Referencias Nulas).

O ternário é um operação útil, mas cada vez que é usado tem algo errado no design. Foi citado o .NET, então vamos citar o Scala e o seu Optional. Repare-se que o conceito de “não tem valor” continua lá , mas sempre usando uma instancia de um objeto e nunca deixando a referencia vazia. Linguagens mais modernas como Kotlin vão mais longe proibindo qualquer uso de null. Porque NullPointerException é simplesmente a exceção mais lançada. E a maior parte das vezes por erro de design.

Se fosse algum outro valor que não fosse usando em calculos (mas vai dai provavelmente não seria Double) podemos até ser mais linientes, mas quando o campo é um dinheiro, ainda por cima um total ?! ora, isso é obviamente um erro de design. O uso da palavra “incompetência” é proposital para despertar este tipo de reação do GilsonNunes. Vamos deixar de passar a mão na cabeça e dizer que está certo porque a microsoft faz. Estamos em outro século. Está errado e é bom que todos saibam. Só assim poderão fazer melhor.

sergiotaborda, eu só comentei pq achei mt leviana sua afirmação de q seria culpa da incompetência de alguem q implementou o outro sistema.

seria como o fato de um a info q veio null do DB e causasse uma nullpointerexception, fosse culpa de quem implementou o SGDB.

imagine um código assim:

BufferedReader br = new BufferedReader(in); String line = br.readLine() if (line.Equals("teste")){ System.out.println("Is Teste"); }

o fato de o line poder ser null, é um erro do BufferedReader?
ou do programador q não entendeu q null, nesse caso, é a maneira de de dizer q não tinha mais info?

Ponha a culpa no inventor do Quicksort. Até hoje estamos limpando a sujeira que ele deixou :slight_smile:

Ninguém é dono da verdade absoluta. Já tive casos de relatórios em que tinha valores com 0 e valores a null e o seu significado era diferente. Os 0 deveriam aparecer no relatório, os null não.

Engraçado quanta indignação futil. Eu não disse que null é o fim do mundo. Nem que null não tem a sua utilidade. Eu disse que é perigoso e deve ser evitado sempre que possivel, especialmente quando usando Double , especialmente quando usando para campos totalizadores, que o caso em epígrafe.

É totalmente desprovido de propósito ficar argumentando que não é um erro de design devolver null num campo numérico totalizador utilizando em algoritmos de calculo. O fato de ser perdoável, o fato de outros fazerem, o fato de ser possivel … nada disso significa que deve ser feito. E nada disto invalida o uso de null em outros lugares para outros fins. Dicutir o contrato do BufferedReader como sendo errado porque devolve null é sem propósito e demonstra a futilidade da analise sendo feita. Existem muito boas razões porque o readLine devolve null. Existem boas razões porque um campo numérico totalizador é nulo ? Não.

Não tentem por tudo no mesmo saco. E não precisam defender o cara que criou o código porque vcs nem o conhecem.
Quem quiser continuar usando null em campos numérico, continue. Mas não se venham queixar depois.
Quem já entendeu que isso é um erro, excelente. Era só isso o meu objetivo.