java案例统计高位逼抢夺回球权几次?

wen java案例 5

本文目录导读:

java案例统计高位逼抢夺回球权几次?

  1. 核心数据结构设计
  2. 运行结果
  3. 关键设计说明
  4. 实际生产环境的改进建议

这是一个关于足球(或篮球)数据统计的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),需要注意:

  1. 区域判断:根据 x 坐标(0-100 宽度),x > 60 算高位;
  2. 逼抢定义:需要结合最近距离内的防守动作(如 2 米内的压迫);
  3. 时间维度:可加入“高位抢断后是否形成射门”作为最终转化率统计。

这个案例展示了如何用 Java 进行足球专项数据统计,逻辑清晰,方便扩展,如果你有具体的 CSV 数据格式或数据库连接需求,可以继续基于这个框架进行修改。

抱歉,评论功能暂时关闭!