Java 案例:统计单刀球成功率
需求分析
单刀球指进攻球员一对一面对守门员的射门机会。成功率 = 进球数 / 单刀球总次数。

需要统计的字段:
- 球员姓名
- 单刀球总次数
- 进球数
- 成功率(进球 / 总次数)
代码实现
实体类 Player
public class Player {
private String name; // 球员姓名
private int totalChances; // 单刀球总次数
private int goals; // 单刀球进球数
public Player(String name, int totalChances, int goals) {
this.name = name;
this.totalChances = totalChances;
this.goals = goals;
}
// 单刀球成功率
public double getSuccessRate() {
if (totalChances == 0) return 0.0;
return (double) goals / totalChances;
}
public String getName() { return name; }
public int getTotalChances() { return totalChances; }
public int getGoals() { return goals; }
@Override
public String toString() {
return String.format("%-8s 单刀次数: %2d 进球: %2d 成功率: %.2f%%",
name, totalChances, goals, getSuccessRate() * 100);
}
}
主程序 OneOnOneStats
import java.util.*;
import java.util.stream.Collectors;
public class OneOnOneStats {
public static void main(String[] args) {
// 模拟数据:球员、单刀次数、进球数
List<Player> players = Arrays.asList(
new Player("梅西", 30, 22),
new Player("C罗", 28, 19),
new Player("姆巴佩", 25, 18),
new Player("哈兰德", 20, 15),
new Player("凯恩", 22, 14),
new Player("萨拉赫", 26, 16)
);
System.out.println("========== 各球员单刀球统计 ==========");
players.forEach(System.out::println);
// 1. 全队总成功率
int totalChances = players.stream().mapToInt(Player::getTotalChances).sum();
int totalGoals = players.stream().mapToInt(Player::getGoals).sum();
double teamRate = (double) totalGoals / totalChances;
System.out.println("\n========== 全队汇总 ==========");
System.out.printf("总单刀次数: %d%n", totalChances);
System.out.printf("总进球数: %d%n", totalGoals);
System.out.printf("全队成功率: %.2f%%%n", teamRate * 100);
// 2. 单刀成功率排名(降序)
System.out.println("\n========== 单刀成功率排名 ==========");
List<Player> ranking = players.stream()
.sorted(Comparator.comparingDouble(Player::getSuccessRate).reversed())
.collect(Collectors.toList());
for (int i = 0; i < ranking.size(); i++) {
Player p = ranking.get(i);
System.out.printf("第%d名 %-6s 成功率 %.2f%%%n",
i + 1, p.getName(), p.getSuccessRate() * 100);
}
// 3. 找出成功率高于全队平均的球员
System.out.println("\n========== 成功率高于全队平均的球员 ==========");
players.stream()
.filter(p -> p.getSuccessRate() > teamRate)
.forEach(p -> System.out.printf("%s (%.2f%%)%n",
p.getName(), p.getSuccessRate() * 100));
// 4. 按成功率分组:高/中/低
System.out.println("\n========== 成功率分级 ==========");
Map<String, List<Player>> groups = players.stream()
.collect(Collectors.groupingBy(p -> {
double r = p.getSuccessRate();
if (r >= 0.75) return "优秀(≥75%)";
if (r >= 0.60) return "良好(60%-75%)";
return "一般(<60%)";
}));
groups.forEach((level, list) -> {
System.out.println(level + ":");
list.forEach(p -> System.out.printf(" %s %.2f%%%n",
p.getName(), p.getSuccessRate() * 100));
});
}
}
运行结果示例
========== 各球员单刀球统计 ==========
梅西 单刀次数: 30 进球: 22 成功率: 73.33%
C罗 单刀次数: 28 进球: 19 成功率: 67.86%
姆巴佩 单刀次数: 25 进球: 18 成功率: 72.00%
哈兰德 单刀次数: 20 进球: 15 成功率: 75.00%
凯恩 单刀次数: 22 进球: 14 成功率: 63.64%
萨拉赫 单刀次数: 26 进球: 16 成功率: 61.54%
========== 全队汇总 ==========
总单刀次数: 151
总进球数: 104
全队成功率: 68.87%
========== 单刀成功率排名 ==========
第1名 哈兰德 成功率 75.00%
第2名 梅西 成功率 73.33%
第3名 姆巴佩 成功率 72.00%
第4名 C罗 成功率 67.86%
第5名 凯恩 成功率 63.64%
第6名 萨拉赫 成功率 61.54%
========== 成功率高于全队平均的球员 ==========
哈兰德 (75.00%)
梅西 (73.33%)
姆巴佩 (72.00%)
========== 成功率分级 ==========
优秀(≥75%):
哈兰德 75.00%
良好(60%-75%):
梅西 73.33%
姆巴佩 72.00%
C罗 67.86%
凯恩 63.64%
萨拉赫 61.54%
关键点说明
| 要点 | 说明 |
|---|---|
| 防止除零 | totalChances == 0 时返回 0.0,避免 ArithmeticException |
| 精度处理 | 用 double 强转输出百分比,String.format("%.2f%%") 保留两位小数 |
| 流式聚合 | mapToInt().sum() 求总量;groupingBy 分类统计 |
| 排序 | Comparator.comparingDouble(...).reversed() 实现降序排名 |
可扩展方向
- 从文件/数据库读取数据(CSV、MySQL)
- 按赛事/时间段筛选(如只统计欧冠、联赛)
- 对比不同赛季成功率趋势
- 输出图表(集成 JFreeChart)
- 加入"单刀球转化期望值(xG)" 生成更专业指标
如果你需要 从 CSV 读取数据 或 接入数据库 的版本,我可以继续补充。