Else 被简单地跳过,但只是有时

Else is simply skipped, but only sometimes

private int bkicalc(int i, List<Integer> history) {

    List<Integer> subList = history.subList(history.size()-1 - i, history.size()-1);
    Set<Integer> uniliste = new HashSet<Integer>(subList);
    
    if (uniliste.size() == 4) {
        if (i>5) {
            System.out.println(i);
        }
        return i;
    } else {
        this.bkicalc(i + 1, history);
    }
    
       System.out.println("else was skipped");
    return 404;

}

您好,这个方法在 for 循环中被访问了 1000 次,其中有 1/10 的次数跳过了 else 和 returns 404。我无法向自己解释为什么会这样。

希望你能帮帮我。

您 return 来自 if 分支,但不是 else 分支。因此,诊断和 404 return 并不表示 else 被跳过,而是 采取 else 分支递归是无关紧要的:除非从递归调用中抛出异常,否则该调用最终将 return,此时控制只是从 else 块中传递出来。

看起来您可能希望在 else 分支中 return 递归调用的结果:

private int bkicalc(int i, List<Integer> history) {

    List<Integer> subList = history.subList(history.size()-1 - i, history.size()-1);
    Set<Integer> uniliste = new HashSet<Integer>(subList);
    
    if (uniliste.size() == 4) {
        if (i>5) {
            System.out.println(i);
        }
        return i;
    } else {
        return this.bkicalc(i + 1, history);  // <-- here
    }
    
    assert false : "unreachable";
    return 404;
}

您甚至可能会发现编译器实际上将 return 404 标记为无法访问。

另请注意,您的子列表的范围有点令人惊讶。提供给 List.subList() 的上限是 exclusive,不包含在内,因此您一直在考虑中忽略 history 的最后一个元素。如果这是故意的,那么添加一个代码注释是明智的。

此外,如果 history 实际上总体上不包含至少 4 个不同的元素,那么在一定数量的递归之后,此方法将失败并返回 IndexOutOfBoundsException。如果它最初不包含至少 5 个元素(记住一个被忽略),这当然肯定会发生。

最后,递归似乎很浪费,而且造成了不必要的混乱。出于各种原因,迭代方法会更好。 (几乎总是如此。)示例:

private int bkicalc(int i, List<Integer> history) {
    if (history.size() >= 5) {
        Set<Integer> uniliste = new HashSet<Integer>(
                history.subList(history.size() - 5, history.size() - 1));
        ListIterator<Integer> iterator = history.listIterator(history.size() - 5);

        while (uniliste.size() < 4 && iterator.hasPrevious()) {
            uniliste.add(iterator.previous());
        }

        if (uniliste.size() == 4) {
            int i = history.size() - 1 - iterator.nextIndex();

            if (i > 5) {
                System.out.println(i);
            }
            return i;
        }
    }

    // Fewer than 4 distinct elements (ignoring the last)
    return -1;
}