【问题标题】:Incorrect example of Scanner in Java book?Java书中扫描仪的错误示例?
【发布时间】:2014-12-16 19:16:09
【问题描述】:

我正在练习 Cay S. Horstmann 和 Gary Cornell 编写的 Java 书中的 HashSet,我认为第 687 页的示例代码有错误。我们有一个 Scanner 将单词导入 HashSet,它看起来像这样(我删除了一些不需要的代码以使问题更加明显):

Set<String> words = new HashSet<String>();
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
    String word = in.next();
    words.add(word);
}

问题是没有办法停止这个循环。或者也许我错过了什么?

为了停止循环,我添加了另一个静态辅助方法:

public static boolean isStop(Scanner in) {
    if (in.next().equals("stop")) {
        return true;
    }
    return false;
}

现在主要代码如下所示:

Set<String> words = new HashSet<String>();
Scanner in = new Scanner(System.in);
while (!isStop(in)) {
    String word = in.next();
    words.add(word);
}

还有其他方法可以停止扫描器循环吗?我不敢相信那本书的作者弄错了?

【问题讨论】:

    标签: java


    【解决方案1】:

    如果在循环之后有要执行的代码,那么是的,我会说作者犯了一个错误。写信给他们!如果这是将项目添加到 Set 的示例,那么该示例很好。这完全取决于作者对示例的意图是什么。

    hasNext() 是一种阻塞方法,这意味着它将始终等待更多输入。关于这个有relatedquestions。您“解决这个问题”的方式是普遍共识所做的。

    【讨论】:

    • 整个代码不包含停止扫描器循环的方法。我会通知书作者,谢谢。
    【解决方案2】:

    循环不会停止,因为它会继续向您的Set 添加“单词”,但程序中没有明显的错误。

    一旦用户输入与该关键字匹配,您选择一个关键字来停止循环的想法听起来不错。

    您实际上并不需要使用 Scanner 作为参数的静态方法。

    只需添加更改代码如下:

    Set<String> words = new HashSet<String>();
    Scanner in = new Scanner(System.in);
    System.out.print("Type a word...");
    while (in.hasNext()) {
        String word = in.next();
        if (word.equalsIgnoreCase("stop")) {
            System.out.printf("Quitting with set: %s%n", words);
            return; // assuming method is void
        }
        else {
            words.add(word);
            System.out.print("Type a word (or \"stop\" to quit)...");
        }
    }
    

    【讨论】:

    • 谢谢,我先试过了,但没有成功:)
    • 我这样改过它,它正在工作,谢谢:boolean cont = true; while (cont) { String word = in.next(); if (word.equalsIgnoreCase("stop")) { cont = false; }
    • @RichardK 酷!我已经用更多细节编辑了我的答案,以防它帮助你。
    【解决方案3】:

    正如其他人解释的那样,当输入中仍有单词时,扫描仪将继续。请注意,当我们谈论System.in 时,它通常会等到用户输入更多文本,因此在用户关闭流之前不会终止(为操作系统提供适当的文件结尾)。在 Unix/Linux 中,要终止循环,用户需要使用 control-D。

    【讨论】:

    • 谢谢。我还尝试关闭流并抛出异常。我找不到其他方法来阻止它,而是制作一个静态方法。
    • 用户(输入输入)应该通过发出适当的字符(在 unix/Linux/Mac 中为 ctrl-D,在 Windows 中为 ctrl-Z)来关闭流。请注意,在那之后,如果有其他尝试从 System.in(或任何基于它的阅读器)读取,他们将不会读取任何内容。
    【解决方案4】:

    由于您正在扫描System.in,循环不会停止,因为它会继续向您的Set 添加“单词”,但程序中没有可见的错误。

    一旦用户输入与该关键字匹配,您选择一个关键字来停止循环的想法听起来不错。

    您实际上并不需要使用 Scanner 作为参数的静态方法。

    只需在String word = in.next();之后添加以下内容:

    if (word.equalsIgnoreCase("stop")) {
        System.out.printf("Quitting with set: %s%n", words);
        in.close();
        return; // assuming method is void
    }
    

    【讨论】:

    • in.next() 推进解析器。 in.hasNext() 检查是否还有要读取的输入。当没有更多输入要读取时,循环会终止。
    • @Luminous 在这个例子中Scanner 正在扫描System.in。只要用户键入文本,它就会继续扫描。控制这种情况的一个好方法是根据关键字停止。当然,您也可以将 next 与空的 String 进行比较(即单个回车)。
    • 当用户完成输入文本时会发生什么? This code example 证明循环确实终止了。没有代码表示循环等待输入更多文本。
    • @Luminous 一旦用户按设计键入“stop[return]”,循环就会终止。我建议使用实际的 IDE 来测试代码。
    • (in.equals("stop")) 已经停止扫描仪。 (!in.equals("stop")) 在这里不起作用。这就是我制作另一个静态方法的原因。
    【解决方案5】:

    只要这个条件为假,循环就会停止:

    in.hasNext()
    

    也就是说,没有更多的词了。

    循环内部是读取下一个单词的命令:

    in.next()
    

    所以单词将继续被读取,直到扫描器没有更多的单词要读取。此循环将在扫描器正在读取的任何内容结束时终止。

    【讨论】:

    • 谢谢,但我能做些什么让它成为假?我没找到路
    • 你什么都不“做”。这个条件 hasNext() 是对 Scanner 扫描的流的自动检查,如果流中仍有单词,则给出“true”,如果没有,则给出“false”。您最终可以“做”以使其为假的是继续在输入上运行程序,直到扫描仪完成。希望您的解释清楚,如果不是,请告诉我。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-26
    • 1970-01-01
    • 1970-01-01
    • 2018-08-01
    • 1970-01-01
    • 2015-10-02
    相关资源
    最近更新 更多