Eu tenho uma condição
if(exists && !isDirectory || !exists)
{}
como posso modificá-lo, para que seja mais compreensível.
existse isDirectorysão verdadeiras?
Eu tenho uma condição
if(exists && !isDirectory || !exists)
{}
como posso modificá-lo, para que seja mais compreensível.
existse isDirectorysão verdadeiras?
Respostas:
|| é comutativo, então
if(!exists || (exists && !isDirectory))
é equivalente.
Agora, porque existe sempre é verdade na segunda parte do, ||você pode soltar o &&:
if(!exists || !isDirectory)
Ou você pode dar um passo adiante e fazer:
if(!(exists && isDirectory))
&&tem maior precedência (pelo menos na maioria dos idiomas conhecidos - pode haver exceções) ||. Assim, a && b || cé equivalente a, (a && b) || cmas não a a && (b || c).
!exists || !isDirectoryé mais "compreensível", porque, isDirectorynão pode ser verdade se !exists. Então, como humano, diremos "se ele não existe ou se existe e não é um diretório".
||é comutativo apenas se usado em valores sem efeitos colaterais - se, por exemplo, usado com funções, algumas funções podem não ser chamadas (curto-circuito) ou retornar um valor diferente em uma ordem diferente.
Como processo, sugiro construir uma tabela de verdade:
e = exists
d = isDirectory
e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | 1
1 | 0 | 1
1 | 1 | 0
Isso corresponde à NANDoperação , que é simplesmente:
!(exists && isDirectory)
Se você não se lembra de todos os seus portais lógicos, a wikipedia tem uma boa referência com as tabelas da verdade para inicializar .
@Christoffer Hammarström levantou um ponto importante sobre o estado de isDirectoryamarração ao estado de exists. Supondo que eles se refiram à mesma referência e que não é possível ter um estado em que a referência não exista e seja um diretório, a tabela verdade pode ser escrita da seguinte maneira:
e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | n/a
1 | 0 | 1
1 | 1 | 0
O n/aé usado para representar um estado que não importa. Reduções aceitáveis podem resultar em um 1ou 0para os estados que resultam em n/a.
Com isso em mente, !(exists && isDirectory)ainda é uma redução válida, resultando em um 1para !e && d.
No entanto, !isDirectoryseria uma redução muito mais simples, resultando em 0para !e && d.
isDirectorydepende exists. Não pode ser um diretório e não existir.
n/aem locais onde o estado é impossível de alcançar e a equação reduzida em conformidade.
Para melhor legibilidade, eu gosto de extrair condições booleanas para métodos:
if(fileNameUnused())
{...}
public boolean fileNameUnused() {
return exists && !isDirectory || !exists;
}
Ou com um nome de método melhor. Se você pode nomear esse método corretamente, o leitor do seu código não precisa descobrir o que significa a condição booleana.
boolean fileNameUnused = !exists || !isDirectory; if (fileNameUnused) { doSomething(); }
Você pode apenas tentar acertar o caso de não-ir e sair se isso aparecer.
while(someCondition) {
if(exists && isDirectory)
continue;
// maybe "break", depends on what you're after.
// the rest of the code
}
ou mesmo
function processFile(someFile)
{
// ...
if(exists && isDirectory)
return false;
// the rest of the code
// ...
}
Você pode usar uma tabela verdade, conforme indicado. O segundo passo pode ser um mapa KV para minimizar o número de termos.
Usar as leis da álgebra booleana é outra abordagem:
A = existe
B =! IsDirectory
! A =! Existe
&& = *
|| = +
[Editar]
Uma transformação mais simples, porque as operações AND e OR são mutuamente distributivas:
existe o &&! isDirectory || ! existe
= A * B +! A
= (A +! A) * (B +! A)
= 1 * (B +! A)
= B +! A
[/ Edit]
existe o &&! isDirectory || ! existe
= A * B +! A
= A * B +! A * 1 // Identidade
= A * B +! A * (B + 1) // Annihilator
= A * B +! A * B +! A / / Distribuutividade e identidade
= B * (A +! A) +! A // Distributividade
= B * 1 +! A // Complementação 2
= B +! A // Identidade
=! IsDirectory || !existe
Ou com complemento duplo (!! x = x):
A * B +! A
= !! (A * B +! A)
=! (! (A * B) * A)
=! ((! A +! B) * A)
=! (! A * A + ! B * A)
=! (0 +! B * A)
=! (! B * A)
= B +! A
=! IsDirectory || !existe
Eu não gosto de usar "!" quando houver mais de uma condição na expressão. Vou adicionar linhas de código para torná-lo mais legível.
doesNotExist = !exists;
isFile = exists && !isDirecotry;
if (isFile || doesNotExist)
{}
Conforme indicado anteriormente, a condição pode ser reduzida para:
if (!(exists && isDirectory))
No entanto, aposto que ser um diretório implica existência. Nesse caso, podemos reduzir a condição para:
if (!isDirectory)