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

为何compareTo方法的输入验证会导致输出结果异常?

输入数字触发验证后,姓名比较逻辑错误显示“两个姓名相同”

我需要实现一个方法比较用户输入的两个姓名,按字母顺序输出排序结果。正常输入时功能正常,但故意输入数字触发输入验证后,输出总是错误显示“两个姓名相同”(即使姓名不相等);测试一个输入正确、一个触发验证的情况时,还会出现输出“ is first alphabetically”(姓名为空)的问题。

原代码

import java.util.Scanner;

public class NameSorter {
    public static void alpha() {
        //takes two names, makes them lowercase, and sorts them using uniCode
        System.out.println("Please input the first name you want me to organize.");
        String firstC = isValidString();
        String fir = firstC.toLowerCase();
        
        System.out.println("Please input the second name you want me to organize.");
        String secondC = isValidString();
        String sec = secondC.toLowerCase();
        
        int uniOut = fir.compareTo(sec);
        if (uniOut > 0) {
            System.out.printf("%s is first alphabetically", secondC);
        } else if (uniOut < 0) {
            System.out.printf("%s is first alphabetically", firstC);
        } else {
            System.out.println("Those names are the same.");
        }
    }

    public static String isValidString() {
        //validates input as a string and has the user continue to input until it is a string
        Scanner in = new Scanner(System.in);
        while (in.hasNextDouble()) {
            double input = in.nextDouble();
            System.out.printf("%f is not a valid input, please try again.\n", input);
        }
        String s = in.nextLine();
        return s;
    }
}

问题根源

  1. Scanner重复创建:每次调用isValidString()都新建Scanner实例,会导致输入流读取混乱。
  2. 换行符残留:当用in.nextDouble()读取数字后,输入流中数字后的换行符未被消费,后续in.nextLine()会直接读取这个空换行符,返回空字符串。两个空字符串的compareTo()结果为0,因此错误显示“姓名相同”;若一个为空、一个为有效姓名,就会出现空姓名的输出。

修复方案

修改验证逻辑,共用一个Scanner实例,直接读取整行输入并判断是否为数字,避免换行符残留问题:

import java.util.Scanner;

public class NameSorter {
    public static void alpha() {
        Scanner in = new Scanner(System.in);
        
        System.out.println("Please input the first name you want me to organize.");
        String firstC = isValidString(in);
        String fir = firstC.toLowerCase();
        
        System.out.println("Please input the second name you want me to organize.");
        String secondC = isValidString(in);
        String sec = secondC.toLowerCase();
        
        int uniOut = fir.compareTo(sec);
        if (uniOut > 0) {
            System.out.printf("%s is first alphabetically%n", secondC);
        } else if (uniOut < 0) {
            System.out.printf("%s is first alphabetically%n", firstC);
        } else {
            System.out.println("Those names are the same.");
        }
        
        in.close();
    }

    public static String isValidString(Scanner in) {
        while (true) {
            String input = in.nextLine().trim();
            // 正则匹配整数/小数格式的数字
            if (input.matches("-?\\d+(\\.\\d+)?")) {
                System.out.printf("%s is not a valid input, please try again.%n", input);
            } else if (input.isEmpty()) {
                System.out.println("Empty input is not allowed, please try again.");
            } else {
                return input;
            }
        }
    }

    public static void main(String[] args) {
        alpha();
    }
}

修改说明

  • 共用Scanner:在alpha()中创建一个Scanner实例并传入验证方法,避免输入流混乱。
  • 整行读取+正则判断:用in.nextLine()读取完整输入行,通过正则判断是否为数字,不会残留换行符。
  • 空输入处理:增加空输入的验证,避免用户直接回车的无效输入。
  • 去除首尾空格:用trim()处理输入,避免用户输入前后空格导致的判断错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 11:37:43