Java 案例:统计"挑球过人"次数多不多
下面给你一个完整的 Java 示例,演示如何统计挑球过人次数并判断是否"多",这个案例可以用于足球数据统计分析场景。

场景说明
假设我们有一场比赛(或一个赛季)中球员的技术动作记录,需要统计"挑球过人"(chip dribble / 挑球过顶)这个动作出现的次数,并判断是否算"多"。
基础版:单场比赛统计
import java.util.*;
public class ChipDribbleStat {
// 定义技术动作枚举
enum Action {
CHIP_DRIBBLE("挑球过人"),
NORMAL_DRIBBLE("普通过人"),
PASS("传球"),
SHOT("射门"),
TACKLE("抢断");
private final String desc;
Action(String desc) { this.desc = desc; }
public String getDesc() { return desc; }
}
// 动作记录
static class ActionRecord {
String player;
Action action;
int minute;
ActionRecord(String player, Action action, int minute) {
this.player = player;
this.action = action;
this.minute = minute;
}
}
public static void main(String[] args) {
// 模拟一场比赛的技术动作数据
List<ActionRecord> records = Arrays.asList(
new ActionRecord("梅西", Action.CHIP_DRIBBLE, 12),
new ActionRecord("梅西", Action.NORMAL_DRIBBLE, 25),
new ActionRecord("内马尔", Action.CHIP_DRIBBLE, 33),
new ActionRecord("梅西", Action.CHIP_DRIBBLE, 45),
new ActionRecord("姆巴佩", Action.SHOT, 52),
new ActionRecord("内马尔", Action.CHIP_DRIBBLE, 61),
new ActionRecord("梅西", Action.CHIP_DRIBBLE, 78),
new ActionRecord("姆巴佩", Action.CHIP_DRIBBLE, 85)
);
// 统计挑球过人次数
long chipCount = records.stream()
.filter(r -> r.action == Action.CHIP_DRIBBLE)
.count();
// 判断标准:>= 5 次算"多"
final int THRESHOLD = 5;
String verdict = chipCount >= THRESHOLD ? "多" : "不多";
System.out.println("本场挑球过人次数: " + chipCount);
System.out.println("判定结果: " + verdict);
}
}
输出:
本场挑球过人次数: 6
判定结果: 多
进阶版:按球员统计 + 多维度判断
实际场景中,仅统计总数不够,还需要按球员对比、按阈值判断(多于场均"才算多)。
import java.util.*;
import java.util.stream.Collectors;
public class ChipDribbleAdvanced {
static class PlayerStat {
String name;
int chipCount;
int totalDribbles;
PlayerStat(String name, int chipCount, int totalDribbles) {
this.name = name;
this.chipCount = chipCount;
this.totalDribbles = totalDribbles;
}
double chipRate() {
return totalDribbles == 0 ? 0 : (double) chipCount / totalDribbles;
}
}
public static void main(String[] args) {
List<PlayerStat> stats = Arrays.asList(
new PlayerStat("梅西", 6, 12),
new PlayerStat("内马尔", 3, 10),
new PlayerStat("姆巴佩", 1, 8),
new PlayerStat("德布劳内", 2, 6)
);
// 1. 全队总数
int totalChips = stats.stream().mapToInt(p -> p.chipCount).sum();
int totalDribbles = stats.stream().mapToInt(p -> p.totalDribbles).sum();
double avgPerPlayer = (double) totalChips / stats.size();
System.out.println("=== 全队统计 ===");
System.out.println("挑球过人总数: " + totalChips);
System.out.println("过人总数: " + totalDribbles);
System.out.printf("挑球占比: %.2f%%%n", 100.0 * totalChips / totalDribbles);
System.out.printf("人均挑球次数: %.2f%n", avgPerPlayer);
// 2. 判断"多不多"(用多个维度)
boolean isMany = totalChips >= 10
|| avgPerPlayer >= 3
|| (double) totalChips / totalDribbles >= 0.3;
System.out.println("\n=== 判定 ===");
System.out.println("挑球过人次数是否算多: " + (isMany ? "多 ✅" : "不多 ❌"));
// 3. 按球员降序,找出挑球达人
System.out.println("\n=== 球员挑球排名 ===");
stats.stream()
.sorted(Comparator.comparingInt((PlayerStat p) -> p.chipCount).reversed())
.forEach(p -> System.out.printf("%-6s 挑球 %d 次 (占比 %.1f%%)%n",
p.name, p.chipCount, p.chipRate() * 100));
}
}
输出:
=== 全队统计 ===
挑球过人总数: 12
过人总数: 36
挑球占比: 33.33%
人均挑球次数: 3.00
=== 判定 ===
挑球过人次数是否算多: 多 ✅
=== 球员挑球排名 ===
梅西 挑球 6 次 (占比 50.0%)
内马尔 挑球 3 次 (占比 30.0%)
德布劳内 挑球 2 次 (占比 33.3%)
姆巴佩 挑球 1 次 (占比 12.5%)
关键设计思路
| 环节 | 做法 |
|---|---|
| 数据建模 | 用 enum 定义动作类型,避免魔法字符串 |
| 统计 | stream().filter().count() 精确计数 |
| "多不多"判定 | 不只看绝对值,还要看 占比、人均、阈值 等多维度 |
| 可扩展 | 阈值 THRESHOLD 可配置,方便按联赛/球员调整 |
判定"多不多"的三种常用口径
- 绝对阈值法:如
次数 >= 5算多(简单直观) - 占比法:
挑球次数 / 总过人次数 >= 30%说明是高比例技巧型球员 - 对比法:与联赛平均值或该球员历史均值比较,超过即为多
// 对比法示例 boolean aboveLeagueAvg = playerChipCount > leagueAvgChipCount;
如果需要,我可以帮你把这个案例扩展成:
- 从 CSV / 数据库 读取真实数据
- 用 Spring Boot 提供 REST 接口 返回统计结果
- 或加入时间窗口(按分钟/半场)分析的版本
告诉我你的具体使用场景即可 👍