java案例统计挑球过人次数多不多?

wen java案例 2

本文目录导读:

java案例统计挑球过人次数多不多?

  1. 需求分析
  2. 核心代码实现
  3. 判断"多不多"的三种视角
  4. 优化建议

这是一个关于足球数据分析的Java案例,我来设计一个统计"挑球过人"(chip dribble / 挑球过顶)次数的系统。

需求分析

"挑球过人"是指球员用脚将球挑起,使球越过防守球员头顶的过人动作,判断"多不多"需要一个基准值对比。

核心代码实现

数据模型

import java.time.LocalDateTime;
// 单次动作事件
public class DribbleEvent {
    private String playerName;
    private String teamName;
    private String type;          // CHIP_DRIBBLE / NORMAL_DRIBBLE / NUTMEG ...
    private boolean success;      // 是否成功
    private LocalDateTime time;
    public DribbleEvent(String playerName, String teamName, 
                        String type, boolean success) {
        this.playerName = playerName;
        this.teamName = teamName;
        this.type = type;
        this.success = success;
        this.time = LocalDateTime.now();
    }
    // getter/setter 省略
    public String getPlayerName() { return playerName; }
    public String getTeamName()   { return teamName; }
    public String getType()       { return type; }
    public boolean isSuccess()    { return success; }
}

统计服务

import java.util.*;
import java.util.stream.Collectors;
public class ChipDribbleAnalyzer {
    private static final String CHIP_DRIBBLE = "CHIP_DRIBBLE";
    /** 统计某球员挑球过人次数(含成功/失败) */
    public long countChipDribbles(List<DribbleEvent> events, String playerName) {
        return events.stream()
                .filter(e -> e.getPlayerName().equals(playerName))
                .filter(e -> CHIP_DRIBBLE.equals(e.getType()))
                .count();
    }
    /** 统计成功率 */
    public double chipSuccessRate(List<DribbleEvent> events, String playerName) {
        List<DribbleEvent> chips = events.stream()
                .filter(e -> e.getPlayerName().equals(playerName))
                .filter(e -> CHIP_DRIBBLE.equals(e.getType()))
                .toList();
        if (chips.isEmpty()) return 0.0;
        long success = chips.stream().filter(DribbleEvent::isSuccess).count();
        return (double) success / chips.size() * 100;
    }
    /** 全队挑球过人总次数 vs 其他过人类型 */
    public Map<String, Long> dribbleTypeDistribution(List<DribbleEvent> events, String teamName) {
        return events.stream()
                .filter(e -> e.getTeamName().equals(teamName))
                .collect(Collectors.groupingBy(
                        DribbleEvent::getType, 
                        Collectors.counting()));
    }
    /** 核心:判断挑球过人是否"多" */
    public AnalysisResult analyze(List<DribbleEvent> events, String playerName) {
        long chipCount = countChipDribbles(events, playerName);
        long totalDribbles = events.stream()
                .filter(e -> e.getPlayerName().equals(playerName))
                .count();
        double chipRatio = totalDribbles == 0 ? 0 
                           : (double) chipCount / totalDribbles * 100;
        double successRate = chipSuccessRate(events, playerName);
        // 判定规则(可调参数)
        String level;
        if (chipRatio >= 25 && chipCount >= 5) {
            level = "非常多 (核心招牌动作)";
        } else if (chipRatio >= 15 && chipCount >= 3) {
            level = "较多 (常用技巧)";
        } else if (chipRatio >= 8) {
            level = "一般 (偶尔使用)";
        } else {
            level = "较少 (不擅长/很少用)";
        }
        return new AnalysisResult(playerName, chipCount, totalDribbles, 
                                  chipRatio, successRate, level);
    }
}
class AnalysisResult {
    String player; long chipCount, totalDribbles;
    double chipRatio, successRate; String level;
    AnalysisResult(String p, long c, long t, double r, double s, String l) {
        player = p; chipCount = c; totalDribbles = t;
        chipRatio = r; successRate = s; level = l;
    }
    public String toString() {
        return String.format(
            "球员: %s | 挑球次数: %d/%d (%.1f%%) | 成功率: %.1f%% | 评价: %s",
            player, chipCount, totalDribbles, chipRatio, successRate, level);
    }
}

测试运行

public class Main {
    public static void main(String[] args) {
        List<DribbleEvent> events = List.of(
            new DribbleEvent("梅西", "阿根廷", "CHIP_DRIBBLE", true),
            new DribbleEvent("梅西", "阿根廷", "CHIP_DRIBBLE", true),
            new DribbleEvent("梅西", "阿根廷", "CHIP_DRIBBLE", false),
            new DribbleEvent("梅西", "阿根廷", "NORMAL_DRIBBLE", true),
            new DribbleEvent("梅西", "阿根廷", "NORMAL_DRIBBLE", true),
            new DribbleEvent("梅西", "阿根廷", "NUTMEG", false),
            new DribbleEvent("内马尔", "巴西", "NORMAL_DRIBBLE", true),
            new DribbleEvent("内马尔", "巴西", "NUTMEG", true)
        );
        ChipDribbleAnalyzer analyzer = new ChipDribbleAnalyzer();
        System.out.println(analyzer.analyze(events, "梅西"));
        System.out.println(analyzer.analyze(events, "内马尔"));
        System.out.println("全队分布: " + 
            analyzer.dribbleTypeDistribution(events, "阿根廷"));
    }
}

输出:

球员: 梅西 | 挑球次数: 3/6 (50.0%) | 成功率: 66.7% | 评价: 较多 (常用技巧)
球员: 内马尔 | 挑球次数: 0/2 (0.0%) | 成功率: 0.0% | 评价: 较少 (不擅长/很少用)
全队分布: {NUTMEG=1, NORMAL_DRIBBLE=2, CHIP_DRIBBLE=3}

判断"多不多"的三种视角

视角 衡量方式 阈值示例
绝对数量 挑球次数直接对比 ≥5次/场 算多
相对占比 挑球 / 总过人次数 ≥20% 算多
对比基准 与联赛/同位置球员平均值对比 高于均值1.5倍算多

优化建议

  1. 引入基准数据:在数据库存联赛同位置球员平均挑球次数,动态比较
  2. 按比赛分段:统计每90分钟挑球次数,避免替补干扰
  3. 加权成功率:成功挑球计2分,失败计0分,综合评分
  4. 对手强度因子:对不同实力对手赋予权重

判断"多不多"需要一个参照系,单看数字没意义,建议用 chipRatio(占个人过人比例)+ chipCount(绝对次数)+ 成功率 三者组合判定,并和同位置球员基准对比,结果才更客观。

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