【问题标题】:Linked List Cycle Potential Exception链表循环潜在异常
【发布时间】:2017-08-19 02:17:51
【问题描述】:

下面是检测链表是否包含循环的代码:

  public static boolean containsCycle(LinkedListNode firstNode) {

// start both runners at the beginning
LinkedListNode slowRunner = firstNode;
LinkedListNode fastRunner = firstNode;

// until we hit the end of the list
while (fastRunner != null && fastRunner.next != null) {
    slowRunner = slowRunner.next;
    fastRunner = fastRunner.next.next;

    // case: fastRunner is about to "lap" slowRunner
    if (fastRunner == slowRunner) {
        return true;
    }
}

// case: fastRunner hit the end of the list
return false;

while循环的条件不应该是fastRunner != null && fastRunner.next.NEXT!= null吗?以目前的代码,fastRunner可以是链表中的最后一个节点,所以一旦进入while循环,最后一个节点的下一个节点就会导致异常。

【问题讨论】:

    标签: java linked-list nodes


    【解决方案1】:

    使用当前代码,fastRunner 可以是链表中的最后一个节点

    fastRunner 不能是链表中的最后一个节点,因为您的 while 循环

    while (fastRunner != null && fastRunner.next != null) {
    

    检查fastRunner 不是最后一个元素(因为fastRunner.next == null 意味着fastRunner 是最后一个元素)。你循环中的这个任务

    fastRunner = fastRunner.next.next;
    

    当然可以将fastRunner 设置为null,但是你没有对它做任何会导致空指针异常的事情,并且while 循环的下一次迭代将退出(从现在开始fastRunner == null

    【讨论】:

      【解决方案2】:

      这个算法当然是正确的,前提是线程安全不是问题。 换句话说,如果在此方法运行时列表被另一个线程中的代码更改,那么它肯定会产生不正确的结果或NullPointerException

      但是,如果您的代码是单线程的,那么NullPointerException 永远不会发生。要让这段代码抛出NullPointerException,必须有一个. 运算符,其左侧有一个空值。尽管还有其他类型的代码可以抛出NullPointerException,例如自动拆箱空值,以及在 for-each 循环中使用空参数;你没有这些。

      所以要看到这段代码可以抛出NullPointerException,您应该依次考虑代码中的每个. 运算符。有四个点需要考虑。

      1. while (fastRunner != null && fastRunner.next != null) { 中的点 - 这永远不会导致 NullPointerException,因为只有在 fastRunner 不为空时才会检查此代码,这要归功于短路评估。
      2. slowRunner = slowRunner.next; 中的点 - 这永远不会导致 NullPointerException,因为 slowRunner 采用的每个值都已被 fastRunnerfastRunner.next 采用。因此,如果slowRunner 为空,您将已经获得NullPointerException。你无法从这个点得到它。
      3. fastRunner = fastRunner.next.next; 中的第一个点 - 这永远不会导致 NullPointerException,因为您已经检查过 fastRunner 不为空。
      4. fastRunner = fastRunner.next.next; 中的第二个点 - 这永远不会导致 NullPointerException,因为您已经检查过 fastRunner.next 不为空。

      因此,您的代码中没有一点可能导致NullPointerException,除非在代码执行时列表被第二个线程更改。

      【讨论】:

        猜你喜欢
        • 2012-06-15
        • 1970-01-01
        • 1970-01-01
        • 2014-06-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多