You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修正Sorter方法以支持更多用户输入并解决程序终止问题

问题描述

我正在给几个朋友开发一款排序算法,目前做的是测试版本。最终会让它更具动态性,但现在只实现了接收用户姓名和输入数字的功能。但运行代码时,程序会请求输入姓名,到提示输入数值的时候直接终止了。我卡了半小时,有点懵,代码如下:

原代码

Sorter.java

//Sorter.java
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Sorter {

    public static void dict() {

        // Create a dictionary
        Map<String, Range> dictionary = new HashMap<>();

        // Add groups and their corresponding value ranges
        dictionary.put("Family A", new Range(0, 10));
        dictionary.put("Family B", new Range(11, 20));
        dictionary.put("Family C", new Range(21, 30));

        // Retrieve the value range for a specific group
        Range rangea = dictionary.get("Family A");
        System.out.println("Value range for Family A: " + rangea.getStart() + " - " + rangea.getEnd());
        Range rangeb = dictionary.get("Family B");
        System.out.println("Value range for Family B: " + rangeb.getStart() + " - " + rangeb.getEnd());
        Range rangec = dictionary.get("Family C");
        System.out.println("Value range for Family C: " + rangec.getStart() + " - " + rangec.getEnd());

    }

    public static String getName() {
        try (Scanner scanner = new Scanner(System.in)) {
            System.out.print("Enter your name: ");
            if (scanner.hasNextLine()) {
                String nameInput = scanner.nextLine();
                System.out.println("Hello, " + nameInput + ".");
                return nameInput;
            } else {
                // handle no input available
                return null;
            }
        }
    }

/**
 * Prompts the user to enter a numerical value and prints the corresponding family group.
 */
    public static void counter() {
        try (Scanner scanner = new Scanner(System.in)) {
            System.out.print("Enter a numerical value: ");
            if (scanner.hasNextLine()) {
                String userInputString = scanner.nextLine();
                try {
                    int userInput = Integer.parseInt(userInputString);
                    String whatFamily = getGroup(userInput);
                    System.out.println("Family: " + whatFamily);
                } catch (NumberFormatException e) {
                    System.out.println("No Family LOL get rekt");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * Determines the group based on the given value.
     *
     * @param  value  the value to be evaluated
     * @return        the group corresponding to the value
     */
    public static String getGroup(int value) {
        // Check if the value is less than 0
        if (value < 0) {
            return "Family A";
        }
        // Check if the value is within the range of Family A
        else if (value >= 1 && value <= 10) {
            return "Family A";
        }
        // Check if the value is within the range of Family B
        else if (value >= 11 && value <= 20) {
            return "Family B";
        }
        // Check if the value is within the range of Family C
        else if (value >= 21 && value <= 30) {
            return "Family C";
        }
        // Check if the value is greater than 30
        else if (value > 30) {
            return "Family C";
        }
        // Value is outside the range of any family
        else {
            return "No Family LOL get rekt";
        }
    }
}

class Range {
    private int start;
    private int end;

    public Range(int start, int end) {
        this.start = start;
        this.end = end;
    }

    public int getStart() {
        return start;
    }

    public int getEnd() {
        return end;
    }
}

Exec.java

//Exec.java

import java.util.HashMap;
import java.util.Map;

public class Exec {
    /**
     * Initializes a dictionary with groups and their corresponding value ranges.
     * Prints the value range for each group and prompts user input.
     *
     * @param  args  command line arguments
     */
    public static void main(String[] args) {

        // Prompt user input
        Sorter.getName();
        Sorter.dict();
        Sorter.counter();
    }
}
问题原因及解决方法

问题根源

每次调用getName()和counter()时,都会新建一个Scanner并通过try-with-resources自动关闭。而关闭Scanner的同时会关闭底层的System.in输入流,导致后续的Scanner无法读取任何输入,程序直接终止。

修复方案

复用同一个Scanner实例,不要在每个方法里关闭它,而是在所有输入操作完成后统一关闭。

修改后的代码

修改Sorter.java的方法

将getName()和counter()改为接收Scanner参数:

public static String getName(Scanner scanner) {
    System.out.print("Enter your name: ");
    if (scanner.hasNextLine()) {
        String nameInput = scanner.nextLine();
        System.out.println("Hello, " + nameInput + ".");
        return nameInput;
    } else {
        return null;
    }
}

public static void counter(Scanner scanner) {
    System.out.print("Enter a numerical value: ");
    if (scanner.hasNextLine()) {
        String userInputString = scanner.nextLine();
        try {
            int userInput = Integer.parseInt(userInputString);
            String whatFamily = getGroup(userInput);
            System.out.println("Family: " + whatFamily);
        } catch (NumberFormatException e) {
            System.out.println("No Family LOL get rekt");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

修改Exec.java的main方法

在main中创建一个Scanner,传递给各个方法使用,最后关闭:

public static void main(String[] args) {
    try (Scanner scanner = new Scanner(System.in)) {
        // Prompt user input
        Sorter.getName(scanner);
        Sorter.dict();
        Sorter.counter(scanner);
    }
}

这样就能保证System.in在所有输入操作完成后才关闭,程序可以正常接收两次输入。

内容的提问来源于stack exchange,提问作者L4w1i3t

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 11:50:02