本课作品
制作矿工收益计算器
带七块煤和十根木棍,能合成多少火把?150个圆石能装几组?一趟采矿的收益怎样扣掉成本?这些问题不需要电脑猜答案,只需要把规则写成表达式。这一课,我们会区分算术、比较和逻辑,并给结果安排边界测试。
开始前:建议先完成第 1–3 课
01 / 11
先弄清问题,再挑运算符

算数量,通常需要算术运算;问“是否足够”,需要比较;多个要求同时出现,就要用逻辑把它们连接起来。三种运算得到的结果不同,不要把“有多少”和“是否足够”混成一件事。
- 多少根火把?得到一个整数。
- 利润是否至少50?得到 true 或 false。
- 利润达标并且挖到钻石?仍然得到 true 或 false。
02 / 11
五把运算工具:+ - * / %

片段:放在 main 中,单独运行
int coal = 7, sticks = 10, blocks = 150;
System.out.println(coal + 3);
System.out.println(sticks - coal);
System.out.println(coal * 4);
System.out.println(blocks / 64);
System.out.println(blocks % 64);运行结果
10
3
28
2
22加法记录获得,减法记录消耗,乘法处理“每组几个”。对非负物品数量,用 / 数完整组,用 % 数剩余数量。这里暂按一种物品每组最多64个的练习规则计算。
03 / 11
优先级:谁先被计算?
| 层次 | 运算符 | 阅读提示 |
|---|---|---|
| 括号 | ( ) | 先明确分组 |
| 取反 | ! | 翻转真假 |
| 乘除余 | * / % | 同层通常从左到右 |
| 加减 | + - | 也留意字符串拼接 |
| 大小比较 | > >= < <= | 得到 boolean |
| 相等比较 | == != | 得到 boolean |
| 逻辑与 | && | 两个都满足 |
| 逻辑或 | || | 至少一个满足 |
片段:放在 main 中,单独运行
System.out.println(2 + 3 * 4);
System.out.println((2 + 3) * 4);
int total = 3 * 12 + 5;
System.out.println(total);运行结果
14
20
4104 / 11
完整组与余数,运输格与箱子
- 第1组64 个
- 第2组64 个
- 剩余22 个
片段:放在 main 中,单独运行
int blocks = 150;
int fullStacks = blocks / 64;
int leftover = blocks % 64;
System.out.println(fullStacks + " 组,余 " + leftover);
int slotsNeeded = (int) Math.ceil(65 / 64.0);
System.out.println("65个物品需要的格数=" + slotsNeeded);运行结果
2 组,余 22
65个物品需要的格数=2第二个结果是物品栏格数,不是箱子数量。这里设定一种物品每格放64个;箱子会有多个格,算箱子数还要知道每个箱子的格数。先说清单位,计算才有意义。
05 / 11
比较:用一个问题得到真假
| 运算符 | diamonds = 4 时 | 结果 |
|---|---|---|
| > | 4 > 2 | true |
| >= | 4 >= 4 | true |
| < | 4 < 10 | true |
| <= | 4 <= 3 | false |
| == | 4 == 4 | true |
| != | 4 != 0 | true |
片段:放在 main 中,单独运行
int diamonds = 4;
System.out.println(diamonds > 2);
System.out.println(diamonds >= 4);
System.out.println(diamonds < 10);
System.out.println(diamonds <= 3);
System.out.println(diamonds == 4);
System.out.println(diamonds != 0);运行结果
true
true
true
false
true
true06 / 11
逻辑:把两个答案连起来

