为什么扫描仪在输出之前先读取?

Why is scanner reading first before the output?

我正在做来自 Hackerrank 的地图练习。目标是输入要输入的条目总数,然后放置键和值,直到达到条目数。还要查找密钥是否存在。但是,我的代码 运行 不正确。即使我在扫描仪输入之前打印输出"Please enter name to find phone number:",扫描仪输入也是先读取的。这是为什么?

Scanner scanner = new Scanner(System.in);
Map<String, Integer> phone = new HashMap<>();
System.out.print("Please enter total number of entries: ");
int n = scanner.nextInt();
scanner.nextLine();

for(int x=0;x<n;x++) {
    System.out.print("Please enter name: ");
    String name = scanner.nextLine();
    System.out.print("Please enter phone number: ");
    int num = scanner.nextInt();
    scanner.nextLine();
    phone.put(name,num);
}

while(scanner.hasNext()) {
    System.out.println("Please enter name to find phone number: "); //the problem is here
    String findName = scanner.nextLine(); // this will read first before above line
    if(phone.containsKey(findName)) {
        System.out.println(findName + "=" + phone.get(findName));
    } else {
        System.out.println("not found");
    }
}

问题出在 while 循环上 -- 在 Scanner 检测到输入可用之前循环不会启动,因此程序会阻塞等待输入。也许让它成为一个暂时的,这样它就可以开始了。

您仍然需要一些机制来允许您退出最后一个循环,也许检查输入的字符串是否有 "exit" 或类似的字符串

事实上,我会完全摆脱 scanner.hasNext(),因为它确实没有用,因为 scanner.nextLine() 会为您进行必要的阻止。

相反,我会创建一个标记值,例如:

private static final String SENTINEL = "exit";

然后循环直到输入该值:

String findName = "";
while (!findName.equalsIgnoreCase(SENTINEL)) {
    System.out.print("Please enter name to find phone number or \"" + SENTINEL + "\" to exit: " );
    findName = scanner.nextLine();

    if (phone.containsKey(findName)) {
        System.out.println(findName + "=" + phone.get(findName));
    } else if (!findName.equalsIgnoreCase(SENTINEL)){
        System.out.println("not found");
    }
} 

例如:

import java.util.*;

public class Foo {
    private static final String SENTINEL = "exit";

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        Map<String, Integer> phone = new HashMap<>();
        System.out.print("Please enter total number of entries: ");
        int n = scanner.nextInt();
        scanner.nextLine();

        for (int x = 0; x < n; x++) {
            System.out.print("Please enter name: ");
            String name = scanner.nextLine();
            System.out.print("Please enter phone number: ");
            int num = scanner.nextInt();
            scanner.nextLine();
            phone.put(name, num);
        }

        String findName = "";
        while (!findName.equalsIgnoreCase(SENTINEL)) {
            System.out.print("Please enter name to find phone number or \"" + SENTINEL + "\" to exit: " );
            findName = scanner.nextLine();
            if (phone.containsKey(findName)) {
                System.out.println(findName + "=" + phone.get(findName));
            } else if (!findName.equalsIgnoreCase(SENTINEL)){
                System.out.println("not found");
            }
        } 
    }
}