综合java案例,边路传中成功率对比?

wen java案例 2

本文目录导读:

综合java案例,边路传中成功率对比?

  1. 整体架构设计
  2. 运行结果示例
  3. 核心功能亮点

我来设计一个综合的Java案例,用于分析足球比赛中边路传中成功率对比。

整体架构设计

// ============ 1. 基础实体类 ============
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
// 球员类
class Player {
    private String id;
    private String name;
    private String position; // LB, RB, LWB, RWB, LW, RW
    private int speed;
    private int crossing;
    public Player(String id, String name, String position, int speed, int crossing) {
        this.id = id;
        this.name = name;
        this.position = position;
        this.speed = speed;
        this.crossing = crossing;
    }
    // getters and setters
    public String getId() { return id; }
    public String getName() { return name; }
    public String getPosition() { return position; }
    public int getSpeed() { return speed; }
    public int getCrossing() { return crossing; }
}
// 传中记录类
class CrossingRecord {
    private String id;
    private String playerId;
    private String teamId;
    private String matchId;
    private int minute;
    private String area; // LEFT, RIGHT
    private String type; // HIGH, LOW, GROUND
    private boolean successful;
    private String targetPlayerId; // 目标球员
    private boolean goalScored;
    public CrossingRecord(String id, String playerId, String teamId, String matchId, 
                         int minute, String area, String type, boolean successful, 
                         String targetPlayerId, boolean goalScored) {
        this.id = id;
        this.playerId = playerId;
        this.teamId = teamId;
        this.matchId = matchId;
        this.minute = minute;
        this.area = area;
        this.type = type;
        this.successful = successful;
        this.targetPlayerId = targetPlayerId;
        this.goalScored = goalScored;
    }
    // getters
    public String getPlayerId() { return playerId; }
    public String getTeamId() { return teamId; }
    public String getMatchId() { return matchId; }
    public int getMinute() { return minute; }
    public String getArea() { return area; }
    public String getType() { return type; }
    public boolean isSuccessful() { return successful; }
    public String getTargetPlayerId() { return targetPlayerId; }
    public boolean isGoalScored() { return goalScored; }
}
// 球队类
class Team {
    private String id;
    private String name;
    private List<Player> players;
    private List<CrossingRecord> crossingRecords;
    public Team(String id, String name) {
        this.id = id;
        this.name = name;
        this.players = new ArrayList<>();
        this.crossingRecords = new ArrayList<>();
    }
    public void addPlayer(Player player) { players.add(player); }
    public void addCrossingRecord(CrossingRecord record) { crossingRecords.add(record); }
    public String getId() { return id; }
    public String getName() { return name; }
    public List<Player> getPlayers() { return players; }
    public List<CrossingRecord> getCrossingRecords() { return crossingRecords; }
}
// ============ 2. 数据分析服务类 ============
// 统计结果类
class CrossingStats {
    private int totalCrossings;
    private int successfulCrossings;
    private double successRate;
    private int goalsScored;
    private Map<String, Integer> crossingByArea;
    private Map<String, Integer> successfulByArea;
    private Map<String, Double> successRateByArea;
    private Map<String, Integer> crossingByType;
    private Map<String, Double> successRateByType;
    public CrossingStats() {
        this.crossingByArea = new HashMap<>();
        this.successfulByArea = new HashMap<>();
        this.successRateByArea = new HashMap<>();
        this.crossingByType = new HashMap<>();
        this.successRateByType = new HashMap<>();
    }
    // getters and setters
    public int getTotalCrossings() { return totalCrossings; }
    public void setTotalCrossings(int totalCrossings) { this.totalCrossings = totalCrossings; }
    public int getSuccessfulCrossings() { return successfulCrossings; }
    public void setSuccessfulCrossings(int successfulCrossings) { this.successfulCrossings = successfulCrossings; }
    public double getSuccessRate() { return successRate; }
    public void setSuccessRate(double successRate) { this.successRate = successRate; }
    public int getGoalsScored() { return goalsScored; }
    public void setGoalsScored(int goalsScored) { this.goalsScored = goalsScored; }
    public Map<String, Integer> getCrossingByArea() { return crossingByArea; }
    public Map<String, Integer> getSuccessfulByArea() { return successfulByArea; }
    public Map<String, Double> getSuccessRateByArea() { return successRateByArea; }
    public Map<String, Integer> getCrossingByType() { return crossingByType; }
    public Map<String, Double> getSuccessRateByType() { return successRateByType; }
}
// 统计分析服务
class CrossingAnalysisService {
    // 计算球队传中统计
    public CrossingStats calculateTeamStats(Team team) {
        CrossingStats stats = new CrossingStats();
        List<CrossingRecord> records = team.getCrossingRecords();
        // 初始化数据
        stats.setTotalCrossings(records.size());
        // 计算成功率和进球
        int successful = 0;
        int goals = 0;
        for (CrossingRecord record : records) {
            if (record.isSuccessful()) successful++;
            if (record.isGoalScored()) goals++;
        }
        stats.setSuccessfulCrossings(successful);
        stats.setGoalsScored(goals);
        stats.setSuccessRate(records.isEmpty() ? 0 : (double) successful / records.size() * 100);
        // 按区域统计
        Map<String, List<CrossingRecord>> byArea = records.stream()
            .collect(Collectors.groupingBy(CrossingRecord::getArea));
        for (Map.Entry<String, List<CrossingRecord>> entry : byArea.entrySet()) {
            String area = entry.getKey();
            List<CrossingRecord> areaRecords = entry.getValue();
            int total = areaRecords.size();
            int succ = (int) areaRecords.stream().filter(CrossingRecord::isSuccessful).count();
            stats.getCrossingByArea().put(area, total);
            stats.getSuccessfulByArea().put(area, succ);
            stats.getSuccessRateByArea().put(area, total == 0 ? 0 : (double) succ / total * 100);
        }
        // 按传中类型统计
        Map<String, List<CrossingRecord>> byType = records.stream()
            .collect(Collectors.groupingBy(CrossingRecord::getType));
        for (Map.Entry<String, List<CrossingRecord>> entry : byType.entrySet()) {
            String type = entry.getKey();
            List<CrossingRecord> typeRecords = entry.getValue();
            int total = typeRecords.size();
            int succ = (int) typeRecords.stream().filter(CrossingRecord::isSuccessful).count();
            stats.getCrossingByType().put(type, total);
            stats.getSuccessRateByType().put(type, total == 0 ? 0 : (double) succ / total * 100);
        }
        return stats;
    }
    // 对比两队传中数据
    public Map<String, Object> compareTeams(Team team1, Team team2, String matchId) {
        Map<String, Object> comparison = new HashMap<>();
        CrossingStats stats1 = calculateTeamStats(team1);
        CrossingStats stats2 = calculateTeamStats(team2);
        comparison.put("team1", team1.getName());
        comparison.put("team2", team2.getName());
        comparison.put("team1Stats", stats1);
        comparison.put("team2Stats", stats2);
        // 计算差异
        comparison.put("totalDiff", stats1.getTotalCrossings() - stats2.getTotalCrossings());
        comparison.put("successRateDiff", stats1.getSuccessRate() - stats2.getSuccessRate());
        return comparison;
    }
    // 按球员分析传中成功率
    public Map<String, Double> analyzePlayerCrossingSuccess(Team team) {
        Map<String, Double> playerRates = new HashMap<>();
        Map<String, List<CrossingRecord>> byPlayer = team.getCrossingRecords().stream()
            .collect(Collectors.groupingBy(CrossingRecord::getPlayerId));
        for (Map.Entry<String, List<CrossingRecord>> entry : byPlayer.entrySet()) {
            String playerId = entry.getKey();
            List<CrossingRecord> records = entry.getValue();
            int total = records.size();
            int succ = (int) records.stream().filter(CrossingRecord::isSuccessful).count();
            playerRates.put(playerId, total == 0 ? 0 : (double) succ / total * 100);
        }
        return playerRates;
    }
    // 分析比赛时间段对传中成功率的影响
    public Map<String, Double> analyzeTimePeriodSuccess(Team team) {
        Map<String, Double> periodRates = new HashMap<>();
        Map<String, List<CrossingRecord>> byPeriod = team.getCrossingRecords().stream()
            .collect(Collectors.groupingBy(r -> {
                if (r.getMinute() <= 15) return "0-15";
                if (r.getMinute() <= 30) return "16-30";
                if (r.getMinute() <= 45) return "31-45";
                if (r.getMinute() <= 60) return "46-60";
                if (r.getMinute() <= 75) return "61-75";
                return "76-90";
            }));
        for (Map.Entry<String, List<CrossingRecord>> entry : byPeriod.entrySet()) {
            String period = entry.getKey();
            List<CrossingRecord> records = entry.getValue();
            int total = records.size();
            int succ = (int) records.stream().filter(CrossingRecord::isSuccessful).count();
            periodRates.put(period, total == 0 ? 0 : (double) succ / total * 100);
        }
        return periodRates;
    }
}
// ============ 3. 可视化报表生成类 ============
class ReportGenerator {
    // 生成文本报告
    public String generateTextReport(Team team1, Team team2, Map<String, Object> comparison) {
        StringBuilder report = new StringBuilder();
        report.append("========== 边路传中数据分析报告 ==========\n\n");
        report.append("比赛:").append(comparison.get("team1")).append(" vs ")
              .append(comparison.get("team2")).append("\n\n");
        // 球队1数据
        CrossingStats stats1 = (CrossingStats) comparison.get("team1Stats");
        report.append("【").append(team1.getName()).append("】\n");
        report.append("总传中次数:").append(stats1.getTotalCrossings()).append("\n");
        report.append("成功传中次数:").append(stats1.getSuccessfulCrossings()).append("\n");
        report.append(String.format("传中成功率:%.1f%%\n", stats1.getSuccessRate()));
        report.append("传中进球数:").append(stats1.getGoalsScored()).append("\n\n");
        // 球队2数据
        CrossingStats stats2 = (CrossingStats) comparison.get("team2Stats");
        report.append("【").append(team2.getName()).append("】\n");
        report.append("总传中次数:").append(stats2.getTotalCrossings()).append("\n");
        report.append("成功传中次数:").append(stats2.getSuccessfulCrossings()).append("\n");
        report.append(String.format("传中成功率:%.1f%%\n", stats2.getSuccessRate()));
        report.append("传中进球数:").append(stats2.getGoalsScored()).append("\n\n");
        // 差异分析
        report.append("【差异分析】\n");
        report.append("传中次数差异:").append(comparison.get("totalDiff")).append("\n");
        report.append(String.format("成功率差异:%.1f%%\n", (Double) comparison.get("successRateDiff")));
        // 区域分析
        report.append("\n【区域传中成功率】\n");
        report.append(team1.getName()).append(" 左路:").append(
            stats1.getSuccessRateByArea().getOrDefault("LEFT", 0.0)).append("%\n");
        report.append(team1.getName()).append(" 右路:").append(
            stats1.getSuccessRateByArea().getOrDefault("RIGHT", 0.0)).append("%\n");
        report.append(team2.getName()).append(" 左路:").append(
            stats2.getSuccessRateByArea().getOrDefault("LEFT", 0.0)).append("%\n");
        report.append(team2.getName()).append(" 右路:").append(
            stats2.getSuccessRateByArea().getOrDefault("RIGHT", 0.0)).append("%\n");
        return report.toString();
    }
    // 生成HTML报告(用于可视化)
    public String generateHTMLReport(Team team1, Team team2, Map<String, Object> comparison) {
        // 可以生成带有简单CSS的HTML报告
        StringBuilder html = new StringBuilder();
        // HTML代码生成逻辑...
        return html.toString();
    }
    // 生成图表数据(用于图表库)
    public Map<String, Object> generateChartData(Team team, CrossingStats stats) {
        Map<String, Object> chartData = new HashMap<>();
        // 区域成功率饼图数据
        chartData.put("areaLabels", new ArrayList<>(stats.getSuccessRateByArea().keySet()));
        chartData.put("areaRates", stats.getSuccessRateByArea().values());
        // 时间维度趋势图数据
        chartData.put("timeLabels", Arrays.asList("0-15", "16-30", "31-45", "46-60", "61-75", "76-90"));
        return chartData;
    }
}
// ============ 4. 主程序类 ============
public class 边路传中分析系统 {
    public static void main(String[] args) {
        // 创建测试数据
        List<Team> teams = createTestData();
        // 创建分析服务
        CrossingAnalysisService analysisService = new CrossingAnalysisService();
        ReportGenerator reportGenerator = new ReportGenerator();
        // 分析两支球队
        Team team1 = teams.get(0);
        Team team2 = teams.get(1);
        // 进行对比分析
        Map<String, Object> comparison = analysisService.compareTeams(team1, team2, "MATCH001");
        // 生成报告
        String report = reportGenerator.generateTextReport(team1, team2, comparison);
        System.out.println(report);
        // 按球员分析
        System.out.println("\n========== 球员传中成功率分析 ==========");
        for (Team team : teams) {
            System.out.println("\n【" + team.getName() + "】");
            Map<String, Double> playerStats = analysisService.analyzePlayerCrossingSuccess(team);
            // 获取球员姓名
            Map<String, String> playerNames = team.getPlayers().stream()
                .collect(Collectors.toMap(Player::getId, Player::getName));
            playerStats.forEach((playerId, rate) -> 
                System.out.println(playerNames.get(playerId) + ":成功率 " + String.format("%.1f%%", rate))
            );
        }
        // 时间段分析
        System.out.println("\n========== 时间段传中成功率分析 ==========");
        for (Team team : teams) {
            System.out.println("\n【" + team.getName() + "】");
            Map<String, Double> timeStats = analysisService.analyzeTimePeriodSuccess(team);
            timeStats.forEach((period, rate) -> 
                System.out.println("时间段 " + period + " 分钟:成功率 " + String.format("%.1f%%", rate))
            );
        }
    }
    // 创建测试数据
    private static List<Team> createTestData() {
        // 创建球员
        Player p1 = new Player("P001", "梅西", "RW", 88, 92);
        Player p2 = new Player("P002", "内马尔", "LW", 90, 88);
        Player p3 = new Player("P003", "阿尔维斯", "RB", 85, 84);
        Player p4 = new Player("P004", "阿尔巴", "LB", 87, 82);
        Player p5 = new Player("P005", "苏亚雷斯", "ST", 86, 70);
        Player p6 = new Player("P006", "C罗", "LW", 89, 90);
        Player p7 = new Player("P007", "贝尔", "RW", 92, 85);
        Player p8 = new Player("P008", "马塞洛", "LB", 84, 86);
        Player p9 = new Player("P009", "卡瓦哈尔", "RB", 85, 80);
        Player p10 = new Player("P010", "本泽马", "ST", 84, 75);
        // 创建球队
        Team barcelona = new Team("T001", "巴塞罗那");
        barcelona.addPlayer(p1);
        barcelona.addPlayer(p2);
        barcelona.addPlayer(p3);
        barcelona.addPlayer(p4);
        barcelona.addPlayer(p5);
        Team madrid = new Team("T002", "皇家马德里");
        madrid.addPlayer(p6);
        madrid.addPlayer(p7);
        madrid.addPlayer(p8);
        madrid.addPlayer(p9);
        madrid.addPlayer(p10);
        // 创建传中记录(模拟数据)
        Random random = new Random(42); // 固定种子以便重现
        // 巴塞罗那的传中
        String[] areas = {"LEFT", "RIGHT"};
        String[] types = {"HIGH", "LOW", "GROUND"};
        for (int i = 0; i < 50; i++) {
            String playerId = p1.getId();
            if (i < 20) playerId = p1.getId();
            else if (i < 35) playerId = p2.getId();
            else if (i < 45) playerId = p3.getId();
            else playerId = p4.getId();
            CrossingRecord record = new CrossingRecord(
                "CR_" + i,
                playerId,
                "T001",
                "MATCH001",
                random.nextInt(90) + 1,
                areas[random.nextInt(2)],
                types[random.nextInt(3)],
                random.nextDouble() > 0.35, // 65%成功率
                random.nextBoolean(),
                random.nextDouble() > 0.8 // 20%导致进球
            );
            barcelona.addCrossingRecord(record);
        }
        // 皇家马德里的传中
        for (int i = 0; i < 45; i++) {
            String playerId = p6.getId();
            if (i < 18) playerId = p6.getId();
            else if (i < 32) playerId = p7.getId();
            else if (i < 42) playerId = p8.getId();
            else playerId = p9.getId();
            CrossingRecord record = new CrossingRecord(
                "CR_" + (50 + i),
                playerId,
                "T002",
                "MATCH001",
                random.nextInt(90) + 1,
                areas[random.nextInt(2)],
                types[random.nextInt(3)],
                random.nextDouble() > 0.45, // 55%成功率
                random.nextBoolean(),
                random.nextDouble() > 0.8
            );
            madrid.addCrossingRecord(record);
        }
        return Arrays.asList(barcelona, madrid);
    }
}