| A | B | A && B | A || B |
|---|---|---|---|
| true | true | true | true |
| true | false | false | true |
| false | true | false | true |
| false | false | false | false |
!true 是 false;!false 是 true。
片段:放在 main 中,单独运行
int torches = 24;
boolean hasPickaxe = true;
boolean ready = torches >= 20 && hasPickaxe;
boolean canStay = false || true;
System.out.println(ready);
System.out.println(canStay);
System.out.println(!ready);运行结果
true
true
false&& 要求左右都满足;|| 只需至少一边满足。它们还会短路:&& 左边为 false、|| 左边为 true 时,右边就不必求值。第5课会用它避免对 null 调用方法。
07 / 11
Math:给常见计算一个好名字
| 方法 | 示例 | 结果 |
|---|---|---|
| Math.min | Math.min(7, 10) | 7 |
| Math.max | Math.max(18, 23) | 23 |
| Math.round | Math.round(12.6) | 13(long) |
| Math.ceil | Math.ceil(129 / 64.0) | 3.0(double) |
片段:放在 main 中,单独运行
int batches = Math.min(7, 10);
int torches = batches * 4;
long distance = Math.round(12.6);
int slots = (int) Math.ceil(129 / 64.0);
System.out.println(torches);
System.out.println(distance);
System.out.println(slots);运行结果
28
13
3火把配方会被数量较少的材料限制,因此先取煤与木棍的较小值,再乘4。round 用于本例的最近整数;ceil 用于不能漏下零头的容量计算。
08 / 11
错误不是只靠改符号就能解决

三种情况,三条不同线索
- 把 diamonds == 3 写成 diamonds = 3:询问变成赋值,意图改变。
- 整数除以0:运行时会抛出 ArithmeticException。
- 把负数当成矿石数量:语法可能合法,却不符合本作品规则。
片段:放在 main 中,单独运行
int players = 0;
boolean canDivide = players != 0;
System.out.println(canDivide);运行结果
false容量计算至少测0、63、64、65:需要的格数应为0、1、1、2。不要只测试自己已经熟悉的150。
09 / 11
先设计采矿收益的规则

- 初始数据矿石数量
火把与食物 - 计价收入减成本
- 判断利润至少50
并且有钻石 - 报告数据、利润
与判断结果
把煤、铁、金、红石、钻石的练习单价分别设为1、3、5、2、12。火把成本为每根1,食物为每份2。单价都用同一种“练习积分”,避免混用单位。
- 收入:每种矿石数量乘单价,再相加。
- 成本:火把数量加上食物数量的两倍。
- 利润:收入减成本;允许出现亏损。
- 无效数据:任何数量为负数,都先给出提示。
10 / 11
完整作品:先检查,再计算
完整程序 · MinerCalculator.java
public class MinerCalculator {
public static void main(String[] args) {
int coal = 20, iron = 8, gold = 3;
int redstone = 12, diamonds = 2;
int torchesUsed = 16, foodUsed = 4;
boolean valid = coal >= 0 && iron >= 0 && gold >= 0
&& redstone >= 0 && diamonds >= 0
&& torchesUsed >= 0 && foodUsed >= 0;
// 先借一个条件守门员;第7课会展开它。
if (!valid) {
System.out.println("数量必须是非负整数");
return;
}
int income = coal + iron * 3 + gold * 5
+ redstone * 2 + diamonds * 12;
int cost = torchesUsed + foodUsed * 2;
int profit = income - cost;
boolean richTrip = profit >= 50 && diamonds > 0;
System.out.println("收入=" + income + ", 成本=" + cost);
System.out.println("利润=" + profit);
System.out.println("丰收=" + richTrip);
}
}运行结果
收入=107, 成本=24
利润=83
丰收=true11 / 11
让边界值检查你的想法
- 算数量+ - * / %
- 标边界括号与单位
- 问真假比较运算
- 连条件&& || !
- 核对正常与边界
- 基础:389个圆石,完整组为6,余5;每格64个时至少需要7格。
- 进阶:火把至少20且有矿镐,并且食物或床至少有一种。写出带括号的判断。
- 创造:设计折扣公式,用 Math.max(1, 计算出的价格) 设置自己的最低价规则。
测试完整作品
把所有矿石设为0,保留消耗:利润应为-24,丰收为false。把 coal 设为-1:只输出数量提示。把成本调到使利润正好为50,再观察 diamonds 为0与大于0的区别。
技术参考:Java SE 11 的 Math API 与语言规范第15章表达式,官方文档见 docs.oracle.com。
TAKE IT WITH YOU
下载本课 PDF
完整课文、代码、图解与练习,选择你需要的语言。
