使用Scanner触发NoSuchElementException,求解释第19行报错原因
Hey there! Let's break down why that NoSuchElementException is hitting your code at line 19, and how to fix it.
What's Causing the Exception?
There are a couple of key issues in your input handling logic that lead to this error:
Mishandling the newline after
nextInt()
When you usescanner.nextInt()to read the number of contactsn, it only grabs the integer value—the newline character after that number stays in the input buffer. Your attempt to fix this withscanner.next()is wrong:next()reads the next non-whitespace token (which would be the first contact's name), leaving the rest of the input sequence out of sync. This misalignment eventually causes your code to try reading input that doesn't exist, triggering theNoSuchElementExceptionwhen it hitsscanner.nextLine()in the while loop.Input reading logic that doesn't match typical test case formats
Most HackerRank test cases for this problem format each contact as a single line with the name and phone number separated by a space (e.g.,Alice 12345). Your code uses two separatenextLine()calls per contact, which would only work if each name and number are on their own lines. When the input doesn't match this, your code reads data incorrectly, leading to missing or extra entries in your contact book, and eventually running out of input to read.Unsafe while loop condition
Usingn-- > 0for your query loop assumes exactlynqueries exist in the input. But if your earlier input handling messed up the sequence, you might exhaust the input stream before the loop finishes, causingscanner.nextLine()to throw the exception.
Fixed Code
Here's a revised version of your code that addresses all these issues:
import java.util.*; import java.io.*; class Solution{ public static void main(String []args) { Scanner scanner = new Scanner(System.in); Map<String, String> contactBook = new HashMap<>(); int n = scanner.nextInt(); scanner.nextLine(); // Properly consume the newline after the integer // Read n contacts (assuming name and number are on the same line) for(int i = 0; i < n; i++) { String[] contactDetails = scanner.nextLine().split(" "); String name = contactDetails[0]; String phoneNumber = contactDetails[1]; contactBook.put(name, phoneNumber); } // Read queries until there's no more input (more robust than relying on n) while(scanner.hasNextLine()) { String search = scanner.nextLine(); if(contactBook.containsKey(search)) { System.out.println(search + "=" + contactBook.get(search)); } else { System.out.println("Not found"); } } scanner.close(); // Good practice to close the scanner } }
Key Fixes Explained:
- Correct newline handling:
scanner.nextLine()afternextInt()clears the leftover newline without consuming actual contact data. - Matching input format: Using
split()to read each contact line into name and number aligns with standard HackerRank test case formatting. - Robust query reading:
scanner.hasNextLine()checks if there's still input to read before callingnextLine(), preventing theNoSuchElementExceptionentirely.
内容的提问来源于stack exchange,提问作者Hegyi Levente

