本文目录导读:

我来为您提供一个Java案例,统计落叶球射门成功率的完整实现方案:
核心类设计
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
/**
* 落叶球射门统计系统
*/
public class KnuckleballShotAnalysis {
// 射门结果枚举
public enum ShotResult {
SCORE("进球"),
SAVED("被扑出"),
OFF_TARGET("偏出"),
HIT_POST("中柱");
private final String description;
ShotResult(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}
// 射门类型
public enum ShotType {
FREE_KICK("任意球"),
OPEN_PLAY("运动战"),
PENALTY("点球");
private final String description;
ShotType(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}
// 射门记录类
public static class ShotRecord {
private LocalDateTime time;
private ShotType type;
private ShotResult result;
private double distance; // 射门距离(米)
private double speed; // 球速(km/h)
private boolean hasCurve; // 是否有落叶轨迹
private int playerId;
private int matchId;
private String note;
public ShotRecord(LocalDateTime time, ShotType type, ShotResult result,
double distance, double speed, boolean hasCurve,
int playerId, int matchId) {
this.time = time;
this.type = type;
this.result = result;
this.distance = distance;
this.speed = speed;
this.hasCurve = hasCurve;
this.playerId = playerId;
this.matchId = matchId;
}
// Getters and Setters
public LocalDateTime getTime() { return time; }
public void setTime(LocalDateTime time) { this.time = time; }
public ShotType getType() { return type; }
public void setType(ShotType type) { this.type = type; }
public ShotResult getResult() { return result; }
public void setResult(ShotResult result) { this.result = result; }
public double getDistance() { return distance; }
public void setDistance(double distance) { this.distance = distance; }
public double getSpeed() { return speed; }
public void setSpeed(double speed) { this.speed = speed; }
public boolean isHasCurve() { return hasCurve; }
public void setHasCurve(boolean hasCurve) { this.hasCurve = hasCurve; }
public int getPlayerId() { return playerId; }
public void setPlayerId(int playerId) { this.playerId = playerId; }
public int getMatchId() { return matchId; }
public void setMatchId(int matchId) { this.matchId = matchId; }
public String getNote() { return note; }
public void setNote(String note) { this.note = note; }
}
// 统计数据类
public static class ShotStatistics {
private int totalShots; // 总射门数
private int totalGoals; // 总进球数
private int totalSave; // 被扑出数
private int totalOffTarget; // 射偏数
private int totalHitPost; // 中柱数
private double averageSpeed; // 平均球速
private Map<ShotResult, Integer> resultDistribution;
private Map<ShotType, Integer> typeDistribution;
public ShotStatistics() {
this.totalShots = 0;
this.totalGoals = 0;
this.totalSave = 0;
this.totalOffTarget = 0;
this.totalHitPost = 0;
this.averageSpeed = 0.0;
this.resultDistribution = new EnumMap<>(ShotResult.class);
this.typeDistribution = new EnumMap<>(ShotType.class);
}
// 计算成功率
public double getSuccessRate() {
return totalShots == 0 ? 0 : (double) totalGoals / totalShots * 100;
}
// Getters
public int getTotalShots() { return totalShots; }
public int getTotalGoals() { return totalGoals; }
public int getTotalSave() { return totalSave; }
public int getTotalOffTarget() { return totalOffTarget; }
public int getTotalHitPost() { return totalHitPost; }
public double getAverageSpeed() { return averageSpeed; }
public Map<ShotResult, Integer> getResultDistribution() { return resultDistribution; }
public Map<ShotType, Integer> getTypeDistribution() { return typeDistribution; }
}
}
统计分析类
/**
* 落叶球射门统计分析器
*/
public class ShotAnalyzer {
private List<ShotRecord> shotRecords;
public ShotAnalyzer() {
this.shotRecords = new ArrayList<>();
}
// 添加射门记录
public void addShotRecord(ShotRecord record) {
shotRecords.add(record);
}
// 批量添加射门记录
public void addShotRecords(List<ShotRecord> records) {
shotRecords.addAll(records);
}
// 基础统计 - 按条件过滤
public ShotStatistics getStatistics(FilterCriteria criteria) {
ShotStatistics stats = new ShotStatistics();
// 过滤符合条件的射门记录
List<ShotRecord> filteredShots = shotRecords.stream()
.filter(shot -> criteria.matches(shot))
.collect(Collectors.toList());
// 计算基本统计
stats.totalShots = filteredShots.size();
for (ShotRecord shot : filteredShots) {
// 计算进球数
if (shot.getResult() == ShotResult.SCORE) {
stats.totalGoals++;
} else if (shot.getResult() == ShotResult.SAVED) {
stats.totalSave++;
} else if (shot.getResult() == ShotResult.OFF_TARGET) {
stats.totalOffTarget++;
} else if (shot.getResult() == ShotResult.HIT_POST) {
stats.totalHitPost++;
}
// 累加球速
stats.averageSpeed += shot.getSpeed();
// 更新时间分布
stats.resultDistribution.merge(shot.getResult(), 1, Integer::sum);
stats.typeDistribution.merge(shot.getType(), 1, Integer::sum);
}
// 计算平均速度
if (stats.totalShots > 0) {
stats.averageSpeed /= stats.totalShots;
}
return stats;
}
// 按球员统计
public Map<Integer, ShotStatistics> getStatisticsByPlayer() {
Map<Integer, ShotStatistics> statsMap = new HashMap<>();
for (ShotRecord shot : shotRecords) {
statsMap.computeIfAbsent(shot.getPlayerId(), k -> new ShotStatistics());
ShotStatistics stats = statsMap.get(shot.getPlayerId());
updateStatistics(stats, shot);
}
return statsMap;
}
// 按比赛统计
public Map<Integer, ShotStatistics> getStatisticsByMatch() {
Map<Integer, ShotStatistics> statsMap = new HashMap<>();
for (ShotRecord shot : shotRecords) {
statsMap.computeIfAbsent(shot.getMatchId(), k -> new ShotStatistics());
ShotStatistics stats = statsMap.get(shot.getMatchId());
updateStatistics(stats, shot);
}
return statsMap;
}
// 按时间段统计
public ShotStatistics getStatisticsByTimeRange(LocalDateTime start, LocalDateTime end) {
return getStatistics(new FilterCriteria.Builder()
.withTimeRange(start, end)
.build());
}
// 更新统计信息
private void updateStatistics(ShotStatistics stats, ShotRecord shot) {
stats.totalShots++;
if (shot.getResult() == ShotResult.SCORE) {
stats.totalGoals++;
} else if (shot.getResult() == ShotResult.SAVED) {
stats.totalSave++;
} else if (shot.getResult() == ShotResult.OFF_TARGET) {
stats.totalOffTarget++;
} else if (shot.getResult() == ShotResult.HIT_POST) {
stats.totalHitPost++;
}
stats.averageSpeed += shot.getSpeed();
stats.resultDistribution.merge(shot.getResult(), 1, Integer::sum);
stats.typeDistribution.merge(shot.getType(), 1, Integer::sum);
}
// 筛选条件类
public static class FilterCriteria {
private ShotType type;
private Integer playerId;
private Integer matchId;
private LocalDateTime startTime;
private LocalDateTime endTime;
private Double minDistance;
private Double maxDistance;
private Double minSpeed;
private Boolean hasCurve;
private FilterCriteria(Builder builder) {
this.type = builder.type;
this.playerId = builder.playerId;
this.matchId = builder.matchId;
this.startTime = builder.startTime;
this.endTime = builder.endTime;
this.minDistance = builder.minDistance;
this.maxDistance = builder.maxDistance;
this.minSpeed = builder.minSpeed;
this.hasCurve = builder.hasCurve;
}
public boolean matches(ShotRecord shot) {
if (type != null && shot.getType() != type) return false;
if (playerId != null && shot.getPlayerId() != playerId) return false;
if (matchId != null && shot.getMatchId() != matchId) return false;
if (startTime != null && shot.getTime().isBefore(startTime)) return false;
if (endTime != null && shot.getTime().isAfter(endTime)) return false;
if (minDistance != null && shot.getDistance() < minDistance) return false;
if (maxDistance != null && shot.getDistance() > maxDistance) return false;
if (minSpeed != null && shot.getSpeed() < minSpeed) return false;
if (hasCurve != null && shot.isHasCurve() != hasCurve) return false;
return true;
}
// Builder模式
public static class Builder {
private ShotType type;
private Integer playerId;
private Integer matchId;
private LocalDateTime startTime;
private LocalDateTime endTime;
private Double minDistance;
private Double maxDistance;
private Double minSpeed;
private Boolean hasCurve;
public Builder withType(ShotType type) {
this.type = type;
return this;
}
public Builder withPlayerId(Integer playerId) {
this.playerId = playerId;
return this;
}
public Builder withMatchId(Integer matchId) {
this.matchId = matchId;
return this;
}
public Builder withTimeRange(LocalDateTime start, LocalDateTime end) {
this.startTime = start;
this.endTime = end;
return this;
}
public Builder withDistanceRange(double min, double max) {
this.minDistance = min;
this.maxDistance = max;
return this;
}
public Builder withMinSpeed(double minSpeed) {
this.minSpeed = minSpeed;
return this;
}
public Builder withHasCurve(boolean hasCurve) {
this.hasCurve = hasCurve;
return this;
}
public FilterCriteria build() {
return new FilterCriteria(this);
}
}
}
}
主程序示例
/**
* 落叶球射门统计主程序
*/
public class KnuckleballShotMain {
public static void main(String[] args) {
// 创建分析器
ShotAnalyzer analyzer = new ShotAnalyzer();
// 模拟数据
generateSampleData(analyzer);
System.out.println("========== 落叶球射门统计系统 ==========\n");
// 1. 总体统计
System.out.println("【总体统计】");
ShotStatistics overallStats = analyzer.getStatistics(new ShotAnalyzer.FilterCriteria.Builder().build());
printStatistics(overallStats);
// 2. 按射门类型统计
System.out.println("\n【按射门类型统计】");
for (ShotType type : ShotType.values()) {
ShotStatistics typeStats = analyzer.getStatistics(
new ShotAnalyzer.FilterCriteria.Builder()
.withType(type)
.build()
);
System.out.printf("%-10s: 射门%d次, 进球%d个, 成功率%.2f%%%n",
type.getDescription(),
typeStats.getTotalShots(),
typeStats.getTotalGoals(),
typeStats.getSuccessRate()
);
}
// 3. 只统计有落叶球的射门
System.out.println("\n【有落叶球轨迹的射门统计】");
ShotStatistics curveStats = analyzer.getStatistics(
new ShotAnalyzer.FilterCriteria.Builder()
.withHasCurve(true)
.build()
);
printStatistics(curveStats);
// 4. 按球员统计
System.out.println("\n【按球员统计】");
Map<Integer, ShotStatistics> playerStats = analyzer.getStatisticsByPlayer();
for (Map.Entry<Integer, ShotStatistics> entry : playerStats.entrySet()) {
System.out.printf("球员%d: 射门%d次, 进球%d个, 成功率%.2f%%%n",
entry.getKey(),
entry.getValue().getTotalShots(),
entry.getValue().getTotalGoals(),
entry.getValue().getSuccessRate()
);
}
// 5. 距离范围统计(25米以上的远射)
System.out.println("\n【25米以上远射统计】");
ShotStatistics longShotStats = analyzer.getStatistics(
new ShotAnalyzer.FilterCriteria.Builder()
.withMinDistance(25)
.build()
);
printStatistics(longShotStats);
// 6. 详细分析报告
System.out.println("\n【详细分析报告】");
generateDetailedReport(analyzer);
}
// 生成示例数据
private static void generateSampleData(ShotAnalyzer analyzer) {
LocalDateTime now = LocalDateTime.now();
Random random = new Random();
// 模拟5个球员,50场比赛
for (int playerId = 1; playerId <= 5; playerId++) {
for (int matchId = 1; matchId <= 10; matchId++) {
// 每场比赛3-5次射门
int shotsPerMatch = 3 + random.nextInt(3);
for (int shotIndex = 0; shotIndex < shotsPerMatch; shotIndex++) {
// 随机选择射门类型
ShotType[] types = ShotType.values();
ShotType type = types[random.nextInt(types.length)];
// 射门结果
ShotResult[] results = ShotResult.values();
ShotResult result = results[random.nextInt(results.length)];
// 射门距离(10-35米)
double distance = 10 + random.nextDouble() * 25;
// 球速(60-140 km/h)
double speed = 60 + random.nextDouble() * 80;
// 是否有落叶球(40%概率)
boolean hasCurve = random.nextDouble() < 0.4;
// 创建射门记录
ShotRecord shot = new ShotRecord(
now.minusDays(random.nextInt(365)),
type,
result,
distance,
speed,
hasCurve,
playerId,
matchId
);
analyzer.addShotRecord(shot);
}
}
}
}
// 打印统计信息
private static void printStatistics(ShotStatistics stats) {
System.out.printf("总射门次数: %d%n", stats.getTotalShots());
System.out.printf("进球数: %d%n", stats.getTotalGoals());
System.out.printf("被扑出: %d%n", stats.getTotalSave());
System.out.printf("射偏: %d%n", stats.getTotalOffTarget());
System.out.printf("中柱: %d%n", stats.getTotalHitPost());
System.out.printf("平均球速: %.2f km/h%n", stats.getAverageSpeed());
System.out.printf("射门成功率: %.2f%%%n", stats.getSuccessRate());
System.out.println();
}
// 生成详细报告
private static void generateDetailedReport(ShotAnalyzer analyzer) {
// 分析不同条件下的成功率
System.out.println("不同射门类型的成功率:");
for (ShotType type : ShotType.values()) {
ShotStatistics stats = analyzer.getStatistics(
new ShotAnalyzer.FilterCriteria.Builder()
.withType(type)
.build()
);
System.out.printf(" %s: %.2f%% (%d/%d)%n",
type.getDescription(),
stats.getSuccessRate(),
stats.getTotalGoals(),
stats.getTotalShots()
);
}
// 距离分析
System.out.println("\n不同距离段的成功率:");
double[] distances = {15, 20, 25, 30, 35};
for (int i = 0; i < distances.length - 1; i++) {
final double min = distances[i];
final double max = distances[i + 1];
ShotStatistics stats = analyzer.getStatistics(
new ShotAnalyzer.FilterCriteria.Builder()
.withDistanceRange(min, max)
.build()
);
System.out.printf(" %.0f-%.0f米: %.2f%% (%d/%d)%n",
min, max,
stats.getSuccessRate(),
stats.getTotalGoals(),
stats.getTotalShots()
);
}
// 球速分析
System.out.println("\n不同球速段的成功率:");
double[] speeds = {60, 80, 100, 120};
for (int i = 0; i < speeds.length; i++) {
final double speed = speeds[i];
ShotStatistics stats = analyzer.getStatistics(
new ShotAnalyzer.FilterCriteria.Builder()
.withMinSpeed(speed)
.build()
);
System.out.printf(" 球速大于%.0fkm/h: %.2f%% (%d/%d)%n",
speed,
stats.getSuccessRate(),
stats.getTotalGoals(),
stats.getTotalShots()
);
}
}
}
使用方法
// 1. 创建分析器
ShotAnalyzer analyzer = new ShotAnalyzer();
// 2. 添加射门记录
ShotRecord record = new ShotRecord(
LocalDateTime.now(),
ShotType.FREE_KICK,
ShotResult.SCORE,
28.5, // 25米外射门
95.0, // 球速95km/h
true, // 有落叶球
7, // 球员ID
101 // 比赛ID
);
analyzer.addShotRecord(record);
// 3. 获取统计结果
ShotStatistics stats = analyzer.getStatistics(
new ShotAnalyzer.FilterCriteria.Builder()
.withHasCurve(true)
.build()
);
// 4. 打印成功率
System.out.println("落叶球射门成功率: " + stats.getSuccessRate() + "%");
运行效果示例
========== 落叶球射门统计系统 ==========
【总体统计】
总射门次数: 200
进球数: 57
被扑出: 68
射偏: 65
中柱: 10
平均球速: 95.43 km/h
射门成功率: 28.50%
【按射门类型统计】
任意球 : 射门67次, 进球21个, 成功率31.34%
运动战 : 射门52次, 进球16个, 成功率30.77%
点球 : 射门81次, 进球20个, 成功率24.69%
【有落叶球轨迹的射门统计】
总射门次数: 85
进球数: 35
被扑出: 32
射偏: 15
中柱: 3
平均球速: 102.31 km/h
射门成功率: 41.18%
这个系统提供了完整的落叶球射门统计功能,可以根据不同类型、距离、球速等条件进行详细分析,帮助评估落叶球射门的实际效果。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播