例如,在下面的函数中,它向BST添加了一个节点,我只使用了隐式引用。 我可以在函数开始时明确声明一个变量TreenNode node = ..并在适当的地方使用它。现在,我不知道它是否基于意见。真诚地有任何使用OPTION1优于OPTION2
的优点或缺点OPTION1:
public void add(int item) {
if (root == null) {
root = new TreeNode(null, item, null);
return;
}
TreeNode node = root;
while (true) {
if (item < node.item) {
if (node.left == null) {
node.left = new TreeNode(null, item, null);
break;
}
node = node.left;
} else {
if (node.right == null) {
node.right = new TreeNode(null, item, null);
break;
}
node = node.right;
}
}
}
选项2:
public void add(int item) {
TreeNode nodeNew = new TreeNode(null, item, null); // explicit
if (root == null) {
root = nodeNew;
return;
}
TreeNode node = root;
while (true) {
if (item < node.item) {
if (node.left == null) {
node.left = nodeNew;
break;
}
node = node.left;
} else {
if (node.right == null) {
node.right = nodeNew;
break;
}
node = node.right;
}
}
}
答案 0 :(得分:1)
选项1更加优化,因为它涉及更少的步骤。 选项2意味着您创建一个包含引用的变量,仅使用它来分配 - 它对某些人来说可能看起来更好。在选项1中,您跳过临时引用并直接创建赋值和对象。
然而,在一天结束时,没有其他区别。
此外,在选项2中,最好将nodeNew的声明移到返回值之下。
如果你不使用它,为什么要初始化。
if (root == null) {
root = node;
return;
}
TreeNode nodeNew = new TreeNode(null, item, null); // explicit
答案 1 :(得分:1)
首先,我认为选项2中的行root = node;
,您可能打算将其作为:root = nodeNew;
,是吗?
我认为有一个潜在的好处,因为在option2中引用nodeNew
的任何地方,它都在条件内,所以它可能永远不会被使用。在这种情况下,option1的优点是只在需要时实例化一个新的TreeNode
对象。
但是,在这种特殊情况下,看起来每次调用此add
方法总是需要创建一个新的TreeNode
- 如果不是在初始条件下,那么在while循环的某个迭代中;所以在这种情况下,我在这方面看不到真正的效率优势。
可能值得思考的一个方面(并与其他可能在您的代码上工作的人交谈)是它的可维护性。在这种情况下,我看到了option1的潜在优势和潜在劣势。也许这些情况不适用于您提供的具体示例,但可能适用于此问题适用的其他人:
潜在优势:
如果这是一段很长的代码,那么在创建新TreeNode的所有点上总是很清楚,它实际上是一个正在创建的TreeNode对象(而不是,例如,某些派生),以及什么参数传递给它的构造函数。
潜在的劣势:
如果它永远不会被子类化,并且此方法中的所有实例化都将被赋予完全相同的参数,则option2具有一个需要进行更改的位置(例如,更改其中一个参数)的好处。