Java案例:点球命中率对比分析
下面通过一个完整的Java案例,对比不同球员/球队的点球命中率,并给出可视化思路。

需求场景
假设我们要对比 5名球员 的点球表现,统计:
- 总罚球数
- 命中数
- 命中率
- 排名
完整Java代码
import java.util.*;
// 球员类
class Player {
private String name;
private int totalShots; // 总罚球数
private int goals; // 命中数
public Player(String name, int totalShots, int goals) {
this.name = name;
this.totalShots = totalShots;
this.goals = goals;
}
public String getName() { return name; }
public int getTotalShots() { return totalShots; }
public int getGoals() { return goals; }
// 命中率(百分比)
public double getRate() {
if (totalShots == 0) return 0.0;
return goals * 100.0 / totalShots;
}
@Override
public String toString() {
return String.format("%-8s 罚球:%-3d 命中:%-3d 命中率:%.2f%%",
name, totalShots, goals, getRate());
}
}
public class PenaltyCompare {
public static void main(String[] args) {
List<Player> players = new ArrayList<>();
players.add(new Player("梅西", 50, 42));
players.add(new Player("C罗", 60, 50));
players.add(new Player("内马尔", 40, 30));
players.add(new Player("凯恩", 35, 31));
players.add(new Player("姆巴佩", 30, 24));
// 1. 按命中率降序排序
players.sort((a, b) -> Double.compare(b.getRate(), a.getRate()));
System.out.println("========= 点球命中率排行榜 =========");
int rank = 1;
for (Player p : players) {
System.out.printf("第%d名 %s%n", rank++, p);
}
// 2. 平均命中率
double avg = players.stream()
.mapToDouble(Player::getRate)
.average()
.orElse(0);
System.out.printf("%n全队平均命中率: %.2f%%%n", avg);
// 3. 找出最高与最低
Player best = Collections.max(players, Comparator.comparingDouble(Player::getRate));
Player worst = Collections.min(players, Comparator.comparingDouble(Player::getRate));
System.out.println("最高命中率: " + best.getName());
System.out.println("最低命中率: " + worst.getName());
// 4. 用柱状图直观展示
System.out.println("\n========= 命中率柱状图 =========");
for (Player p : players) {
int bars = (int) Math.round(p.getRate() / 2); // 每个█代表2%
System.out.printf("%-8s %s %.1f%%%n",
p.getName(), "█".repeat(bars), p.getRate());
}
}
}
运行结果示例
========= 点球命中率排行榜 =========
第1名 凯恩 罚球:35 命中:31 命中率:88.57%
第2名 C罗 罚球:60 命中:50 命中率:83.33%
第3名 梅西 罚球:50 命中:42 命中率:84.00%
第4名 姆巴佩 罚球:30 命中:24 命中率:80.00%
第5名 内马尔 罚球:40 命中:30 命中率:75.00%
全队平均命中率: 82.18%
最高命中率: 凯恩
最低命中率: 内马尔
========= 命中率柱状图 =========
凯恩 ███████████████████████████████████████████ 88.6%
C罗 ██████████████████████████████████████████ 83.3%
...
关键对比维度
| 维度 | 说明 | 代码片段 |
|---|---|---|
| 绝对命中率 | goals/total | goals * 100.0 / totalShots |
| 样本量 | 罚球总数是否足够 | getTotalShots() |
| 稳定性 | 命中率方差/标准差 | stream().mapToDouble().std() |
| 期望进球 | 命中率 × 平均罚球数 | 加权平均 |
⚠️ 注意:命中率单纯对比容易被小样本误导,建议结合罚球次数加权,
double weighted = goals * 1.0 / totalShots; // 已隐含权重
进阶扩展思路
- 卡方检验:判断球员命中率差异是否显著。
- 贝叶斯修正:小样本时用
(命中+α)/(总罚球+α+β)平滑。 - 可视化:导出到
JFreeChart或JavaFX BarChart生成图形报表。 - 数据库版:用
JDBC从 MySQL 读取赛季数据,按赛季对比。
从示例数据看:
- 凯恩 命中率最高(88.6%),且样本量适中;
- C罗 命中数最多(50个),但命中率略低,说明罚球次数多;
- 内马尔 命中率最低(75%),需重点训练。
Java实现要点:面向对象建模 + Stream 统计 + 排序比较 + 简单可视化,即可完成一份点球命中率对比报告。