Java 案例:统计"凌空抽射"次数
下面用一个完整的 Java 案例,演示如何统计足球比赛中"凌空抽射"射门次数,并判断"多不多"。

需求分析
- 输入:一系列射门记录(射门类型 + 是否进球)
- 统计:凌空抽射的总次数、进球数、占比
- 判断:设定阈值,判断凌空抽射次数"多"还是"少"
实体类设计
// 射门类型枚举
enum ShootType {
VOLLEY("凌空抽射"),
HEADER("头球"),
PENALTY("点球"),
FREE_KICK("任意球"),
NORMAL("普通射门");
private final String desc;
ShootType(String desc) { this.desc = desc; }
public String getDesc() { return desc; }
}
// 射门记录
class ShootRecord {
private String player; // 球员
private ShootType type; // 射门类型
private boolean goal; // 是否进球
public ShootRecord(String player, ShootType type, boolean goal) {
this.player = player;
this.type = type;
this.goal = goal;
}
public ShootType getType() { return type; }
public boolean isGoal() { return goal; }
public String getPlayer() { return player; }
}
统计与判断逻辑
import java.util.*;
import java.util.stream.Collectors;
public class VolleyStats {
/** 阈值:凌空抽射次数 >= 该值视为"多" */
private static final int MANY_THRESHOLD = 5;
public static void main(String[] args) {
// 模拟一场比赛的射门数据
List<ShootRecord> shots = Arrays.asList(
new ShootRecord("梅西", ShootType.VOLLEY, true),
new ShootRecord("C罗", ShootType.VOLLEY, false),
new ShootRecord("姆巴佩", ShootType.VOLLEY, true),
new ShootRecord("内马尔", ShootType.HEADER, false),
new ShootRecord("哈兰德", ShootType.VOLLEY, true),
new ShootRecord("凯恩", ShootType.PENALTY, true),
new ShootRecord("苏牙", ShootType.VOLLEY, false),
new ShootRecord("贝尔", ShootType.FREE_KICK, false),
new ShootRecord("本泽马", ShootType.VOLLEY, true),
new ShootRecord("莱万", ShootType.NORMAL, false),
new ShootRecord("格列兹曼", ShootType.VOLLEY, false)
);
// 1. 过滤出所有凌空抽射
List<ShootRecord> volleys = shots.stream()
.filter(s -> s.getType() == ShootType.VOLLEY)
.collect(Collectors.toList());
int totalShots = shots.size();
int volleyCount = volleys.size();
long volleyGoals = volleys.stream().filter(ShootRecord::isGoal).count();
// 2. 计算占比
double ratio = totalShots == 0 ? 0 : (double) volleyCount / totalShots * 100;
// 3. 判断"多不多"
String verdict = volleyCount >= MANY_THRESHOLD ? "偏多 🔥" : "偏少 💤";
// 4. 输出结果
System.out.println("====== 凌空抽射统计 ======");
System.out.printf("总射门次数:%d%n", totalShots);
System.out.printf("凌空抽射次数:%d(占比 %.1f%%)%n", volleyCount, ratio);
System.out.printf("凌空抽射进球:%d 个(转化率 %.1f%%)%n",
volleyGoals, volleyCount == 0 ? 0 : volleyGoals * 100.0 / volleyCount);
System.out.printf("判断结果:凌空抽射次数%s(阈值 %d)%n", verdict, MANY_THRESHOLD);
// 5. 按球员分组统计谁最爱凌空抽射
System.out.println("\n------ 各球员凌空抽射明细 ------");
volleys.stream()
.collect(Collectors.groupingBy(ShootRecord::getPlayer, Collectors.counting()))
.forEach((p, c) -> System.out.printf("%s:%d 次%n", p, c));
}
}
运行结果示例
====== 凌空抽射统计 ======
总射门次数:11
凌空抽射次数:7(占比 63.6%)
凌空抽射进球:4 个(转化率 57.1%)
判断结果:凌空抽射次数偏多 🔥(阈值 5)
------ 各球员凌空抽射明细 ------
梅西:1 次
C罗:1 次
姆巴佩:1 次
哈兰德:1 次
苏牙:1 次
本泽马:1 次
格列兹曼:1 次
关键点说明
| 环节 | 说明 |
|---|---|
| 区分类型 | 用枚举 ShootType 明确"凌空抽射",避免字符串比较的隐患 |
| 统计次数 | filter + count() 快速统计次数 |
| 判断多不多 | 用阈值 + 占比双维度判断更合理:绝对次数看阈值,相对占比看百分比 |
| 可扩展 | 若数据来自数据库/文件,只需替换数据源,统计逻辑不变 |
进一步优化建议
- 阈值可配置:把
MANY_THRESHOLD放进配置文件,方便不同赛事调整。 - 多维度对比:可以同时统计其他射门类型,比较凌空抽射在所有类型中的排名。
- 接入真实数据:用 JDBC 读取比赛表,
SELECT type, COUNT(*) FROM shoots GROUP BY type,再用 Java 处理业务判断。
这样这个案例既完成了次数统计,又给出"多不多"的量化判断,还顺带算出转化率和球员明细,是一个完整可运行的小实战。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播