一、把数据输出到控制台

1.1 print 和 println:是否自动换行

写法 作用
System.out.print(内容); 输出内容,不自动换行
System.out.println(内容); 输出内容后自动换行
System.out.printf(格式字符串, 数据...); 按指定格式输出,不自动换行

它们不只能输出字符串,也可以输出数字、表达式的结果等。下面的代码片段放在 main 方法中运行。

System.out.print("Java"); System.out.println("输入输出"); System.out.println(10 + 20); System.out.print("A\nB"); 

输出:

Java输入输出 30 A B 

println 在输出后自动换行;\n 是写在字符串中的换行符。 print 虽然不自动换行,但遇到 \n 仍然会换行。单独写 System.out.println(); 表示只换行。

1.2 printf:把数据放到指定位置

格式字符串中的 %d、%f 等是占位符,后面的数据按顺序填入对应位置。

String name = "张三"; int age = 18; float salary = 1000.5f; System.out.printf("姓名:%s,年龄:%d,工资:%.2f\n", name, age, salary); 

输出:

姓名:张三,年龄:18,工资:1000.50 
写法 含义
%s 输出字符串
%d 按十进制输出整数
%f 输出浮点数,默认保留 6 位小数
%.2f 输出浮点数,保留 2 位小数
%% 输出一个 %,不需要对应的数据

使用时注意:

  • 占位符与数据的类型要匹配,例如 %d 对应整数,%f 对应浮点数。
  • printf 不自动换行,需要换行时可在格式字符串中加 \n。
  • %.2f 控制的是显示格式,不会改变变量中保存的值。

其他格式符不必背诵,用到时查阅即可,这里不逐项展开。

二、使用 Scanner 读取键盘输入

2.1 先准备输入工具

import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); // 在这里读取输入 sc.close(); } } 

暂时只需理解这三步:

  1. import java.util.Scanner;:导入 Scanner 类,写在类定义之前,让程序能使用这个输入工具。
  2. Scanner sc = new Scanner(System.in);:创建输入工具,命名为 sc。System.in 表示标准输入,通常来自键盘;new 在这里用于创建对象。
  3. sc.close();:全部输入结束后关闭它。它也会关闭关联的 System.in,所以不要在还需要键盘输入时提前调用。

2.2 根据数据类型选择读取方法

方法 读取内容 返回类型
sc.nextInt() 下一个整数 int
sc.nextFloat() 下一个浮点数 float
sc.nextLine() 从当前位置读到本行结束,返回内容不包含行末换行符 String

读取方法会取走本次读取的输入。程序执行到读取语句时,如果还没有可读取的完整输入,通常会停下来等待。

nextInt()、nextFloat() 默认用空格、换行等空白字符分隔数据。例如依次读取年龄和工资时,输入 18 1000.5,或把两个数分行输入,都可以。

键盘输入要符合读取方法要求的类型。 nextInt() 不能读取 18.5 或 张三,否则会报输入不匹配的异常;异常处理后续再学。用 nextFloat() 读取时,键盘输入 1000.5 即可,不需要像 Java 代码中的浮点数字面量那样加 f。

2.3 完整示例:输入姓名、年龄和工资

import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.print("请输入姓名:"); String name = sc.nextLine(); System.out.print("请输入年龄:"); int age = sc.nextInt(); System.out.print("请输入工资:"); float salary = sc.nextFloat(); System.out.println("姓名:" + name); System.out.println("年龄:" + age); System.out.println("工资:" + salary); sc.close(); } } 

依次输入 张三、18、1000.5,每次按回车,最终输出:

姓名:张三 年龄:18 工资:1000.5 

2.4 为什么先读年龄,再读姓名会出问题?

假设改成下面的顺序,并要求年龄、姓名分别输入一行:

int age = sc.nextInt(); String name = sc.nextLine(); 

输入 18 后按回车,name 往往直接得到空字符串,程序没有等待输入姓名。

原因在于两个方法的读取规则不同:

  • nextInt() 读取整数前会跳过空白,但读完 18 后,不会顺便取走它后面的换行符。
  • nextLine() 从当前位置读取到本行结束,并取走行末换行符。此时当前位置已经在 18 后面,所以读到的本行剩余内容为空。

可以把输入理解为:

输入: 18[换行] nextInt() 读取后剩下: [换行] nextLine() 读取结果: "" 

解决方法:在读取姓名前,先用一次 nextLine() 结束年龄所在的这一行。

将上一个完整示例的输入部分改为:

