本文目录导读:

下面是一个用 Java 统计定位球得分占比的完整案例,假设你有一批进球数据,需要统计其中“定位球得分”占总进球的比例。
需求说明
统计一支球队所有进球中,定位球得分所占的百分比。
定位球通常包括:
- 任意球(直接/间接)
- 角球
- 点球
- 定位球二次进攻(可选)
数据模型
/**
* 进球记录
*/
public class Goal {
private String playerName; // 进球球员
private int minute; // 进球分钟
private GoalType goalType; // 进球方式
public Goal(String playerName, int minute, GoalType goalType) {
this.playerName = playerName;
this.minute = minute;
this.goalType = goalType;
}
public GoalType getGoalType() {
return goalType;
}
// getter/setter 省略
}
/**
* 进球方式枚举
*/
public enum GoalType {
OPEN_PLAY, // 运动战
FREE_KICK, // 任意球
CORNER, // 角球
PENALTY, // 点球
OWN_GOAL // 乌龙球
}
统计逻辑
import java.util.List;
public class GoalStatistics {
/**
* 判断是否为定位球得分
*/
public static boolean isSetPiece(GoalType type) {
return type == GoalType.FREE_KICK
|| type == GoalType.CORNER
|| type == GoalType.PENALTY;
}
/**
* 统计定位球得分占比
* @param goals 所有进球
* @return 占比(0~1),若无进球返回 0
*/
public static double setPieceRatio(List<Goal> goals) {
if (goals == null || goals.isEmpty()) {
return 0.0;
}
long total = goals.size();
long setPieceCount = goals.stream()
.filter(g -> isSetPiece(g.getGoalType()))
.count();
return (double) setPieceCount / total;
}
/**
* 打印详细统计
*/
public static void printReport(List<Goal> goals) {
if (goals == null || goals.isEmpty()) {
System.out.println("没有进球数据");
return;
}
long total = goals.size();
long setPiece = goals.stream().filter(g -> isSetPiece(g.getGoalType())).count();
long openPlay = goals.stream().filter(g -> g.getGoalType() == GoalType.OPEN_PLAY).count();
long penalty = goals.stream().filter(g -> g.getGoalType() == GoalType.PENALTY).count();
long freeKick = goals.stream().filter(g -> g.getGoalType() == GoalType.FREE_KICK).count();
long corner = goals.stream().filter(g -> g.getGoalType() == GoalType.CORNER).count();
double ratio = (double) setPiece / total * 100;
System.out.println("===== 进球统计 =====");
System.out.println("总进球数 : " + total);
System.out.println("运动战进球 : " + openPlay);
System.out.println("定位球进球 : " + setPiece);
System.out.println(" ├─ 点球 : " + penalty);
System.out.println(" ├─ 任意球 : " + freeKick);
System.out.println(" └─ 角球 : " + corner);
System.out.printf("定位球得分占比: %.2f%%%n", ratio);
}
}
测试示例
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Goal> goals = Arrays.asList(
new Goal("梅西", 12, GoalType.OPEN_PLAY),
new Goal("苏亚雷斯", 25, GoalType.PENALTY),
new Goal("拉基蒂奇", 38, GoalType.FREE_KICK),
new Goal("皮克", 55, GoalType.CORNER),
new Goal("梅西", 67, GoalType.OPEN_PLAY),
new Goal("格列兹曼", 78, GoalType.FREE_KICK),
new Goal("布斯克茨", 85, GoalType.OPEN_PLAY),
new Goal("苏亚雷斯", 90, GoalType.OPEN_PLAY)
);
GoalStatistics.printReport(goals);
}
}
运行结果
===== 进球统计 =====
总进球数 : 8
运动战进球 : 4
定位球进球 : 4
├─ 点球 : 1
├─ 任意球 : 2
└─ 角球 : 1
定位球得分占比: 50.00%
做成通用工具类
如果你有多个球队或整个联赛的数据,可以进一步封装:
public class SetPieceAnalyzer {
public static double ratio(List<Goal> goals) {
if (goals == null || goals.isEmpty()) return 0.0;
long setPiece = goals.stream()
.filter(g -> GoalStatistics.isSetPiece(g.getGoalType()))
.count();
return (double) setPiece / goals.size();
}
/** 按球队分组统计 */
public static void reportByTeam(java.util.Map<String, List<Goal>> teamGoals) {
teamGoals.forEach((team, goals) -> {
double r = ratio(goals) * 100;
System.out.printf("%s: 总进球=%d, 定位球占比=%.2f%%%n",
team, goals.size(), r);
});
}
}
要点说明
| 关键点 | 说明 |
|---|---|
| 数据建模 | 用枚举 GoalType 明确进球类型,避免字符串硬编码 |
| 统计口径 | 定位球包含任意球、角球、点球(按需调整) |
| 空值处理 | 无进球时返回 0,避免除零异常 |
| 性能 | stream().filter().count() 一次遍历即可 |
| 扩展性 | 若要区分“直接定位球”和“二次进攻”,可在 Goal 中加字段 |
如果你有具体的场景(读取 CSV、接入数据库、按球员/赛季统计、还是从比赛事件 API 抓取),告诉我,我可以给你一个更贴合的完整可运行版本。