我有病
if(exists && !isDirectory || !exists)
{}
我该如何修改它,以便使其更容易理解。
exists
且isDirectory
都为真怎么办?
我有病
if(exists && !isDirectory || !exists)
{}
我该如何修改它,以便使其更容易理解。
exists
且isDirectory
都为真怎么办?
Answers:
||
是可交换的
if(!exists || (exists && !isDirectory))
是等效的。
现在,因为存在在第二部分中始终为真,||
您可以删除&&
:
if(!exists || !isDirectory)
或者,您可以进一步执行以下操作:
if(!(exists && isDirectory))
&&
它的优先级更高(至少在大多数众所周知的语言中,可能会有例外)||
。因此a && b || c
等同于(a && b) || c
但不等同于a && (b || c)
。
!exists || !isDirectory
更“可以理解”,因为isDirectory
if不能成立!exists
。因此,作为一个人类,我们将说“如果它不存在或[存在并且它]不是目录”。
||
仅在用于无副作用的值上时才是可交换的-例如,如果与函数一起使用,则某些函数可能不会被调用(短路)或以不同的顺序返回不同的值。
作为一个过程,我建议建立一个真值表:
e = exists
d = isDirectory
e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | 1
1 | 0 | 1
1 | 1 | 0
!(exists && isDirectory)
如果您不记得所有的逻辑门,那么Wikipedia可以很好地引用要启动的真值表。
@ChristofferHammarström提出了关于isDirectory
被捆绑到的状态的重要观点exists
。假设它们引用相同的引用,并且不可能具有该引用不存在且为目录的状态,则真值表可以编写如下:
e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | n/a
1 | 0 | 1
1 | 1 | 0
将n/a
被用于表示没关系的状态。可接受的减少可能导致1
或0
导致的状态n/a
。
考虑到这一点,!(exists && isDirectory)
仍然是有效的减少,导致1
为!e && d
。
但是,!isDirectory
这将是一个简单得多的减少,导致0
为!e && d
。
isDirectory
依赖exists
。它既不能是目录,也不能存在。
n/a
在无法实现状态的位置,并且方程式相应减少。
为了提高可读性,我喜欢将布尔条件提取到方法中:
if(fileNameUnused())
{...}
public boolean fileNameUnused() {
return exists && !isDirectory || !exists;
}
或使用更好的方法名称。如果可以正确地命名此方法,则代码的阅读者无需弄清楚布尔条件的含义。
boolean fileNameUnused = !exists || !isDirectory; if (fileNameUnused) { doSomething(); }
你可以只尝试钉不走的情况和解救如果出现。
while(someCondition) {
if(exists && isDirectory)
continue;
// maybe "break", depends on what you're after.
// the rest of the code
}
甚至
function processFile(someFile)
{
// ...
if(exists && isDirectory)
return false;
// the rest of the code
// ...
}
您可以使用所指出的真值表。第二步可能是用于最小化术语数量的KV地图。
使用布尔代数定律是另一种方法:
A =存在
B =!isDirectory
!A =!存在
&& = *
|| = +
[编辑]
一个更简单的转换,因为操作AND和OR是相互分配的:
存在&&!isDirectory || !exists
= A * B +!A
=(A +!A)*(B +!A)
= 1 *(B +!A)
= B +!A
[/编辑]
存在&&!isDirectory || !exists
= A * B +!A
= A * B +!A * 1 //身份
= A * B +!A *(B + 1)//歼灭者
= A * B +!A * B +!A / /分配和标识
= B *(A +!A)+!A //分配
= B * 1 +!A //补码2
= B +!A //标识
=!isDirectory || 存在
或使用双补码(!! 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 || 存在
我不喜欢使用“!” 当表达式中有多个条件时。我将添加代码行以使其更具可读性。
doesNotExist = !exists;
isFile = exists && !isDirecotry;
if (isFile || doesNotExist)
{}