java案例统计头球争顶成功率如何?

wen java案例 3

用Java统计头球争顶成功率案例

下面给你一个完整的Java实现方案,包含数据模型、统计算法、示例代码,可以直接运行。

java案例统计头球争顶成功率如何?

需求分析

头球争顶成功率公式:

成功率 = 成功争顶次数 / 总争顶次数 × 100%

通常需要按球员球队比赛等维度统计。

数据模型

import java.util.*;
/**
 * 争顶事件(一次头球争顶)
 */
class AerialDuel {
    private String playerName;   // 球员姓名
    private String team;         // 所属球队
    private boolean won;         // 是否争顶成功
    public AerialDuel(String playerName, String team, boolean won) {
        this.playerName = playerName;
        this.team = team;
        this.won = won;
    }
    public String getPlayerName() { return playerName; }
    public String getTeam() { return team; }
    public boolean isWon() { return won; }
}

统计结果封装

class AerialStat {
    private String name;
    private int total;      // 总争顶次数
    private int won;        // 成功次数
    public AerialStat(String name) {
        this.name = name;
    }
    public void add(boolean isWon) {
        total++;
        if (isWon) won++;
    }
    /** 成功率(百分比,保留一位小数) */
    public double getSuccessRate() {
        if (total == 0) return 0.0;
        return Math.round(won * 1000.0 / total) / 10.0;
    }
    public String getName() { return name; }
    public int getTotal() { return total; }
    public int getWon() { return won; }
    @Override
    public String toString() {
        return String.format("%-10s 争顶:%2d 成功:%2d 成功率:%.1f%%",
                name, total, won, getSuccessRate());
    }
}

统计核心类

import java.util.*;
import java.util.stream.Collectors;
public class AerialDuelAnalyzer {
    private final List<AerialDuel> duels = new ArrayList<>();
    public void addDuel(AerialDuel duel) {
        duels.add(duel);
    }
    /** 按球员统计 */
    public Map<String, AerialStat> statByPlayer() {
        Map<String, AerialStat> map = new LinkedHashMap<>();
        for (AerialDuel d : duels) {
            map.computeIfAbsent(d.getPlayerName(), AerialStat::new)
               .add(d.isWon());
        }
        return map;
    }
    /** 按球队统计 */
    public Map<String, AerialStat> statByTeam() {
        Map<String, AerialStat> map = new LinkedHashMap<>();
        for (AerialDuel d : duels) {
            map.computeIfAbsent(d.getTeam(), AerialStat::new)
               .add(d.isWon());
        }
        return map;
    }
    /** 按球员统计并排序(成功率降序) */
    public List<AerialStat> rankByPlayer() {
        return statByPlayer().values().stream()
                .sorted(Comparator.comparingDouble(AerialStat::getSuccessRate).reversed())
                .collect(Collectors.toList());
    }
}

测试运行

public class Main {
    public static void main(String[] args) {
        AerialDuelAnalyzer analyzer = new AerialDuelAnalyzer();
        // 模拟一场比赛的头球争顶数据
        // 球员A:5次争顶,3次成功
        analyzer.addDuel(new AerialDuel("张三", "红队", true));
        analyzer.addDuel(new AerialDuel("张三", "红队", true));
        analyzer.addDuel(new AerialDuel("张三", "红队", false));
        analyzer.addDuel(new AerialDuel("张三", "红队", true));
        analyzer.addDuel(new AerialDuel("张三", "红队", false));
        // 球员B:4次争顶,4次成功
        analyzer.addDuel(new AerialDuel("李四", "红队", true));
        analyzer.addDuel(new AerialDuel("李四", "红队", true));
        analyzer.addDuel(new AerialDuel("李四", "红队", true));
        analyzer.addDuel(new AerialDuel("李四", "红队", true));
        // 球员C(蓝队):3次争顶,1次成功
        analyzer.addDuel(new AerialDuel("王五", "蓝队", false));
        analyzer.addDuel(new AerialDuel("王五", "蓝队", true));
        analyzer.addDuel(new AerialDuel("王五", "蓝队", false));
        // 球员D(蓝队):2次争顶,1次成功
        analyzer.addDuel(new AerialDuel("赵六", "蓝队", false));
        analyzer.addDuel(new AerialDuel("赵六", "蓝队", true));
        // ===== 输出按球员排名 =====
        System.out.println("===== 球员头球争顶成功率排名 =====");
        analyzer.rankByPlayer().forEach(System.out::println);
        // ===== 输出按球队统计 =====
        System.out.println("\n===== 球队头球争顶成功率 =====");
        analyzer.statByTeam().forEach((team, stat) -> System.out.println(stat));
    }
}

运行结果

===== 球员头球争顶成功率排名 =====
李四         争顶: 4 成功: 4 成功率:100.0%
张三         争顶: 5 成功: 3 成功率:60.0%
赵六         争顶: 2 成功: 1 成功率:50.0%
王五         争顶: 3 成功: 1 成功率:33.3%
===== 球队头球争顶成功率 =====
红队         争顶: 9 成功: 7 成功率:77.8%
蓝队         争顶: 5 成功: 2 成功率:40.0%

进阶扩展建议

扩展点 说明
数据来源 从 CSV/数据库/JSON 读取比赛事件
分区域统计 增加 zone 字段(前场/中场/后场)分析争顶位置
时间维度 增加 minute 字段,统计各时段成功率
SQL 实现 SELECT player, COUNT(*), SUM(won)/COUNT(*)*100 FROM duels GROUP BY player
可视化 导出结果到 Excel(Apache POI)或用 JFreeChart 画柱状图
多场比赛 传入选定的 matchId 过滤后再统计

关键设计要点

  1. computeIfAbsent + 累加器 避免了多次遍历的复杂度,O(n) 一次扫描完成统计。
  2. *成功率计算用 `Math.round(x1000)/10.0`** 保证保留一位小数且不产生浮点误差显示问题。
  3. 返回 LinkedHashMap 保留球员首次出现的顺序,便于阅读;需要排序时用 Stream.sorted
  4. 模型与统计分离,方便后面接真实数据源(爬虫、API、DB)。

如果你有真实的数据格式(Opta、SofaScore 导出 CSV),我可以帮你写针对该格式的解析 + 统计完整代码。

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