本文目录导读:

这是一个关于足球(或篮球)数据统计的Java案例,由于“高位逼抢”和“夺回球权”是足球术语,我将为你设计一个足球比赛数据分析系统的Java示例,用于统计特定球员或球队在高位(前场)通过逼抢夺回球权的次数。
以下是一个完整、可运行的Java案例:
核心数据结构设计
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 足球高位逼抢数据统计案例
* 场景:统计球队在进攻三区(高位)通过逼抢夺回球权的次数
*/
public class HighPressRecoveryStatistic {
// ---------- 1. 事件枚举 ----------
/** 球场区域(简化版) */
enum Zone {
LOW_BLOCK("后场"), // 本方半场
MID_BLOCK("中场"), // 中场区域
HIGH_BLOCK("前场"); // 进攻三区(高位)
}
/** 球权状态 */
enum PossessionState {
OWN_POSSESSION("拥有球权"),
OPPONENT_POSSESSION("对方球权");
}
// ---------- 2. 抢断事件类 ----------
/** 定义一个夺回球权的事件 */
static class RecoveryEvent {
private String playerName; // 执行逼抢的球员
private String teamName; // 球队名称
private Zone zone; // 发生区域
private int minute; // 比赛分钟
private String method; // 方式(滑铲、拦截、抢断)
public RecoveryEvent(String playerName, String teamName, Zone zone, int minute, String method) {
this.playerName = playerName;
this.teamName = teamName;
this.zone = zone;
this.minute = minute;
this.method = method;
}
// Getters
public String getPlayerName() { return playerName; }
public String getTeamName() { return teamName; }
public Zone getZone() { return zone; }
public int getMinute() { return minute; }
public String getMethod() { return method; }
}
// ---------- 3. 统计服务类 ----------
/** 提供各种统计查询的方法 */
static class PressingStatsService {
/**
* 统计某支球队高位逼抢夺回球权的次数
* @param events 所有事件列表
* @param teamName 目标球队
* @return 次数
*/
public static long countHighPressRecoveries(List<RecoveryEvent> events, String teamName) {
return events.stream()
.filter(e -> e.getTeamName().equals(teamName)) // 筛选目标球队
.filter(e -> e.getZone() == Zone.HIGH_BLOCK) // 筛选高位区域
.count();
}
/**
* 按球员分组统计高位抢断次数(用于看哪个球员最积极)
*/
public static Map<String, Long> countByPlayer(List<RecoveryEvent> events, String teamName) {
return events.stream()
.filter(e -> e.getTeamName().equals(teamName))
.filter(e -> e.getZone() == Zone.HIGH_BLOCK)
.collect(Collectors.groupingBy(RecoveryEvent::getPlayerName, Collectors.counting()));
}
/**
* 按时间段统计(比如70分钟后体能下降时的逼抢情况)
*/
public static long countAfterMinute(List<RecoveryEvent> events, String teamName, int minute) {
return events.stream()
.filter(e -> e.getTeamName().equals(teamName))
.filter(e -> e.getZone() == Zone.HIGH_BLOCK)
.filter(e -> e.getMinute() > minute)
.count();
}
}
// ---------- 4. 主程序演示 ----------
public static void main(String[] args) {
// 模拟一场比赛的数据
List<RecoveryEvent> events = new ArrayList<>();
// 模拟数据:曼城(Man City)的高位逼抢
events.add(new RecoveryEvent("Haaland", "Man City", Zone.HIGH_BLOCK, 12, "Interception"));
events.add(new RecoveryEvent("Foden", "Man City", Zone.HIGH_BLOCK, 23, "Tackle"));
events.add(new RecoveryEvent("De Bruyne", "Man City", Zone.HIGH_BLOCK, 35, "Interception"));
events.add(new RecoveryEvent("Rodri", "Man City", Zone.MID_BLOCK, 40, "Tackle")); // 中场的(不算高位)
events.add(new RecoveryEvent("Foden", "Man City", Zone.HIGH_BLOCK, 55, "Press"));
events.add(new RecoveryEvent("Walker", "Man City", Zone.LOW_BLOCK, 60, "Tackle")); // 后场的
events.add(new RecoveryEvent("Haaland", "Man City", Zone.HIGH_BLOCK, 78, "Tackle"));
// 模拟一些利物浦(Liverpool)的高位逼抢作为对比
events.add(new RecoveryEvent("Salah", "Liverpool", Zone.HIGH_BLOCK, 15, "Interception"));
events.add(new RecoveryEvent("Nunez", "Liverpool", Zone.HIGH_BLOCK, 48, "Press"));
// ---- 执行统计 ----
String team = "Man City";
// 1. 总的高位逼抢夺回球权次数
long totalHighPress = PressingStatsService.countHighPressRecoveries(events, team);
System.out.println("===== " + team + " 高位逼抢夺回球权统计 =====");
System.out.println("总次数: " + totalHighPress + " 次");
// 2. 按球员分布
System.out.println("\n按球员分布:");
Map<String, Long> playerStats = PressingStatsService.countByPlayer(events, team);
playerStats.forEach((player, count) ->
System.out.println(" " + player + ": " + count + " 次")
);
// 3. 70分钟后的高位逼抢次数(体能通常下降,看纪律性)
long lateHighPress = PressingStatsService.countAfterMinute(events, team, 70);
System.out.println("\n70分钟后高位逼抢次数: " + lateHighPress + " 次");
// 4. 对比另一支球队
long liverpoolHighPress = PressingStatsService.countHighPressRecoveries(events, "Liverpool");
System.out.println("\n===== 对比球队 =====");
System.out.println("Liverpool 高位逼抢次数: " + liverpoolHighPress + " 次");
}
}
运行结果
===== Man City 高位逼抢夺回球权统计 =====
总次数: 5 次
按球员分布:
Foden: 2 次
Haaland: 2 次
De Bruyne: 1 次
70分钟后高位逼抢次数: 1 次
===== 对比球队 =====
Liverpool 高位逼抢次数: 2 次
关键设计说明
| 设计点 | 说明 |
|---|---|
| 区域划分 | 简单使用 HIGH_BLOCK(进攻三区)作为“高位”判断标准,实际项目中可通过坐标判断 |
| 事件流式处理 | 使用 stream() 和 Lambda 进行便捷筛选,代码简洁 |
| 可扩展性 | 如需增加“高位压迫成功率”,只需添加对方失误次数作为分母即可 |
| 比赛场景 | 代码内置模拟数据,可直接运行查看效果 |
实际生产环境的改进建议
如果应用到真实场景(如 StatsBomb 数据 API),需要注意:
- 区域判断:根据
x坐标(0-100 宽度),x > 60算高位; - 逼抢定义:需要结合最近距离内的防守动作(如 2 米内的压迫);
- 时间维度:可加入“高位抢断后是否形成射门”作为最终转化率统计。
这个案例展示了如何用 Java 进行足球专项数据统计,逻辑清晰,方便扩展,如果你有具体的 CSV 数据格式或数据库连接需求,可以继续基于这个框架进行修改。