根据Coursera上的Algorithms, Part 1,我在Java上编写Deque
课程。目前我的基于数组的Deque
方法removeLast()
:
public Item removeLast() {
if (size() == array.length / 4) {
resize(array.length / 2);
}
if (head != tail) {
Item tmp = array[--head];
array[head] = null;
return tmp;
}
throw new NoSuchElementException("Stack underflow");
}
如果head == tail
表示Deque
为空,我根据作业规范抛出异常,在方法结束而不是return
语句。此代码直接关注不变量(head != tail
)。
另一方面,方法可以像这样重写:
public Item removeLastRewritten() {
if (size() == array.length / 4) {
resize(array.length / 2);
}
if (head == tail) {
throw new NoSuchElementException("Stack underflow");
}
Item tmp = array[--head];
array[head] = null;
return tmp;
}
在我看来removeLast
更清楚地写出了这些原因:
always fail, only if ...
这是更可靠的方法,特别是当方法代码会扩大并变得更加复杂时。tail != head
和后续if {}
代码块之间提供更清晰的链接。我有以下问题:
removeLast
?答案 0 :(得分:2)
没有错误的答案。在GrepCode中,您可以找到您提出的每种口味:
E java.util.PriorityQueue.next()
public E More ...next() {
if (... != ...)
throw new ConcurrentModificationException();
...
if (...) {
return lastRetElt;
}
throw new NoSuchElementException();
}
E org.fluentlenium.core.domain.FluentList.first()
public E More ...first() {
if (this.size() == 0) {
throw new NoSuchElementException("Element not found");
}
return this.get(0);
}
答案 1 :(得分:1)
它看起来很奇怪的原因是因为你省略了>
块的else
块,它会包含两个方法中if
块之后的剩余块。你可以在这里摆脱它的原因是因为抛出的异常会破坏你方法的流程。
我认为最好不要依赖它,只是做得很好并直观地使用if
块。
if-else
我不喜欢在方法结束之前抛出异常的另一个原因是我坚信并因此彻底使用public Item removeLastRewrittenAgain() {
if (size() == array.length / 4) {
resize(array.length / 2);
}
if (head != tail) { // invert the if-else block if preferred, it would not make any difference
Item tmp = array[--head];
array[head] = null;
return tmp;
} else {
throw new NoSuchElementException("Stack underflow");
}
}
的概念,这意味着我不会离开我觉得中间某处的方法对于不熟悉代码的人来说更难阅读。
返回您的价值的一个地方(或抛出的例外):您方法的最底层。
答案 2 :(得分:1)
如果您明确提及private static bool FilesPresent()
{
IEnumerable<string> dirs = Directory.EnumerateDirectories(dataFileDirectoryPath, "*.*", SearchOption.TopDirectoryOnly);
return dirs.Any(d => Directory.EnumerateFiles(d, "*.*", SearchOption.AllDirectories).Any());
}
,则无论您的选择如何,您的代码都会变得更具可读性。
然后是
的困境else
与
if (head != tail) {
Item tmp = array[--head];
array[head] = null;
return tmp;
} else {
throw new NoSuchElementException("Stack underflow");
}
在这里,我非常喜欢第二个。当我正在阅读if语句的“复杂部分”时,我想知道为什么我实际上在if (head == tail) {
throw new NoSuchElementException("Stack underflow");
} else {
Item tmp = array[--head];
array[head] = null;
return tmp;
}
内。在阅读第一个变体时,只有当你抛出异常时,if的全部原因才会变得明显。
我想你也可以通过写
来解决这个问题if
但我更喜欢一旦你知道错误就抛出异常的版本。