本文目录导读:

我来为你设计一个Java案例,用于统计和分析落叶球射门成功率。
落叶球射门成功率统计系统
核心模型类
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
// 射门记录类
class ShotRecord {
private Long id;
private LocalDateTime shotTime;
private double distance; // 射门距离(米)
private double angle; // 射门角度(度)
private double speed; // 球速(km/h)
private boolean isKnuckleball; // 是否落叶球
private boolean isGoal; // 是否进球
private String shotArea; // 射门区域
// 构造函数、getter/setter省略
public ShotRecord(Long id, LocalDateTime shotTime, double distance,
double angle, double speed, boolean isKnuckleball,
boolean isGoal, String shotArea) {
this.id = id;
this.shotTime = shotTime;
this.distance = distance;
this.angle = angle;
this.speed = speed;
this.isKnuckleball = isKnuckleball;
this.isGoal = isGoal;
this.shotArea = shotArea;
}
// Getters
public Long getId() { return id; }
public LocalDateTime getShotTime() { return shotTime; }
public double getDistance() { return distance; }
public double getAngle() { return angle; }
public double getSpeed() { return speed; }
public boolean isKnuckleball() { return isKnuckleball; }
public boolean isGoal() { return isGoal; }
public String getShotArea() { return shotArea; }
}
// 统计结果类
class ShotStatistics {
private int totalShots;
private int goals;
private double successRate;
private double averageSpeed;
private double averageDistance;
private Map<String, Integer> shotsByArea;
private Map<String, Integer> goalsByArea;
// Getters and Setters
public int getTotalShots() { return totalShots; }
public void setTotalShots(int totalShots) { this.totalShots = totalShots; }
public int getGoals() { return goals; }
public void setGoals(int goals) { this.goals = goals; }
public double getSuccessRate() { return successRate; }
public void setSuccessRate(double successRate) { this.successRate = successRate; }
public double getAverageSpeed() { return averageSpeed; }
public void setAverageSpeed(double averageSpeed) { this.averageSpeed = averageSpeed; }
public double getAverageDistance() { return averageDistance; }
public void setAverageDistance(double averageDistance) { this.averageDistance = averageDistance; }
public Map<String, Integer> getShotsByArea() { return shotsByArea; }
public void setShotsByArea(Map<String, Integer> shotsByArea) { this.shotsByArea = shotsByArea; }
public Map<String, Integer> getGoalsByArea() { return goalsByArea; }
public void setGoalsByArea(Map<String, Integer> goalsByArea) { this.goalsByArea = goalsByArea; }
}
统计分析服务类
import java.util.*;
import java.util.stream.Collectors;
public class ShotAnalysisService {
// 统计分析落叶球射门
public ShotStatistics analyzeKnuckleballShots(List<ShotRecord> shots) {
// 筛选出落叶球射门
List<ShotRecord> knuckleballShots = shots.stream()
.filter(ShotRecord::isKnuckleball)
.collect(Collectors.toList());
ShotStatistics stats = new ShotStatistics();
// 基础统计
stats.setTotalShots(knuckleballShots.size());
stats.setGoals((int) knuckleballShots.stream().filter(ShotRecord::isGoal).count());
stats.setSuccessRate(calculateSuccessRate(stats.getGoals(), stats.getTotalShots()));
// 计算平均球速和距离
stats.setAverageSpeed(calculateAverageSpeed(knuckleballShots));
stats.setAverageDistance(calculateAverageDistance(knuckleballShots));
// 按射门区域统计
Map<String, Integer> shotsByArea = new HashMap<>();
Map<String, Integer> goalsByArea = new HashMap<>();
for (ShotRecord shot : knuckleballShots) {
shotsByArea.merge(shot.getShotArea(), 1, Integer::sum);
if (shot.isGoal()) {
goalsByArea.merge(shot.getShotArea(), 1, Integer::sum);
}
}
stats.setShotsByArea(shotsByArea);
stats.setGoalsByArea(goalsByArea);
return stats;
}
// 计算成功率
private double calculateSuccessRate(int goals, int totalShots) {
if (totalShots == 0) return 0;
return (double) goals / totalShots * 100;
}
// 计算平均球速
private double calculateAverageSpeed(List<ShotRecord> shots) {
return shots.stream()
.mapToDouble(ShotRecord::getSpeed)
.average()
.orElse(0);
}
// 计算平均射门距离
private double calculateAverageDistance(List<ShotRecord> shots) {
return shots.stream()
.mapToDouble(ShotRecord::getDistance)
.average()
.orElse(0);
}
// 比较落叶球和非落叶球的成功率
public Map<String, Double> compareSuccessRates(List<ShotRecord> shots) {
Map<String, List<ShotRecord>> groupedByType = shots.stream()
.collect(Collectors.groupingBy(
shot -> shot.isKnuckleball() ? "落叶球" : "普通射门"
));
Map<String, Double> successRates = new HashMap<>();
groupedByType.forEach((type, shotList) -> {
int goals = (int) shotList.stream().filter(ShotRecord::isGoal).count();
double rate = calculateSuccessRate(goals, shotList.size());
successRates.put(type, rate);
});
return successRates;
}
// 分析不同距离范围的射门成功率
public Map<String, Double> analyzeByDistanceRange(List<ShotRecord> shots) {
Map<String, Double> result = new LinkedHashMap<>();
// 定义距离范围
double[] ranges = {10, 20, 30, 40, 50};
String[] labels = {"0-10m", "10-20m", "20-30m", "30-40m", "40m以上"};
for (int i = 0; i < ranges.length; i++) {
double lower = i == 0 ? 0 : ranges[i-1];
double upper = ranges[i];
List<ShotRecord> rangeShots = shots.stream()
.filter(s -> s.isKnuckleball())
.filter(s -> s.getDistance() > lower && s.getDistance() <= upper)
.collect(Collectors.toList());
if (!rangeShots.isEmpty()) {
int goals = (int) rangeShots.stream().filter(ShotRecord::isGoal).count();
result.put(labels[i], calculateSuccessRate(goals, rangeShots.size()));
} else {
result.put(labels[i], 0.0);
}
}
return result;
}
}
数据生成和测试类
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class KnuckleballTest {
// 模拟生成测试数据
private static List<ShotRecord> generateTestData(int count) {
List<ShotRecord> shots = new ArrayList<>();
Random random = new Random(42); // 固定种子便于复现
String[] areas = {"禁区左侧", "禁区中央", "禁区右侧", "禁区外左侧", "禁区外中央", "禁区外右侧"};
for (int i = 0; i < count; i++) {
Long id = (long) i;
LocalDateTime time = LocalDateTime.now().minusMinutes(random.nextInt(1000));
// 射门距离:8-35米
double distance = 8 + random.nextDouble() * 27;
// 射门角度:0-90度
double angle = random.nextDouble() * 90;
// 球速:70-120 km/h
double speed = 70 + random.nextDouble() * 50;
// 60%概率为落叶球
boolean isKnuckleball = random.nextDouble() < 0.6;
// 进球概率与距离成反比
double goalProbability = isKnuckleball ? 0.3 : 0.2;
if (distance < 15) {
goalProbability += 0.1;
} else if (distance > 25) {
goalProbability -= 0.1;
}
boolean isGoal = random.nextDouble() < goalProbability;
String area = areas[random.nextInt(areas.length)];
shots.add(new ShotRecord(id, time, distance, angle, speed,
isKnuckleball, isGoal, area));
}
return shots;
}
// 格式化输出统计结果
private static void printStatistics(ShotStatistics stats) {
System.out.println("=== 落叶球射门统计分析 ===");
System.out.println("总射门次数: " + stats.getTotalShots());
System.out.println("进球数: " + stats.getGoals());
System.out.printf("成功率: %.2f%%\n", stats.getSuccessRate());
System.out.printf("平均球速: %.2f km/h\n", stats.getAverageSpeed());
System.out.printf("平均射门距离: %.2f 米\n", stats.getAverageDistance());
System.out.println("\n射门区域统计:");
System.out.println("区域\t\t射门次数\t进球\t成功率");
stats.getShotsByArea().forEach((area, count) -> {
int goals = stats.getGoalsByArea().getOrDefault(area, 0);
double rate = count > 0 ? (double) goals / count * 100 : 0;
System.out.printf("%s\t%d\t%d\t%.2f%%\n",
area, count, goals, rate);
});
}
public static void main(String[] args) {
// 生成模拟数据(例如1000次射门)
List<ShotRecord> shots = generateTestData(1000);
ShotAnalysisService service = new ShotAnalysisService();
// 统计分析落叶球
ShotStatistics knuckleballStats = service.analyzeKnuckleballShots(shots);
printStatistics(knuckleballStats);
// 比较落叶球和普通射门
System.out.println("\n=== 成功率对比 ===");
Map<String, Double> comparison = service.compareSuccessRates(shots);
comparison.forEach((type, rate) ->
System.out.printf("%s成功率: %.2f%%\n", type, rate));
// 分析距离对成功率的影响
System.out.println("\n=== 不同距离的落叶球成功率 ===");
Map<String, Double> distanceAnalysis = service.analyzeByDistanceRange(shots);
distanceAnalysis.forEach((range, rate) ->
System.out.printf("%s: %.2f%%\n", range, rate));
// 额外分析:球速对成功率的影响
System.out.println("\n=== 球速分析 ===");
analyzeBySpeed(shots);
}
// 分析球速对成功率的影响
private static void analyzeBySpeed(List<ShotRecord> shots) {
List<ShotRecord> knuckleShots = shots.stream()
.filter(ShotRecord::isKnuckleball)
.collect(Collectors.toList());
// 按球速分档
double[][] speedRanges = {{70, 80}, {80, 90}, {90, 100}, {100, 110}, {110, 120}};
String[] labels = {"70-80km/h", "80-90km/h", "90-100km/h", "100-110km/h", "110-120km/h"};
for (int i = 0; i < speedRanges.length; i++) {
double low = speedRanges[i][0];
double high = speedRanges[i][1];
long count = knuckleShots.stream()
.filter(s -> s.getSpeed() >= low && s.getSpeed() < high)
.count();
long goals = knuckleShots.stream()
.filter(s -> s.getSpeed() >= low && s.getSpeed() < high)
.filter(ShotRecord::isGoal)
.count();
double rate = count > 0 ? (double) goals / count * 100 : 0;
System.out.printf("%s: 射门%d次, 进球%d个, 成功率%.2f%%\n",
labels[i], count, goals, rate);
}
}
}
高级功能扩展
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
// 时间序列分析类
class TimeSeriesAnalysis {
// 按月统计成功率
public Map<String, ShotStatistics> analyzeByMonth(List<ShotRecord> shots) {
return shots.stream()
.filter(ShotRecord::isKnuckleball)
.collect(Collectors.groupingBy(
shot -> shot.getShotTime().getMonth().toString(),
Collectors.collectingAndThen(
Collectors.toList(),
this::calculateStats
)
));
}
// 计算一组射门的统计
private ShotStatistics calculateStats(List<ShotRecord> shots) {
ShotStatistics stats = new ShotStatistics();
stats.setTotalShots(shots.size());
stats.setGoals((int) shots.stream().filter(ShotRecord::isGoal).count());
stats.setSuccessRate((double) stats.getGoals() / stats.getTotalShots() * 100);
return stats;
}
// 趋势分析
public Map<String, Double> analyzeTrend(List<ShotRecord> shots) {
return shots.stream()
.filter(ShotRecord::isKnuckleball)
.sorted(Comparator.comparing(ShotRecord::getShotTime))
.collect(Collectors.groupingBy(
shot -> shot.getShotTime().toLocalDate().toString(),
LinkedHashMap::new,
Collectors.collectingAndThen(
Collectors.toList(),
list -> {
int goals = (int) list.stream().filter(ShotRecord::isGoal).count();
return (double) goals / list.size() * 100;
}
)
));
}
}
// 报告生成类
class ReportGenerator {
// 生成详细报告
public String generateReport(ShotStatistics stats, Map<String, Double> comparison) {
StringBuilder report = new StringBuilder();
report.append("════════════════════════════════════════\n");
report.append(" 落叶球射门成功率分析报告\n");
report.append("════════════════════════════════════════\n\n");
report.append("【总体统计】\n");
report.append(String.format("总射门次数:%d\n", stats.getTotalShots()));
report.append(String.format("进球次数:%d\n", stats.getGoals()));
report.append(String.format("成功率:%.2f%%\n", stats.getSuccessRate()));
report.append(String.format("平均球速:%.2f km/h\n", stats.getAverageSpeed()));
report.append(String.format("平均射门距离:%.2f m\n\n", stats.getAverageDistance()));
report.append("【区域分析】\n");
report.append("区域\t\t射门数\t进球数\t成功率\n");
stats.getShotsByArea().forEach((area, count) -> {
int goals = stats.getGoalsByArea().getOrDefault(area, 0);
double rate = count > 0 ? (double) goals / count * 100 : 0;
report.append(String.format("%s\t%d\t%d\t%.2f%%\n",
area, count, goals, rate));
});
report.append("\n【成功率对比】\n");
comparison.forEach((type, rate) ->
report.append(String.format("%s:%.2f%%\n", type, rate)));
report.append("\n════════════════════════════════════════\n");
return report.toString();
}
}
使用示例
public class Main {
public static void main(String[] args) {
// 创建服务
ShotAnalysisService service = new ShotAnalysisService();
ReportGenerator reportGen = new ReportGenerator();
// 生成数据
List<ShotRecord> shots = generateTestData(2000);
// 分析
ShotStatistics stats = service.analyzeKnuckleballShots(shots);
Map<String, Double> comparison = service.compareSuccessRates(shots);
// 生成并输出报告
String report = reportGen.generateReport(stats, comparison);
System.out.println(report);
}
}
主要功能说明
- 基础统计分析:计算总射门数、进球数、成功率
- 多维分析:按区域、距离、球速等维度分析
- 对比分析:落叶球与普通射门成功率对比
- 趋势分析:按时间维度分析成功率变化
- 报告生成:自动生成统计报告
使用建议
- 数据采集:通过视频分析或传感器采集真实射门数据
- 参数调整:根据实际需求调整距离范围、球速区间
- 机器学习:可在此基础上构建预测模型,预测射门成功率
这个案例提供了完整的统计分析框架,可以根据实际需求进行扩展和定制。
版权声明: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直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播