根据java案例,进攻三区传球成功率?

wen java案例 3

Java 案例:计算进攻三区传球成功率

需求分析

进攻三区(Final Third) 通常指足球场靠近对方球门的 1/3 区域,是进攻组织、制造威胁的关键区域。

根据java案例,进攻三区传球成功率?

  • 传球成功率 = 成功传球次数 ÷ 总传球次数 × 100%

核心 Java 代码实现

定义传球数据模型

/**
 * 传球记录
 */
public class PassRecord {
    private String passer;        // 传球球员
    private String receiver;      // 接球球员
    private int startX;           // 传球起点X坐标(0-100,代表球场长度)
    private int startY;           // 传球起点Y坐标(0-100)
    private int endX;             // 传球终点X坐标
    private int endY;             // 传球终点Y坐标
    private boolean success;      // 是否成功
    public PassRecord(String passer, String receiver,
                      int startX, int startY,
                      int endX, int endY, boolean success) {
        this.passer = passer;
        this.receiver = receiver;
        this.startX = startX;
        this.startY = startY;
        this.endX = endX;
        this.endY = endY;
        this.success = success;
    }
    // 判断传球起点是否在进攻三区(假设进攻方向为左往右,x >= 66 为进攻三区)
    public boolean isInFinalThird() {
        return this.startX >= 66;
    }
    // getter
    public boolean isSuccess() { return success; }
    public String getPasser() { return passer; }
}

💡 坐标约定:球场从本方球门(x=0)到对方球门(x=100),x ≥ 66 即进攻三区。


统计计算逻辑

import java.util.*;
import java.util.stream.Collectors;
public class FinalThirdPassAnalyzer {
    /**
     * 计算某球员在进攻三区的传球成功率
     */
    public static double calcPlayerFinalThirdSuccessRate(
            List<PassRecord> records, String playerName) {
        int total = 0;
        int success = 0;
        for (PassRecord r : records) {
            if (r.getPasser().equals(playerName) && r.isInFinalThird()) {
                total++;
                if (r.isSuccess()) success++;
            }
        }
        return total == 0 ? 0.0 : (success * 100.0 / total);
    }
    /**
     * 计算全队在进攻三区的传球成功率
     */
    public static double calcTeamFinalThirdSuccessRate(List<PassRecord> records) {
        int total = 0, success = 0;
        for (PassRecord r : records) {
            if (r.isInFinalThird()) {
                total++;
                if (r.isSuccess()) success++;
            }
        }
        return total == 0 ? 0.0 : (success * 100.0 / total);
    }
    /**
     * 按球员分组统计(Java 8 Stream 写法)
     */
    public static Map<String, String> analyzeByPlayer(List<PassRecord> records) {
        return records.stream()
                .filter(PassRecord::isInFinalThird)
                .collect(Collectors.groupingBy(
                        PassRecord::getPasser,
                        Collectors.collectingAndThen(Collectors.toList(), list -> {
                            long total = list.size();
                            long success = list.stream().filter(PassRecord::isSuccess).count();
                            double rate = total == 0 ? 0 : success * 100.0 / total;
                            return String.format("传球%d次 / 成功%d次 / 成功率%.2f%%",
                                    total, success, rate);
                        })
                ));
    }
}

测试 Main 方法

public class Main {
    public static void main(String[] args) {
        List<PassRecord> passes = Arrays.asList(
            // passer, receiver, startX, startY, endX, endY, success
            new PassRecord("德布劳内", "哈兰德", 70, 30, 85, 40, true),
            new PassRecord("德布劳内", "福登",   75, 50, 80, 60, true),
            new PassRecord("德布劳内", "格拉利什", 68, 20, 60, 25, false),
            new PassRecord("B席",     "德布劳内", 72, 40, 78, 45, true),
            new PassRecord("B席",     "哈兰德",   80, 45, 88, 50, false),
            new PassRecord("福登",    "哈兰德",   69, 35, 90, 50, true),
            new PassRecord("罗德里",   "B席",     50, 50, 70, 55, true)   // 起点不在进攻三区,不计入
        );
        // 全队进攻三区传球成功率
        double teamRate = FinalThirdPassAnalyzer.calcTeamFinalThirdSuccessRate(passes);
        System.out.printf("【全队】进攻三区传球成功率: %.2f%%%n", teamRate);
        // 各球员统计
        System.out.println("\n【按球员统计】");
        FinalThirdPassAnalyzer.analyzeByPlayer(passes)
                .forEach((player, stat) -> System.out.println(player + " → " + stat));
        // 单球员查询
        double kdbRate = FinalThirdPassAnalyzer.calcPlayerFinalThirdSuccessRate(passes, "德布劳内");
        System.out.printf("%n德布劳内进攻三区传球成功率: %.2f%%%n", kdbRate);
    }
}

运行结果

【全队】进攻三区传球成功率: 66.67%
【按球员统计】
德布劳内 → 传球3次 / 成功2次 / 成功率66.67%
B席 → 传球2次 / 成功1次 / 成功率50.00%
福登 → 传球1次 / 成功1次 / 成功率100.00%
德布劳内进攻三区传球成功率: 66.67%

关键设计点

设计点 说明
区域判定 用 startX >= 66 判断是否进攻三区,可按实际需求调整(有的统计按终点判定)
坐标系统 通常采用 0-100 归一化坐标,方便不同比赛数据统一
成功定义 接球方成功控制住球(非被断、非出界)
Stream 优化 更适合多球员大量数据的分组统计
扩展性 可增加 passType(短传/长传)、pressure(压迫强度)等字段

可选扩展功能

  1. 按比赛分阶段:统计每 15 分钟区间的进攻三区成功率
  2. 对比分析:主客队进攻三区传球成功率对比
  3. 可视化:用 JFreeChart 输出柱状图
  4. 读取真实数据:从 CSV / JSON(如 StatsBomb 数据)批量导入

如果你有具体的数据格式(如从 Opta、StatsBomb 导出),我可以帮你写对应的解析和统计代码。

上一篇这个java案例是否追踪了伤病恢复进度?

下一篇当前分类已是最新一篇

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