Math 是算术工具箱(全 static:abs/ceil/floor/round/random),Random 是真·随机机器(new 出来反复 nextInt)——两个一起凑齐"取整三兄弟 + 任意范围随机数"。
第六章 Java API/6.3 System类(工具类套路:构造私有 + 全 static)、2.3 Java中的运算符((int) 强转砍小数,random 公式的关键一步)。
1. Math 类:还是那个工具箱套路
Math.abs(-5) // 5:绝对值
Math.max(3, 9) // 9:比大小(还有 min)
Math.pow(2, 10) // 1024.0:乘方(2 的 10 次方)
Math.sqrt(16) // 4.0:开平方
全 static,类名直接点——和 System 一个模子(6.3 的知识直接复用,这类工具箱以后见一个认一个)。
2. 取整三兄弟:floor / ceil / round
以 1.7 为例,数轴上一看就懂:
| 方法 | 方向 | 结果 | 返回类型 |
|---|---|---|---|
Math.floor(1.7) |
向小取(地板) | 1.0 | double |
Math.ceil(1.7) |
向大取(天花板) | 2.0 | double |
Math.round(1.7) |
四舍五入 | 2 | long(唯一返回整数的) |
floor(-1.2) = -2.0(向小取,-2 比 -1 小);ceil(-1.2) = -1.0。方向永远看数轴正负,不是看绝对值。
3. Math.random():随机数的"原料"
double d = Math.random(); // [0.0, 1.0) —— 含 0.0,永不到 1.0
天生只给 double 小数,想要"1~7 的骰子"要自己变形,三步:
Math.random() // [0.0, 1.0)
* 7 // [0.0, 7.0) 乘上宽度
(int)(...) + 1 // 0~6 再 +1 → 1~7 强转砍小数 + 挪起点
万能公式(想要 小~大 之间的整数):
(int)(Math.random() * (大 - 小 + 1)) + 小
右端 +1 的原因:random 永远够不到 1.0,不 +1 就永远摇不出"大"。
4. Random 类:真·随机机器
import java.util.Random; // 要导包!java.util 下
Random r = new Random();
int n1 = r.nextInt(7); // 0 ~ 6(给"边界",不含边界)
int n2 = r.nextInt(1, 8); // 1 ~ 7(JDK17 新用法:起点, 终点+1)
double d = r.nextDouble(); // [0.0, 1.0),和 Math.random 一个意思
boolean b = r.nextBoolean(); // true / false 各一半
| 对比 | Math.random() | Random 对象 |
|---|---|---|
| 类型 | static 方法直接点 | 要 new(6.1 包装类之外又一个"必须 new 的") |
| 适合 | 偶尔来一个 | 成批生产(循环里摇 N 个) |
| 范围控制 | 自己套公式 | nextInt(边界) 或 JDK17 nextInt(小, 大+1) |
机器造一台就够了——放循环里每次 new 是浪费(6.1 误区里"装箱无开销"同款意识)。
5. 经典实战:猜数字游戏
import java.util.Random;
import java.util.Scanner;
public class GuessNumber {
public static void main(String[] args) {
Random r = new Random();
int answer = r.nextInt(1, 101); // 1~100
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("猜一个 1~100 的数:");
int guess = sc.nextInt();
if (guess > answer) {
System.out.println("大了");
} else if (guess < answer) {
System.out.println("小了");
} else {
System.out.println("猜中了!");
break; // 2.5 循环结构 + break 收网
}
}
}
}
一节串三样:Random 出题、Scanner 收输入(System.in 的首秀预告)、while+if-else 判定——写完这个,前面五章的零件全都转起来了。
6. 动手环节(IDEA06 · Demo04)
- 写
Demo04,打印floor(1.7)、ceil(1.7)、round(1.7)、round(-1.5),对照第 2 节表格。成功标准:四个结果全说得清。 - 30 秒实验 ①:
Math.floor(-1.2)和Math.ceil(-1.2)→ 亲眼看负数方向。 - 30 秒实验 ②:跑 10 次
(int)(Math.random()*7)+1→ 全落在 1~7,一个都不出界。 - 30 秒实验 ③:
r.nextInt(7)连摇 20 次 → 0~6,永远见不到 7——"边界不含"亲眼验证。 - 30 秒实验 ④:把
new Random()挪进循环里 → 程序照跑但纯属浪费(对照 6.1 装箱开销意识)。 - 综合任务:写完猜数字游戏,加一个"猜了几次"计数器(2.5 循环结构收网)。
7. 常见误区
- 以为 Math.random() 能取到 1.0 → 范围是 [0.0, 1.0),右边永远不含——公式里 +1 就是为它。
- floor/ceil 对负数的方向想反 → 方向看数轴位置:floor 向小、ceil 向大,与正负无关。
- round 以为返回 double → 它是三兄弟里唯一返回整数的(long)。
- nextInt(7) 以为是 1~7 → 是 0~6,Random 的边界一律"不含";要 1~7 用 JDK17 的 nextInt(1, 8)。
8. 本节小结
| 要点 | 内容 |
|---|---|
| Math | 全 static 工具箱:abs/max/min/pow/sqrt + 取整三兄弟 + random |
| 取整 | floor 向小(double)、ceil 向大(double)、round 四舍五入(long) |
| random | [0.0, 1.0);公式 (int)(Math.random()*(大-小+1))+小 |
| Random | new 出来的随机机器:nextInt(bound) 不含边界;JDK17 nextInt(小, 大+1) |
| 实战 | 猜数字游戏:Random + Scanner + while 一锅端 |
9. 可折叠自测题
floor = -3.0(向小取);ceil = -2.0(向大取);round = -2(四舍五入,-2.3 更接近 -2)。
(int)(Math.random() * 6) + 15(宽度 = 20-15+1 = 6);或 new Random().nextInt(15, 21)(终点 +1)。
0~99(边界不含)。1~100:nextInt(1, 101) 或老写法 nextInt(100) + 1。
Math.random() 永远够不到 1.0,乘上宽度后永远够不到"宽度"本身,取整后最大只到"大-1"。+1 把这个永远差一点的缺口补上。
Random r = new Random();
int[] count = new int[8]; // 下标 0~7,0 号位弃用
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
int n = r.nextInt(1, 8);
count[n]++;
}
long end = System.currentTimeMillis();
for (int i = 1; i <= 7; i++)
System.out.println(i + " 出现 " + count[i] + " 次");
System.out.println("耗时:" + (end - start) + " 毫秒");
串起:Random 成批生产 + 数组计数(2.7)+ 6.3 秒表——三个工具的接力棒。
10. 下一步学什么
- ☑ 6.5 BigInteger和BigDecimal类 ✅ —— long 溢出与 double 失真的两扇解药之门:构造传字符串、方法运算、divide 舍入。点此复习
相关笔记
- 第六章 Java API/6.3 System类 ← 上一篇:工具类套路,本节原样复用;秒表在本节毕业题上岗
- 2.3 Java中的运算符:(int) 强转砍小数,random 公式第③步的本体
- 2.5 循环结构语句:while + break,猜数字游戏的骨架
- 2.7 数组:摇奖统计的计数容器