下面是一个简单的bfs代码
private void bfsTraveral() {
if (root == null) {
throw new NullPointerException("The root cannot be null.");
}
Queue<TreeNode> queue = new LinkedList<>();
Queue<TreeNode> queueNext = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
TreeNode node = queue.poll();
System.out.println(node.element);
if (node.left != null) queueNext.add(node.left);
if (node.right != null) queueNext.add(node.right);
if (queue.isEmpty()) {
queue = queueNext;
queueNext = new LinkedList<>();
}
}
}
我的问题是关于队列为空时处理的代码片段。
它创建一个新队列 queueNext = new LinkedList<>();
。
我的问题是 - 交换而不是创建新对象是个好习惯吗?如果是的话为什么?请注意,在上面的代码中,GC 应该处理空引用,并且我们不会泄漏内存。
替换代码:
if (queue.isEmpty()) {
Queue temp = queue;
queue = queueNext;
queueNext = temp;
}
最佳答案
在我看来,答案取决于应用程序的上下文。问题中没有足够的上下文,无法为您提供 100% 的答案。
在您的示例中,创建新队列比交换队列更具可读性和可维护性。对于刚接触代码的人(或者如果您几个月后才查看它),更容易理解您正在从头开始使用新队列,而不是必须弄清楚您正在使用队列临时交换执行什么操作-罗。如果您对垃圾收集、内存泄漏等有信心,并且性能(内存或速度)不是问题,那么我会创建一个新队列。
另一方面,如果性能是一个问题,那么您可以使用交换。这对于内存有限和/或实时性能要求非常高的平台尤其重要,因为内存碎片可能会影响速度。例如,在传统的游戏开发中,内存使用非常宝贵,因此通常会看到对象的巧妙重用,而不是对象的创建/销毁。例如,游戏实体通常是从预先分配的池中初始化的。或者可以使用环形缓冲区,而不是动态创建/销毁新缓冲区。在您的示例中,您可以预先分配一定大小的队列(即预先建立稳定的内存占用量),然后在遍历中操作它们。
希望有帮助!
关于java - 交换或创建新的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24790507/