Java案例:统计低位防守解围次数
下面是一个完整的Java案例,用于统计足球比赛中低位防守解围的次数。

场景说明
- 低位防守(Low Block):球队退守到本方半场,防线靠近禁区。
- 解围(Clearance):防守球员将球踢出危险区域。
- 统计条件:解围发生时,球员位置在本方半场且靠近禁区(低位区域)。
完整代码
import java.util.*;
import java.util.stream.Collectors;
// 解围事件实体
class ClearanceEvent {
private String playerName; // 球员姓名
private String team; // 所属球队
private int minute; // 比赛分钟
private double x; // 场地X坐标(0-105米,0为本方球门)
private double y; // 场地Y坐标(0-68米)
private boolean isOwnHalf; // 是否在本方半场
public ClearanceEvent(String playerName, String team, int minute,
double x, double y, boolean isOwnHalf) {
this.playerName = playerName;
this.team = team;
this.minute = minute;
this.x = x;
this.y = y;
this.isOwnHalf = isOwnHalf;
}
public String getPlayerName() { return playerName; }
public String getTeam() { return team; }
public int getMinute() { return minute; }
public double getX() { return x; }
public double getY() { return y; }
public boolean isOwnHalf() { return isOwnHalf; }
@Override
public String toString() {
return String.format("%s(%s) 第%d分钟 (%.1f, %.1f)",
playerName, team, minute, x, y);
}
}
// 统计结果
class LowBlockStats {
private int totalCount; // 总次数
private Map<String, Long> playerCount; // 按球员统计
private Map<String, Long> teamCount; // 按球队统计
private List<ClearanceEvent> details; // 明细
public LowBlockStats(int totalCount, Map<String, Long> playerCount,
Map<String, Long> teamCount, List<ClearanceEvent> details) {
this.totalCount = totalCount;
this.playerCount = playerCount;
this.teamCount = teamCount;
this.details = details;
}
public void print() {
System.out.println("====== 低位防守解围统计 ======");
System.out.println("总次数:" + totalCount);
System.out.println("\n--- 按球队 ---");
teamCount.forEach((k, v) -> System.out.println(k + " : " + v + " 次"));
System.out.println("\n--- 按球员 ---");
playerCount.forEach((k, v) -> System.out.println(k + " : " + v + " 次"));
System.out.println("\n--- 解围明细 ---");
details.forEach(System.out::println);
}
}
public class LowBlockClearanceAnalyzer {
// 低位防守区域判定:本方半场 + 距离本方球门 40 米以内
private static final double LOW_BLOCK_X_THRESHOLD = 40.0;
/**
* 判断是否为低位防守解围
* 条件:
* 1. 在本方半场
* 2. 距离本方球门 40m 以内(x < 40)
*/
public static boolean isLowBlockClearance(ClearanceEvent e) {
return e.isOwnHalf() && e.getX() < LOW_BLOCK_X_THRESHOLD;
}
/**
* 统计低位防守解围次数
*/
public static LowBlockStats analyze(List<ClearanceEvent> events) {
// 过滤出低位防守解围
List<ClearanceEvent> lowBlocks = events.stream()
.filter(LowBlockClearanceAnalyzer::isLowBlockClearance)
.collect(Collectors.toList());
// 按球员统计
Map<String, Long> byPlayer = lowBlocks.stream()
.collect(Collectors.groupingBy(
ClearanceEvent::getPlayerName, Collectors.counting()));
// 按球队统计
Map<String, Long> byTeam = lowBlocks.stream()
.collect(Collectors.groupingBy(
ClearanceEvent::getTeam, Collectors.counting()));
return new LowBlockStats(lowBlocks.size(), byPlayer, byTeam, lowBlocks);
}
public static void main(String[] args) {
// 模拟数据:一场比赛的解围事件
List<ClearanceEvent> events = Arrays.asList(
new ClearanceEvent("李磊", "主队", 12, 20, 30, true), // ✅ 低位
new ClearanceEvent("张琳芃", "主队", 25, 35, 40, true), // ✅ 低位
new ClearanceEvent("蒋光太", "主队", 33, 45, 30, true), // ❌ x>=40
new ClearanceEvent("李磊", "主队", 44, 15, 20, true), // ✅ 低位
new ClearanceEvent("王刚", "主队", 58, 55, 35, false), // ❌ 对方半场
new ClearanceEvent("张琳芃", "主队", 67, 25, 25, true), // ✅ 低位
new ClearanceEvent("蒋光太", "主队", 78, 10, 15, true), // ✅ 低位
new ClearanceEvent("李磊", "主队", 85, 60, 30, false), // ❌ 对方半场
new ClearanceEvent("对方A", "客队", 20, 30, 40, true), // ✅ 低位
new ClearanceEvent("对方B", "客队", 55, 18, 22, true) // ✅ 低位
);
LowBlockStats stats = analyze(events);
stats.print();
}
}
输出结果
====== 低位防守解围统计 ======
总次数:7
--- 按球队 ---
主队 : 5 次
客队 : 2 次
--- 按球员 ---
李磊 : 2 次
张琳芃 : 2 次
蒋光太 : 1 次
对方A : 1 次
对方B : 1 次
--- 解围明细 ---
李磊(主队) 第12分钟 (20.0, 30.0)
张琳芃(主队) 第25分钟 (35.0, 40.0)
李磊(主队) 第44分钟 (15.0, 20.0)
张琳芃(主队) 第67分钟 (25.0, 25.0)
蒋光太(主队) 第78分钟 (10.0, 15.0)
对方A(客队) 第20分钟 (30.0, 40.0)
对方B(客队) 第55分钟 (18.0, 22.0)
核心逻辑解析
| 判定项 | 条件 | 说明 |
|---|---|---|
| 本方半场 | isOwnHalf == true |
防守姿态 |
| 低位区域 | x < 40 |
距本方球门40米内 |
| 事件类型 | ClearanceEvent |
解围动作 |
可扩展方向
- 真实数据接入:可从 Opta / StatsBomb 的 JSON 事件数据中读取。
- 增加时间维度:如统计上下半场、每15分钟时段的解围次数。
- 空间热力图:结合 x/y 坐标生成解围位置分布图。
- 同比分析:对比两队低位解围次数,生成防御压力评估。
如需接入真实比赛数据(如 StatsBomb 开放数据),可以告诉我,我可以补充数据解析部分。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播