O operador add da classe set retorna um booleano que é verdadeiro se o elemento (que deve ser adicionado) já não estava lá e falso caso contrário. Está escrevendo
if (set.add(entry)) {
//do some more stuff
}
considerado bom estilo em termos de escrita de código limpo? Eu estou pensando desde que você faz duas coisas ao mesmo tempo. 1) adicionando o elemento e 2) verificando se o elemento existia.
java
coding-style
clean-code
Andreas Braun
fonte
fonte
java.util.Set
, que retorna verdadeiroadd
quando o elemento já não estava lá, certo?if (!set.add(entry)) {// entry already present, possibly a case you want to handle}
Respostas:
Sim, ele é.
O ponto usual de uma operação retornar um valor booleano é que você pode usá-lo para tomar decisões, ou seja, dentro de uma
if
construção. A única outra maneira de realizar esse potencial seria armazenar o valor de retorno em uma variável e, em seguida, reutilizá-lo imediatamente em umif
, o que é simplesmente bobo e certamente não preferível à escritaif(operation()) { ... }
. Então vá em frente e faça isso, não vamos julgá-lo (por isso).fonte
Set.add
como operação única sem nomear uma alternativa. Se a operação pretendida for adicionar um único elemento e descobrir se foi adicionado, não há necessidade de uma alternativa mais poderosa que ainda complique a operação sem benefício. Espero que você esteja ciente de queSet.add
é um método JRE embutido que pode ser usado sem antes estudar um livro com mais de 700 páginas.Eu diria que não é o mais limpo possível, porque força o mantenedor a já saber ou procurar o que o valor de retorno significa. Isso significa que o valor já existia, não existia, foi inserido com sucesso? Se você não o usa muito, não saberá, e mesmo se o fizer, é muito mais carga mental.
Eu preferiria o seguinte:
Sim, um pouco mais detalhado, mas o compilador deve gerar exatamente o mesmo bytecode, e mesmo pessoas que não usam conjuntos de Java há anos podem seguir a lógica sem procurar nada.
fonte
add
retorna true se o elemento já não estava lá, não se estivesse. (Redação da pergunta é enganosa.)Set.add
, é inexperiente e deve procurar esses métodos para aprendê-los e se tornar mais experiente.notAlreadyPresent
não é a melhor expressão. Eu usariaadded
e espero que o leitor saiba por que um valor não seria adicionado a um Conjunto.Se verdadeiro significa sucesso, é um código bom e claro.
Existe uma convenção generalizada de que uma função ou método retorna true (ou algo que é avaliado como true) com êxito. Desde que seu código siga isso, acho que colocar o método na condicional é bom.
Código como este é desnecessariamente confuso na minha opinião:
Parece que você está se repetindo.
No entanto, a pergunta é ambígua sobre o significado do valor de retorno. Você diz "um booleano que indica se o elemento adicionado já existia", o que pode implicar que true significa que o elemento existia (e a adição não ocorreu). Se for esse o caso, eu idealmente mudaria o comportamento de retorno do método para ser mais convencional. Se isso não for possível, eu adicionaria uma variável intermediária extra que permite rotular claramente o resultado de retorno no seu código (conforme sugerido por outras pessoas).
fonte
false
significa que o elemento não foi adicionado porque já estava contido etrue
significa que o elemento ainda não estava contido. Comoadd()
adiciona o elemento ao conjunto, se o conjunto ainda não o contiver,true
significa que o elemento foi adicionado com êxito ao conjunto.add
bem-sucedido sem ter que fazer nada. Se o item ainda não estava no conjunto, será possíveladd
adicionar o item ao conjunto. Qual interpretação está correta é arbitrária. A definição menos arbitrária de sucesso é a da linguagem: o método será bem-sucedido se retornar normalmente.firstLessThanSecond(int l, int r)
e retornartrue
sel > r
oufalse
sel <= r
, esse método não será bem-sucedido, mesmo que retorne normalmente.add
é uma abreviação grave do contrato. A documentação começa com "Adiciona o elemento especificado a este conjunto, se ele ainda não estiver presente", que é satisfeito se o item já estava no conjunto ou não. Você é livre para interpretar o valor de retorno da maneira que desejar, mas, no final das contas, é apenas sua interpretação. E no seu segundo exemplo, o método avalia se uma condição é verdadeira. Se a condição for falsa, o método certamente não falhou, pois avaliou com êxito a condicional.Eu diria que é muito parecido com um C. Na maioria das vezes, eu preferiria ter uma variável com nome descritivo para um resultado de mutação e nenhuma mutação acontecendo em uma
if
condição.Um compilador eliminará essa variável se for reutilizada imediatamente. Um ser humano terá mais facilidade em ler a fonte; para mim, é mais importante.
Alguém deve estender a condição adicionando um
and
or
cláusula / à condição if, pode acabar não ligando.add()
em certos casos devido à avaliação de curto-circuito. A menos que o curto-circuito seja especificamente previsto, isso pode acabar como um bug.fonte
if (set.contains(entry)){set.add(entry); //do more stuff}
isso também será eliminado pelo compilador?contains
eadd
. Além disso, ele duplica o trabalho de procurarentry
no conjunto; isso pode desempenhar um papel para conjuntos muito grandes e loops muito leves.if (set.contains(entry)){set.add(entry); //do more stuff}
mas sim, por exemplo, com a resposta de Karl Bielefeldt?Seu código parece interromper a separação de consultas de comando . Isso é discutido no livro Código Limpo e no vídeo Estrutura da Função . Então, da perspectiva do Código Limpo, acho que não é considerado um bom estilo.
Para mim, a intenção do seu código não é clara. Os dois são executados quando a entrada é adicionada com êxito ou também quando ela já existe? O que
add()
retorna? o item? O código de erro?fonte
if (set.contains(entry)){set.add(entry); //do more stuff}
que parece meio bobo. Qual é a sua opinião sobre isso?Collection
API.