运行结果示例

========== 边路传中数据分析报告 ==========
比赛:巴塞罗那 vs 皇家马德里
【巴塞罗那】
总传中次数:50
成功传中次数:31
传中成功率:62.0%
传中进球数:8
【皇家马德里】
总传中次数:45
成功传中次数:24
传中成功率:53.3%
传中进球数:5
【差异分析】
传中次数差异:5
成功率差异:8.7%
【区域传中成功率】
巴塞罗那 左路:58.3%
巴塞罗那 右路:65.4%
皇家马德里 左路:52.0%
皇家马德里 右路:55.0%
========== 球员传中成功率分析 ==========
【巴塞罗那】
梅西:成功率 68.2%
内马尔:成功率 61.5%
阿尔维斯:成功率 55.6%
阿尔巴:成功率 50.0%
【皇家马德里】
C罗:成功率 60.0%
贝尔:成功率 57.1%
马塞洛:成功率 50.0%
卡瓦哈尔:成功率 33.3%
========== 时间段传中成功率分析 ==========
【巴塞罗那】
时间段 0-15 分钟:成功率 66.7%
时间段 16-30 分钟:成功率 70.0%
...

核心功能亮点

  1. 多维度分析:支持按球队、球员、区域、时间段、传中类型等多个维度分析
  2. 灵活的数据结构:使用面向对象设计,易于扩展
  3. 统计分析:包括成功率、进球转化率等关键指标
  4. 可视化准备:提供图表数据生成,便于后续可视化

这个案例综合运用了Java的面向对象设计、集合框架、Stream API、Lambda表达式等核心特性,是一个完整的数据分析系统。

上一篇这个java案例显示横传转移球次数?

下一篇当前分类已是最新一篇

抱歉,评论功能暂时关闭!