优先用 bufferedreader 包装 inputstreamreader,兼顾效率与易用性;大量数值输入时用 bufferedreader + split 替代 scanner;极端性能需求下可用 bufferedinputstream 手动字节解析。

System.in 本身是字节流,直接读取效率低、编码易出错、开发繁琐。真正提升效率的关键不是“怎么读”,而是“用什么包装它”——选对封装层,性能和可维护性都能明显改善。
优先用 BufferedReader 包装 InputStreamReader
这是兼顾效率与易用性的主流方案。BufferedReader 内部带默认 8KB 缓冲区,避免频繁系统调用;InputStreamReader 负责字节→字符的正确解码(如 UTF-8)。
- 适合按行处理场景(如读配置、交互式输入),readLine() 比 Scanner 的 nextLine() 快得多
- 不自动跳过空白或解析类型,需手动转换(如 Integer.parseInt(line)),但正因如此,没有额外开销
- 注意:必须显式 close(),否则可能泄漏资源(尤其在循环或长生命周期中)
大量数值输入时,绕过 Scanner 直接用 BufferedReader + 字符串拆分
Scanner 内部做了大量格式预检、异常捕获和状态管理,对纯数字批量输入来说属于冗余开销。
- 典型写法:BufferedReader → readLine() → String.split() → Integer.parseInt()
- 实测对比:读 400 多万个整数,BufferedReader + split 耗时约 0.7 秒,Scanner 同样逻辑耗时超 3 秒
- 若追求极致,可用 String.indexOf / substring 手动切分,避开正则 split,还能再提速
避免 Scanner 在高频/大数据场景下使用
Scanner 设计目标是“开发便捷”,不是“吞吐最快”。它每次调用 nextInt() 或 hasNextInt() 都会重新扫描、校验、跳过分隔符,底层仍依赖缓冲,但逻辑更重。
- 适合命令行小工具、教学示例、用户交互等低频输入场景
- 若已用 Scanner,务必配 hasNextXxx() 判断再读,防止 InputMismatchException
- nextInt() 后紧跟 nextLine() 时,记得先调一次 nextLine() 清掉残留换行符,否则会跳过真实输入
极端性能需求:BufferedInputStream + 手动字节解析
当输入全是 ASCII 数字且格式高度规整(如每行一个整数),可跳过字符编码层,直接操作字节。
- 用 BufferedInputStream 包装 System.in,配合 byte[] 缓冲区批量读取
- 逐字节判断是否为数字字符('0'–'9'),累加计算值,跳过空格和换行
- 无字符串创建、无编码转换、无异常抛出,实测可压到 0.1 秒级(千万级整数)
- 代价是代码复杂、容错差、不支持中文或特殊符号,仅推荐竞赛或高性能批处理











