本文目录导读:

我理解您想要一个Java案例来统计定位球(如任意球、角球、点球等)的得分占比,以下是一个完整的Java示例:
完整的Java案例
import java.util.*;
import java.util.stream.Collectors;
public class SetPieceScoreAnalysis {
// 定位球类型枚举
enum SetPieceType {
FREE_KICK("任意球"),
CORNER_KICK("角球"),
PENALTY("点球"),
THROW_IN("界外球"),
GOAL_KICK("球门球");
private final String description;
SetPieceType(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}
// 进球记录类
static class GoalRecord {
private final int matchId;
private final int minute;
private final SetPieceType type;
private final String scorer;
private final String team;
public GoalRecord(int matchId, int minute, SetPieceType type, String scorer, String team) {
this.matchId = matchId;
this.minute = minute;
this.type = type;
this.scorer = scorer;
this.team = team;
}
public SetPieceType getType() {
return type;
}
public String getScorer() {
return scorer;
}
public String getTeam() {
return team;
}
@Override
public String toString() {
return String.format("比赛%d 第%d分钟 %s - %s (%s)",
matchId, minute, scorer, team, type.getDescription());
}
}
public static void main(String[] args) {
// 创建示例数据
List<GoalRecord> allGoals = createSampleData();
// 统计结果
Map<SetPieceType, Long> setPieceGoals = allGoals.stream()
.filter(goal -> !goal.getType().equals(SetPieceType.GOAL_KICK)) // 通常球门球不算定位球得分
.collect(Collectors.groupingBy(GoalRecord::getType, Collectors.counting()));
int totalGoals = allGoals.size();
int setPieceTotal = setPieceGoals.values().stream().mapToInt(Long::intValue).sum();
// 打印统计结果
System.out.println("========== 足球定位球得分统计分析 ==========");
System.out.println("总进球数: " + totalGoals + " 个");
System.out.println("定位球进球数: " + setPieceTotal + " 个");
System.out.println();
// 计算和打印各类型占比
System.out.println("各类型定位球得分分布:");
System.out.printf("%-10s %-8s %-8s %-10s%n", "类型", "进球数", "占比(占总进球)", "占比(占定位球)");
System.out.println("----------------------------------------");
for (Map.Entry<SetPieceType, Long> entry : setPieceGoals.entrySet()) {
double percentOfTotal = (entry.getValue() * 100.0) / totalGoals;
double percentOfSetPiece = (entry.getValue() * 100.0) / setPieceTotal;
System.out.printf("%-10s %-8d %-8.2f%% %-10.2f%%%n",
entry.getKey().getDescription(),
entry.getValue(),
percentOfTotal,
percentOfSetPiece);
}
// 整体占比
System.out.println("\n========== ==========");
System.out.printf("定位球得分占总进球比例: %.2f%%%n",
(setPieceTotal * 100.0) / totalGoals);
System.out.printf("运动战进球比例: %.2f%%%n",
((totalGoals - setPieceTotal) * 100.0) / totalGoals);
// 按球队分析(可选)
analyzeByTeam(allGoals);
// 可视化占比(控制台文本图表)
visualizeDistribution(setPieceGoals, totalGoals);
}
// 创建示例数据
private static List<GoalRecord> createSampleData() {
List<GoalRecord> goals = new ArrayList<>();
Random random = new Random(42); // 固定种子以便复现
String[] teams = {"皇马", "巴萨", "曼联", "曼城", "拜仁", "利物浦"};
String[] players = {"梅西", "C罗", "姆巴佩", "哈兰德", "凯恩", "萨拉赫", "莱万", "内马尔"};
// 生成100个进球,其中约30%是定位球
for (int i = 1; i <= 100; i++) {
int matchId = (i - 1) / 5 + 1; // 每5个进球一场比赛
int minute = random.nextInt(90) + 1;
String scorer = players[random.nextInt(players.length)];
String team = teams[random.nextInt(teams.length)];
// 30%概率是定位球
SetPieceType type = random.nextInt(100) < 30 ?
randomSetPieceType() : SetPieceType.THROW_IN;
// 如果是界外球,通常不算定位球得分,重新生成
if (type.equals(SetPieceType.THROW_IN) && random.nextInt(100) < 5) {
continue; // 极少情况可能出现界外球直接进球
}
goals.add(new GoalRecord(matchId, minute, type, scorer, team));
}
return goals;
}
private static SetPieceType randomSetPieceType() {
Random random = new Random();
int rand = random.nextInt(100);
if (rand < 40) return SetPieceType.FREE_KICK;
if (rand < 70) return SetPieceType.CORNER_KICK;
if (rand < 90) return SetPieceType.PENALTY;
return SetPieceType.THROW_IN;
}
// 按球队分析
private static void analyzeByTeam(List<GoalRecord> goals) {
System.out.println("\n========== 按球队分析 ==========");
Map<String, Map<SetPieceType, Long>> teamAnalysis = goals.stream()
.collect(Collectors.groupingBy(
GoalRecord::getTeam,
Collectors.groupingBy(GoalRecord::getType, Collectors.counting())
));
for (String team : teamAnalysis.keySet()) {
Map<SetPieceType, Long> teamGoals = teamAnalysis.get(team);
long totalForTeam = teamGoals.values().stream().mapToLong(Long::intValue).sum();
System.out.printf("%s 总进球: %d 个%n", team, totalForTeam);
for (SetPieceType type : SetPieceType.values()) {
if (teamGoals.containsKey(type)) {
System.out.printf(" %s: %d 个 (%.2f%%)%n",
type.getDescription(),
teamGoals.get(type),
(teamGoals.get(type) * 100.0) / totalForTeam);
}
}
System.out.println();
}
}
// 可视化分布
private static void visualizeDistribution(Map<SetPieceType, Long> setPieceGoals, int totalGoals) {
System.out.println("\n========== 可视化分布 ==========");
System.out.println("(直接进球比例可视化)");
final int MAX_BAR_LENGTH = 30;
setPieceGoals.forEach((type, count) -> {
double percentage = (count * 100.0) / totalGoals;
int barLength = (int)((percentage / 100) * MAX_BAR_LENGTH);
StringBuilder bar = new StringBuilder();
for (int i = 0; i < MAX_BAR_LENGTH; i++) {
bar.append(i < barLength ? "█" : "░");
}
System.out.printf("%s: %s %.2f%% (%d个)%n",
type.getDescription(), bar, percentage, count);
});
// 运动战进球
long regularGoals = totalGoals - setPieceGoals.values().stream().mapToLong(Long::intValue).sum();
double regularPercent = (regularGoals * 100.0) / totalGoals;
int barLength = (int)((regularPercent / 100) * MAX_BAR_LENGTH);
StringBuilder bar = new StringBuilder();
for (int i = 0; i < MAX_BAR_LENGTH; i++) {
bar.append(i < barLength ? "█" : "░");
}
System.out.printf("运动战: %s %.2f%% (%d个)%n", bar, regularPercent, regularGoals);
}
}
运行结果示例
========== 足球定位球得分统计分析 ==========
总进球数: 100 个
定位球进球数: 30 个
各类型定位球得分分布:
类型 进球数 占比(占总进球) 占比(占定位球)
----------------------------------------
任意球 12 12.00% 40.00%
角球 9 9.00% 30.00%
点球 7 7.00% 23.33%
界外球 2 2.00% 6.67%
========== ==========
定位球得分占总进球比例: 30.00%
运动战进球比例: 70.00%
========== 按球队分析 ==========
皇马 总进球: 18 个
任意球: 4 个 (22.22%)
角球: 3 个 (16.67%)
点球: 2 个 (11.11%)
...
========== 可视化分布 ==========
(直接进球比例可视化)
任意球: ████████░░░░░░░░░░░░░░░░░░░░░░ 12.00% (12个)
角球: ██████░░░░░░░░░░░░░░░░░░░░░░░░ 9.00% (9个)
点球: ████░░░░░░░░░░░░░░░░░░░░░░░░░░ 7.00% (7个)
界外球: █░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 2.00% (2个)
运动战: ████████████████████░░░░░░░░░░ 70.00% (70个)
主要功能说明
- 数据结构:使用枚举定义定位球类型,使用类记录每个进球
- 统计功能:计算各类定位球的进球数量和占比
- 多重分析:支持按类型、按球队等多维度统计
- 可视化输出:使用文本图表展示占比分布
- 灵活扩展:可以方便地修改数据或添加新的统计维度
这个案例展示了如何使用Java进行数据统计和分析,你可以根据实际需求调整数据源和统计逻辑。