一、把数据输出到控制台
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(); } } 暂时只需理解这三步:
-
import java.util.Scanner;:导入Scanner类,写在类定义之前,让程序能使用这个输入工具。 -
Scanner sc = new Scanner(System.in);:创建输入工具,命名为sc。System.in表示标准输入,通常来自键盘;new在这里用于创建对象。 -
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 退出循环,然后关闭输入工具。