System.out.print("请输入年龄:"); int age = sc.nextInt(); sc.nextLine(); // 读走年龄这一行剩余的内容和换行符 System.out.print("请输入姓名:"); String name = sc.nextLine(); System.out.print("请输入工资:"); float salary = sc.nextFloat(); 

注意两点:

  • nextFloat() 后接 nextLine() 时,也可能遇到同样的问题。
  • 额外的 nextLine() 会读走本行所有剩余内容,不只是换行符。上面的写法要求年龄和姓名分行输入;如果输入 18 张三,这一行中的姓名也会被丢弃。

三、循环处理多组输入

3.1 hasNextInt() 判断,nextInt() 读取

不知道总共有多少个整数时,可以边判断、边读取:

while (sc.hasNextInt()) { int num = sc.nextInt(); // 处理 num } 

两者的区别是:

  • hasNextInt():判断接下来是否有可读取的 int,返回 true 或 false,不会取走这个整数。
  • nextInt():真正读取并取走这个整数。

如果循环中只判断却不读取,输入位置不会前进,就可能一直对同一个整数重复判断。

暂时没有输入,不等于输入已经结束。 在键盘交互时,hasNextInt() 可能等待后续输入;遇到非整数内容,或到达输入末尾时,才会返回 false。

3.2 完整示例:求若干整数的和与平均值

import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int sum = 0; int count = 0; while (sc.hasNextInt()) { int num = sc.nextInt(); sum += num; count++; } System.out.println("sum = " + sum); if (count > 0) { double avg = (double) sum / count; System.out.println("avg = " + avg); } else { System.out.println("没有输入整数,无法计算平均值"); } sc.close(); } } 

输入下面的内容并按回车:

10 20 21 end 

输出:

sum = 51 avg = 17.0 

前三个整数被依次累加,count 变为 3。接下来遇到 end,hasNextInt() 返回 false,循环结束。这里的 end 不是 Java 规定的结束符,只是一个不能作为整数读取的内容;循环不会读走它。

计算时要注意:

  • sum / count 两边都是整数时会执行整数除法。例如输入 10 11 end,直接相除只能得到 10;写成 (double) sum / count 才能得到 10.5。
  • 必须先判断 count > 0,避免没有读入数据就计算平均值。
  • 这个程序只处理整数。输入 40.0、50.5 等内容时,hasNextInt() 会返回 false,不会继续累加。

3.3 如何真正结束键盘输入?

除了输入非整数让上述循环退出,也可以发送“输入结束”信号(EOF):

  • Windows 的 CMD:通常在新行按 Ctrl + Z,再按回车。
  • Linux、macOS 的终端:通常在空行按 Ctrl + D。
  • IDEA 控制台:使用发送 EOF 的操作,具体快捷键取决于系统和键位设置。

按回车只是提交一行,不代表全部输入结束;强制停止程序也不等于发送 EOF。 发送 EOF 后,循环才能正常结束,并继续执行后面的统计输出。

四、综合练习:猜数字游戏

程序随机生成一个 1~100(包含两端) 的整数。用户反复输入猜测值,程序提示“低了”或“高了”,猜对后结束。

4.1 使用 Random 生成目标数字

import java.util.Random; 

导入后,在 main 中使用:

Random random = new Random(); int target = random.nextInt(100) + 1; 

Random 是生成随机数的工具,使用方式和 Scanner 类似:先创建对象,再调用方法。

random.nextInt(100) 的范围是 0~99,包含 0、不包含 100;加 1 后才是 1~100。

注意:sc.nextInt() 从输入中读取整数;random.nextInt(100) 生成随机整数。虽然方法名相同,但所属工具不同,作用也不同。

4.2 完整代码

import java.util.Random; import java.util.Scanner; public class Main { public static void main(String[] args) { Random random = new Random(); Scanner sc = new Scanner(System.in); int target = random.nextInt(100) + 1; while (true) { System.out.print("请输入猜测的数字(1~100):"); int num = sc.nextInt(); if (num < target) { System.out.println("低了"); } else if (num > target) { System.out.println("高了"); } else { System.out.println("猜对了"); break; } } sc.close(); } } 

假设本次生成的目标是 63:

请输入猜测的数字(1~100):50 低了 请输入猜测的数字(1~100):75 高了 请输入猜测的数字(1~100):63 猜对了 

目标数字必须在循环外生成,只生成一次。 如果放到循环内,每猜一次目标就可能改变,用户就无法根据提示逐步缩小范围。猜对时通过 break 退出循环,然后关闭输入工具。