Java案例:统计反击次数,哪队更高效?
这是一个典型的"用Java解决实际问题"的案例,下面我给出完整的分析思路、代码实现和结论。

问题理解
"反击次数"通常指体育比赛(足球、篮球等)中防守方抢断/断球后发动快攻的次数,要判断"哪队更高效",需要:
- 统计每队的反击次数
- 对比效率——不能只看次数多少,而要看"反击转化为得分"的比例
数据模型设计
// 一次反击事件
class CounterAttack {
String team; // 球队
boolean scored; // 是否转化为得分
int duration; // 反击耗时(秒)
public CounterAttack(String team, boolean scored, int duration) {
this.team = team;
this.scored = scored;
this.duration = duration;
}
}
核心统计逻辑(Java 8 Stream)
import java.util.*;
import java.util.stream.*;
public class CounterAttackAnalyzer {
public static void main(String[] args) {
List<CounterAttack> events = List.of(
new CounterAttack("A队", true, 8),
new CounterAttack("A队", false, 6),
new CounterAttack("A队", true, 7),
new CounterAttack("B队", true, 5),
new CounterAttack("B队", true, 6),
new CounterAttack("B队", false, 9),
new CounterAttack("B队", true, 4)
);
// 1. 按队伍分组统计
Map<String, List<CounterAttack>> byTeam = events.stream()
.collect(Collectors.groupingBy(e -> e.team));
// 2. 计算每队的次数、成功数、效率
Map<String, double[]> stats = new LinkedHashMap<>();
byTeam.forEach((team, list) -> {
long total = list.size();
long success = list.stream().filter(e -> e.scored).count();
double efficiency = total == 0 ? 0 : (double) success / total;
stats.put(team, new double[]{total, success, efficiency});
});
// 3. 输出对比
System.out.println("队伍\t反击次数\t成功次数\t反击效率");
stats.forEach((team, s) ->
System.out.printf("%s\t%.0f\t\t%.0f\t\t%.1f%%%n",
team, s[0], s[1], s[2] * 100));
// 4. 判断哪队更高效(按效率)
String best = stats.entrySet().stream()
.max(Comparator.comparingDouble(e -> e.getValue()[2]))
.map(Map.Entry::getKey)
.orElse("无");
System.out.println("\n>>> 反击效率更高的队伍:" + best);
}
}
运行结果
队伍 反击次数 成功次数 反击效率
A队 3 2 66.7%
B队 4 3 75.0%
>>> 反击效率更高的队伍:B队
| 对比维度 | A队 | B队 | 说明 |
|---|---|---|---|
| 反击次数 | 3 | 4 | B队发动更多 |
| 成功次数 | 2 | 3 | B队转化更多 |
| 反击效率 | 7% | 0% | B队更高效 |
B队更高效:虽然只多1次反击,但成功率高出8.3个百分点。
如果追求"极致高效"的优化写法
如果想同时兼顾次数优势和效率优势,可以引入综合评分:
// 综合评分 = 成功次数 × 效率(次数多且效率高的队得分更高)
Comparator<Map.Entry<String, double[]>> comparator =
Comparator.comparingDouble(e -> e.getValue()[1] * e.getValue()[2]);
这样能避免"只发动1次且成功1次 = 100%效率"的极端情况误导判断。
这个案例的启示
- 不能只看绝对次数——次数多但效率低,实际收益可能更差
- 效率是比例指标——要结合样本量看,样本太小(如1次反击100%成功)不可靠
- Stream分组聚合是Java处理这类统计问题的利器,代码简洁且易扩展(可加耗时、球员等维度)
如果你有具体的比赛数据格式(CSV/数据库/JSON),我可以帮你改成对应的读取版本。