Java 案例:统计脚后跟传球成功次数
下面是一个完整的 Java 示例,模拟统计足球比赛中"脚后跟传球(backheel pass)"的成功次数。

需求分析
- 一次脚后跟传球需要记录:传球者、接球者、是否成功
- 成功条件:传球到位(同一队接到球),且没有被对方拦截
- 统计每名球员、每支球队的脚后跟传球成功次数
完整代码
import java.util.*;
import java.util.stream.Collectors;
// 传球类型枚举
enum PassType {
NORMAL, BACKHEEL // 普通传球 / 脚后跟传球
}
// 传球记录
class Pass {
private final String fromPlayer; // 传球球员
private final String toPlayer; // 接球球员
private final String team; // 所属球队
private final PassType type; // 传球类型
private final boolean success; // 是否成功
public Pass(String fromPlayer, String toPlayer, String team,
PassType type, boolean success) {
this.fromPlayer = fromPlayer;
this.toPlayer = toPlayer;
this.team = team;
this.type = type;
this.success = success;
}
public String getFromPlayer() { return fromPlayer; }
public String getTeam() { return team; }
public PassType getType() { return type; }
public boolean isSuccess() { return success; }
}
public class BackheelPassStats {
public static void main(String[] args) {
// 模拟比赛传球数据(可替换为从文件/数据库读取)
List<Pass> passes = Arrays.asList(
new Pass("梅西", "苏亚雷斯", "巴萨", PassType.BACKHEEL, true),
new Pass("梅西", "内马尔", "巴萨", PassType.BACKHEEL, false),
new Pass("阿尔巴","梅西", "巴萨", PassType.BACKHEEL, true),
new Pass("苏亚雷斯","梅西", "巴萨", PassType.BACKHEEL, true),
new Pass("内马尔","苏亚雷斯", "巴萨", PassType.NORMAL, true),
new Pass("莫德里奇","本泽马", "皇马", PassType.BACKHEEL, true),
new Pass("克罗斯","莫德里奇", "皇马", PassType.BACKHEEL, false),
new Pass("本泽马","维尼修斯", "皇马", PassType.BACKHEEL, true)
);
// 1. 筛选出所有"脚后跟传球"
List<Pass> backheels = passes.stream()
.filter(p -> p.getType() == PassType.BACKHEEL)
.collect(Collectors.toList());
// 2. 总次数 & 成功次数
long total = backheels.size();
long success = backheels.stream().filter(Pass::isSuccess).count();
System.out.println("===== 脚后跟传球统计(全场)=====");
System.out.println("总次数 : " + total);
System.out.println("成功次数 : " + success);
System.out.println("成功率 : " +
(total == 0 ? "0%" :
String.format("%.1f%%", success * 100.0 / total)));
// 3. 按球员统计成功次数
Map<String, Long> byPlayer = backheels.stream()
.filter(Pass::isSuccess)
.collect(Collectors.groupingBy(
Pass::getFromPlayer,
Collectors.counting()));
System.out.println("\n===== 各球员脚后跟传球成功次数 =====");
byPlayer.entrySet().stream()
.sorted(Map.Entry.<String, Long>comparingByValue().reversed())
.forEach(e -> System.out.printf("%-6s : %d 次%n",
e.getKey(), e.getValue()));
// 4. 按球队统计成功次数
Map<String, Long> byTeam = backheels.stream()
.filter(Pass::isSuccess)
.collect(Collectors.groupingBy(
Pass::getTeam,
Collectors.counting()));
System.out.println("\n===== 各球队脚后跟传球成功次数 =====");
byTeam.forEach((team, cnt) ->
System.out.printf("%-4s : %d 次%n", team, cnt));
}
}
运行结果
===== 脚后跟传球统计(全场)=====
总次数 : 7
成功次数 : 5
成功率 : 71.4%
===== 各球员脚后跟传球成功次数 =====
梅西 : 1 次
阿尔巴 : 1 次
苏亚雷斯 : 1 次
莫德里奇 : 1 次
本泽马 : 1 次
===== 各球队脚后跟传球成功次数 =====
巴萨 : 3 次
皇马 : 2 次
代码要点
| 步骤 | 说明 |
|---|---|
| 枚举 PassType | 明确区分脚后跟传球与普通传球,避免硬编码 |
| filter | 先筛出 BACKHEEL,再筛出 success == true |
| groupingBy + counting | 一行代码完成"按球员/球队分组计数" |
| sorted + reversed | 结果按成功次数降序排列 |
| String.format | 百分比、对齐输出更美观 |
扩展建议
- 接真实数据:从 CSV/JSON 文件或数据库读取
Pass列表(可用 Jackson、OpenCSV) - 加时间维度:为
Pass增加minute字段,统计每个时间段内的脚后跟传球 - 加区域维度:增加
x, y坐标,统计脚后跟传球是否发生在"禁区"等关键区域 - 连续配合分析:用滑动窗口分析"脚后跟传球→助攻"的连线
如果你需要我把这个改成读取 CSV 或 Spring Boot 接口版本,告诉我即可 👍