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

wen java案例 3

Java 案例:统计"挑球过人"次数

下面给你一个完整的 Java 案例,模拟统计足球比赛中"挑球过人"的技术动作次数,并判断多不多。

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

需求分析

  • 从比赛事件数据中筛选出 "挑球过人" 类型的事件
  • 统计总次数
  • 按球员分组统计
  • 判断次数"多不多"(设定阈值)

完整代码

import java.util.*;
import java.util.stream.Collectors;
/**
 * 统计挑球过人次数
 */
public class DribbleStatsDemo {
    // 事件类型枚举
    enum ActionType {
        PASS,           // 传球
        SHOT,           // 射门
        TACKLE,         // 抢断
        NUTMEG,         // 穿裆过人
        RAINBOW_FLICK,  // 彩虹过人
        CHIP_DRIBBLE    // 挑球过人 ⭐
    }
    // 比赛事件
    static class MatchEvent {
        String player;
        ActionType type;
        int minute;
        MatchEvent(String player, ActionType type, int minute) {
            this.player = player;
            this.type = type;
            this.minute = minute;
        }
    }
    public static void main(String[] args) {
        // 1. 模拟比赛事件数据
        List<MatchEvent> events = List.of(
            new MatchEvent("梅西",   ActionType.CHIP_DRIBBLE, 12),
            new MatchEvent("梅西",   ActionType.CHIP_DRIBBLE, 35),
            new MatchEvent("梅西",   ActionType.PASS,         40),
            new MatchEvent("内马尔", ActionType.CHIP_DRIBBLE, 8),
            new MatchEvent("内马尔", ActionType.NUTMEG,       20),
            new MatchEvent("内马尔", ActionType.SHOT,         55),
            new MatchEvent("姆巴佩", ActionType.CHIP_DRIBBLE, 30),
            new MatchEvent("姆巴佩", ActionType.CHIP_DRIBBLE, 62),
            new MatchEvent("姆巴佩", ActionType.CHIP_DRIBBLE, 78),
            new MatchEvent("姆巴佩", ActionType.TACKLE,       85),
            new MatchEvent("维尼修斯", ActionType.RAINBOW_FLICK, 25),
            new MatchEvent("维尼修斯", ActionType.CHIP_DRIBBLE, 70)
        );
        // 2. 筛选所有挑球过人事件
        List<MatchEvent> chipDribbles = events.stream()
            .filter(e -> e.type == ActionType.CHIP_DRIBBLE)
            .collect(Collectors.toList());
        // 3. 总次数统计
        int total = chipDribbles.size();
        System.out.println("=== 挑球过人总次数:" + total + " 次 ===");
        // 4. 按球员分组统计(降序)
        Map<String, Long> byPlayer = chipDribbles.stream()
            .collect(Collectors.groupingBy(
                e -> e.player,
                Collectors.counting()
            ));
        System.out.println("\n=== 各球员挑球过人次数 ===");
        byPlayer.entrySet().stream()
            .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
            .forEach(en -> System.out.printf("%-8s : %d 次%n",
                    en.getKey(), en.getValue()));
        // 5. 判断"多不多"
        // 规则:单场 >= 5 次 -> 多;< 3 次 -> 少;其余 -> 一般
        System.out.println("\n=== 多不多判断 ===");
        System.out.println("全队总次数评价:" + judge(total, 5, 3));
        // 单球员评价
        String topPlayer = byPlayer.entrySet().stream()
            .max(Map.Entry.comparingByValue())
            .map(Map.Entry::getKey).orElse("无");
        long topCount = byPlayer.getOrDefault(topPlayer, 0L);
        System.out.printf("表现最突出的球员:%s(%d 次)→ %s%n",
                topPlayer, topCount, judge(topCount, 3, 2));
        // 6. 附加信息:按时间分布(可选)
        System.out.println("\n=== 挑球过人发生时间点 ===");
        chipDribbles.stream()
            .sorted(Comparator.comparingInt(e -> e.minute))
            .forEach(e -> System.out.printf("%2d'  %s%n", e.minute, e.player));
    }
    /**
     * 判断次数的"多不多"
     * @param count 实际次数
     * @param high  高阈值
     * @param low   低阈值
     */
    private static String judge(int count, int high, int low) {
        if (count >= high) return "🔝 多!技术亮眼";
        if (count < low)   return "🔻 少,需加强";
        return "⚖️ 一般水平";
    }
}

运行输出示例

=== 挑球过人总次数:6 次 ===
=== 各球员挑球过人次数 ===
梅西     : 2 次
姆巴佩   : 3 次
内马尔   : 1 次
维尼修斯 : 1 次
=== 多不多判断 ===
全队总次数评价:🔝 多!技术亮眼
表现最突出的球员:姆巴佩(3 次)→ 🔝 多!技术亮眼
=== 挑球过人发生时间点 ===
 8'  内马尔
12'  梅西
30'  姆巴佩
35'  梅西
62'  姆巴佩
70'  维尼修斯
78'  姆巴佩

关键点讲解

步骤 技术点 说明
数据建模 内部类 + 枚举 用 ActionType 枚举约束事件类型,避免字符串硬编码
筛选 Stream.filter 只保留 CHIP_DRIBBLE 事件
分组统计 Collectors.groupingBy + counting 一句话完成按球员聚合
排序 comparingByValue().reversed() 排行榜按次数降序
判定 自定义 judge 方法 阈值参数化,方便调整(比如单场 5 次算多)

扩展思路

  1. 真实数据:从 CSV / JSON / 数据库读取 MatchEvent,替换 List.of(...) 即可。
  2. 看比赛势头:结合时间轴,若某球员连续 10 分钟挑球 ≥ 2 次,可标记为"状态爆发"。
  3. 加权评分:挑球过人 分 3 级(成功过掉 1 人 / 2 人成功 → 高分),用 Map<String,Integer> 更精准。
  4. 阈值可配置:把 high、low 放进配置文件(application.yml),便于不同联赛标准差异。

需要我改成 从 CSV 文件读取数据 或 统计成功率(挑球过人成功/失败) 的版本吗?

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