break 语句的控制流如何在嵌套循环中工作? (Java)

How does the control flow for break statements work in nested loops? (Java)

我已经在 Java 中编程了一段时间,但是我今天 运行 做了一些我认为很奇怪的事情。我记得当在嵌套循环中使用 break 语句时,控制流 returns 到外循环的 header 。如此图所示。

Control Flow Diagram(我知道你们喜欢内联,但根据声誉要求我不允许)

也许这张图和我的记忆有误。我这样说是因为当我 运行 以下代码时,控制流将每个标记添加到 LinkedList listOfAllPalindromes。我已经验证包含 break 语句的 if-block 正在按预期访问。所以简而言之,我的记忆有误吗,当它遇到 break 语句时,控制流是否应该像它看起来那样跳转到 listOfAllPalindromes.add(token)?

 public static void main(String[] args) throws FileNotFoundException {

    File dictionary = new File("english3.txt");
    Scanner s = new Scanner(dictionary);
    String token;
    LinkedList<String> listOfPalindromes = new LinkedList<>();

    while (s.hasNext())
    {
        token = s.next().toLowerCase();

        for (int i = 0; i <= (token.length()-1)/2; i++)
        {
            if(token.charAt(i) != token.charAt(token.length()-(i+1)))
            {
                break;
            }
        }
        
        listOfPalindromes.add(token);
    }

    for(String word : listOfPalindromes)
    {
        System.out.println(word);
    }
}

为循环使用标签以更好地理解循环的控制流。

它应该在遇到 break 语句时跳出 for 循环

来自jls-14.15

A break statement with no label attempts to transfer control to the innermost enclosing switch, while, do, or for statement; this enclosing statement, which is called the break target, then immediately completes normally.

因此,回答您的问题 break 语句将中断您的 for 循环,并且将执行 listOfPalindromes.add(token) 行。

您可以使用其他方法解决您的问题,检查是否为回文,然后从您的第一个循环中触发此方法。 示例:

public static void main(String[] args) throws FileNotFoundException {

    File dictionary = new File("english3.txt");
    Scanner s = new Scanner(dictionary);
    String token;
    LinkedList<String> listOfPalindromes = new LinkedList<>();

    while (s.hasNext())
    {
        token = s.next().toLowerCase();

        if(isPalindrome(token)) {
            listOfPalindromes.add(token);
        }
    }

    for(String word : listOfPalindromes)
    {
        System.out.println(word);
    }
}

private static boolean isPalindrome(String token) {
    for (int i = 0; i <= (token.length()-1)/2; i++)
    {
        if(token.charAt(i) != token.charAt(token.length()-(i+1)))
        {
            return false;
        }
    }
    return true;
}

我没有检查代码是否正确,只解决了 break

的问题

您应该使用带标签的 continue 而不是像这样的 break

Scanner s = new Scanner("lever level canoe kayak carrace racecar mademoiselle madam");
String token;
LinkedList<String> listOfPalindromes = new LinkedList<>();

L: while (s.hasNext()) {
    token = s.next().toLowerCase();

    for (int i = 0; i <= (token.length() - 1) / 2; i++) {
        if (token.charAt(i) != token.charAt(token.length() - (i + 1))) {
            continue L;
        }
    }

    listOfPalindromes.add(token);
}

for (String word : listOfPalindromes) {
    System.out.println(word);
}

输出

level
kayak
racecar
madam