Java Scanner 类学习笔记详细版java.util.Scanner是 Java 5 引入的一个强大的文本扫描器类位于java.util包中。它主要用于解析基本数据类型如int,double,boolean和字符串支持从各种输入源如标准输入System.in、文件、字符串读取数据。相比于传统的BufferedReaderScanner的 API 更加简洁、易用特别适合处理格式化的输入数据。一、核心特性多类型支持可以直接读取int,double,boolean,String等多种类型无需手动转换。正则表达式支持底层使用正则表达式来解析输入支持自定义分隔符。多种输入源支持从System.in控制台、File、InputStream、Readable、String等读取。易用性API 设计直观如nextInt(),nextLine()等。性能由于内部使用了正则匹配和缓冲性能低于BufferedReader。在处理海量数据时建议使用BufferedReaderStringTokenizer或自定义解析器。二、构造方法importjava.util.Scanner;importjava.io.File;importjava.io.InputStream;// 1. 从标准输入控制台读取ScannerscnewScanner(System.in);// 2. 从文件读取ScannerfileScannernewScanner(newFile(data.txt));// 3. 从字节流读取ScannerstreamScannernewScanner(inputStream);// 4. 从字符串读取常用于测试或解析特定格式字符串ScannerstrScannernewScanner(Hello 123 World);// 5. 指定字符编码防止文件读取乱码ScannerfileScannerUTF8newScanner(newFile(data.txt),UTF-8);三、常用读取方法Scanner提供了一系列nextXxx()方法来读取不同类型的数据。1. 读取基本类型方法功能返回值说明next()读取下一个单词以空白符分隔String遇到空格、换行、制表符停止nextInt()读取下一个intint如果输入不是整数抛InputMismatchExceptionnextDouble()读取下一个doubledoublenextLong()读取下一个longlongnextBoolean()读取下一个booleanboolean接受true,false(不区分大小写)nextByte(),nextShort(),nextFloat()读取对应类型对应类型2. 读取整行方法功能返回值说明nextLine()读取整行直到换行符String包含空格消耗掉换行符hasNextXxx()检查是否有下一个匹配项boolean防止读取时抛出异常推荐配合使用3. 示例代码ScannerscnewScanner(System.in);System.out.print(请输入姓名);Stringnamesc.next();// 读取 Alice (遇到空格停止)System.out.print(请输入年龄);intagesc.nextInt();// 读取 25System.out.print(请输入身高);doubleheightsc.nextDouble();// 读取 1.75System.out.print(请输入描述);// ⚠️ 注意这里如果前面有 nextInt()需要处理换行符残留问题见下文Stringdescsc.nextLine();System.out.println(姓名name);System.out.println(年龄age);System.out.println(身高height);System.out.println(描述desc);四、经典陷阱nextInt()与nextLine()的混用这是Scanner最著名的坑。问题现象ScannerscnewScanner(System.in);System.out.print(输入年龄);intagesc.nextInt();// 输入 25 并回车System.out.print(输入姓名);Stringnamesc.nextLine();// 直接跳过name 为空字符串原因分析nextInt()只读取了数字25没有读取回车符\n。回车符仍然留在输入缓冲区中。nextLine()读取的是“从当前位置到下一个换行符之间的内容”。由于缓冲区里立刻就是一个换行符nextLine()读取了空字符串并消耗了那个换行符导致程序“跳过”了用户的输入。解决方案方案 1在nextInt()后额外调用一次nextLine()消耗换行符intagesc.nextInt();sc.nextLine();// 消耗掉残留的换行符Stringnamesc.nextLine();// 正常读取下一行方案 2统一使用nextLine()读取然后手动转换类型intageInteger.parseInt(sc.nextLine());// 读取整行并解析Stringnamesc.nextLine();推荐方案 2代码更统一避免缓冲区问题且能更好地处理输入验证。五、分隔符与自定义模式默认情况下Scanner使用空白符空格、制表符\t、换行符\n、回车符\r作为分隔符。1. 修改分隔符使用useDelimiter()方法。ScannerscnewScanner(100,200,300);sc.useDelimiter(,);// 设置逗号为分隔符while(sc.hasNextInt()){System.out.println(sc.nextInt());// 输出 100, 200, 300}2. 使用正则表达式作为分隔符// 以逗号或分号或空格分隔sc.useDelimiter([,;\\s]);3. 查找匹配模式使用findInLine()或next()配合正则。// 查找所有数字sc.useDelimiter(\\D);// 非数字作为分隔符while(sc.hasNextInt()){System.out.println(sc.nextInt());}六、安全性与异常处理1. 输入不匹配异常如果调用nextInt()但用户输入了 “abc”会抛出InputMismatchException。最佳实践先使用hasNextXxx()检查。ScannerscnewScanner(System.in);System.out.print(请输入一个整数);if(sc.hasNextInt()){intnumsc.nextInt();System.out.println(你输入的是num);}else{System.out.println(输入无效请输入整数);sc.next();// 消耗掉无效输入防止死循环}2. 资源关闭Scanner实现了Closeable接口使用完毕后应关闭释放底层资源。对于System.in通常不需要显式关闭关闭后整个标准输入流不可用但在文件读取时必须关闭。推荐使用try-with-resources。try(ScannerscnewScanner(newFile(data.txt))){while(sc.hasNextLine()){System.out.println(sc.nextLine());}}catch(Exceptione){e.printStackTrace();}七、Scanner vs BufferedReader特性ScannerBufferedReader易用性高(自动解析类型)低 (需手动Integer.parseInt)性能低(正则匹配开销大)高(纯字符缓冲)功能支持正则、多类型解析仅读取字符/行适用场景交互式命令行、小数据量、格式简单大数据量文件读取、高性能要求异常处理抛出InputMismatchException抛出IOException建议写算法题、小工具、用户交互用Scanner。处理大文件、高性能服务用BufferedReader。八、实战案例1. 简单的计算器importjava.util.Scanner;publicclassCalculator{publicstaticvoidmain(String[]args){ScannerscnewScanner(System.in);System.out.print(请输入第一个数字);doublenum1sc.nextDouble();System.out.print(请输入运算符 (, -, *, /));Stringopsc.next();System.out.print(请输入第二个数字);doublenum2sc.nextDouble();doubleresult0;switch(op){case:resultnum1num2;break;case-:resultnum1-num2;break;case*:resultnum1*num2;break;case/:if(num2!0)resultnum1/num2;else{System.out.println(除数不能为0);return;}break;default:System.out.println(无效运算符);return;}System.out.println(结果result);sc.close();}}2. 解析 CSV 文件importjava.io.File;importjava.util.Scanner;publicclassCSVParser{publicstaticvoidmain(String[]args)throwsException{try(ScannerscnewScanner(newFile(users.csv))){sc.useDelimiter(,|\\n);// 逗号或换行符分隔while(sc.hasNext()){Stringnamesc.next();Stringagesc.next();Stringcitysc.next();System.out.println(Name: name, Age: age, City: city);}}}}九、总结Scanner是 Java 中最方便的输入工具特别适合交互式输入和小数据量解析。核心方法next(),nextInt(),nextLine(),hasNextXxx()。最大陷阱nextInt()后直接接nextLine()会导致跳过输入需额外nextLine()消耗换行符。性能大数据量处理时性能不如BufferedReader。安全性务必使用hasNextXxx()检查输入避免InputMismatchException。资源管理文件读取时务必关闭 Scanner。掌握Scanner能极大简化 Java 程序的输入处理逻辑是初学者和日常开发中不可或缺的工具。