java案例统计高球传中争顶成功率?

wen java案例 1

本文目录导读:

java案例统计高球传中争顶成功率?

  1. 核心实体类设计
  2. 统计服务类
  3. 数据模拟和主程序
  4. 高级分析扩展(可选)

我将为您设计一个Java案例来统计足球比赛中的高球传中争顶成功率,这个案例将包含完整的面向对象设计和统计逻辑。

核心实体类设计

// 球员实体类
class Player {
    private int id;
    private String name;
    private String position; // 位置:中锋、后卫等
    private double height;   // 身高(米)
    public Player(int id, String name, String position, double height) {
        this.id = id;
        this.name = name;
        this.position = position;
        this.height = height;
    }
    // Getter和Setter
    public int getId() { return id; }
    public String getName() { return name; }
    public String getPosition() { return position; }
    public double getHeight() { return height; }
}
// 争顶事件实体
class AerialDuel {
    private int attackerId;     // 进攻球员ID
    private int defenderId;     // 防守球员ID
    private boolean isWon;      // 是否争顶成功
    private String timestamp;   // 时间戳
    private int gameId;         // 比赛ID
    public AerialDuel(int attackerId, int defenderId, boolean isWon, String timestamp, int gameId) {
        this.attackerId = attackerId;
        this.defenderId = defenderId;
        this.isWon = isWon;
        this.timestamp = timestamp;
        this.gameId = gameId;
    }
    // Getter和Setter
    public int getAttackerId() { return attackerId; }
    public int getDefenderId() { return defenderId; }
    public boolean isWon() { return isWon; }
    public String getTimestamp() { return timestamp; }
    public int getGameId() { return gameId; }
}
// 比赛实体
class Match {
    private int matchId;
    private String homeTeam;
    private String awayTeam;
    private String date;
    public Match(int matchId, String homeTeam, String awayTeam, String date) {
        this.matchId = matchId;
        this.homeTeam = homeTeam;
        this.awayTeam = awayTeam;
        this.date = date;
    }
    // Getter方法
    public int getMatchId() { return matchId; }
    public String getHomeTeam() { return homeTeam; }
    public String getAwayTeam() { return awayTeam; }
    public String getDate() { return date; }
}

统计服务类

import java.util.*;
import java.util.stream.Collectors;
// 统计服务类
class AerialDuelStatisticsService {
    private List<Player> players;
    private List<AerialDuel> duels;
    private List<Match> matches;
    private Map<Integer, String> teamMap; // 球员ID -> 所属球队
    public AerialDuelStatisticsService() {
        this.players = new ArrayList<>();
        this.duels = new ArrayList<>();
        this.matches = new ArrayList<>();
        this.teamMap = new HashMap<>();
    }
    // 添加数据方法
    public void addPlayer(Player player) {
        players.add(player);
    }
    public void addDuel(AerialDuel duel) {
        duels.add(duel);
    }
    public void addMatch(Match match) {
        matches.add(match);
    }
    public void assignPlayerToTeam(int playerId, String teamName) {
        teamMap.put(playerId, teamName);
    }
    // 计算单个球员的争顶成功率
    public double calculatePlayerSuccessRate(int playerId) {
        List<AerialDuel> playerDuels = duels.stream()
            .filter(d -> isPlayerInDuel(d, playerId))
            .collect(Collectors.toList());
        if (playerDuels.isEmpty()) {
            return 0.0;
        }
        long wonDuels = playerDuels.stream()
            .filter(d -> isPlayerWon(d, playerId))
            .count();
        return (double) wonDuels / playerDuels.size() * 100;
    }
    // 判断球员是否参与争顶
    private boolean isPlayerInDuel(AerialDuel duel, int playerId) {
        return duel.getAttackerId() == playerId || duel.getDefenderId() == playerId;
    }
    // 判断球员是否赢得争顶
    private boolean isPlayerWon(AerialDuel duel, int playerId) {
        if (duel.isWon()) {
            return duel.getAttackerId() == playerId;
        } else {
            return duel.getDefenderId() == playerId;
        }
    }
    // 按球队统计争顶成功率
    public Map<String, Double> calculateTeamSuccessRate() {
        Map<String, List<AerialDuel>> teamDuels = new HashMap<>();
        for (AerialDuel duel : duels) {
            String attackerTeam = teamMap.get(duel.getAttackerId());
            String defenderTeam = teamMap.get(duel.getDefenderId());
            teamDuels.computeIfAbsent(attackerTeam, k -> new ArrayList<>()).add(duel);
            // 防守方也算争顶
            AerialDuel defensiveDuel = new AerialDuel(
                duel.getDefenderId(), 
                duel.getAttackerId(), 
                !duel.isWon(), 
                duel.getTimestamp(), 
                duel.getGameId()
            );
            teamDuels.computeIfAbsent(defenderTeam, k -> new ArrayList<>()).add(defensiveDuel);
        }
        Map<String, Double> successRates = new HashMap<>();
        for (Map.Entry<String, List<AerialDuel>> entry : teamDuels.entrySet()) {
            long wonCount = entry.getValue().stream()
                .filter(AerialDuel::isWon)
                .count();
            double rate = (double) wonCount / entry.getValue().size() * 100;
            successRates.put(entry.getKey(), rate);
        }
        return successRates;
    }
    // 按位置统计争顶成功率
    public Map<String, Double> calculatePositionSuccessRate() {
        Map<String, List<AerialDuel>> positionDuels = new HashMap<>();
        Map<Integer, Player> playerMap = players.stream()
            .collect(Collectors.toMap(Player::getId, p -> p));
        for (AerialDuel duel : duels) {
            Player attacker = playerMap.get(duel.getAttackerId());
            Player defender = playerMap.get(duel.getDefenderId());
            if (attacker != null) {
                positionDuels.computeIfAbsent(attacker.getPosition() + "-进攻", 
                    k -> new ArrayList<>()).add(duel);
            }
            if (defender != null) {
                positionDuels.computeIfAbsent(defender.getPosition() + "-防守", 
                    k -> new ArrayList<>()).add(new AerialDuel(
                        duel.getDefenderId(), 
                        duel.getAttackerId(), 
                        !duel.isWon(), 
                        duel.getTimestamp(), 
                        duel.getGameId()
                    ));
            }
        }
        Map<String, Double> successRates = new HashMap<>();
        for (Map.Entry<String, List<AerialDuel>> entry : positionDuels.entrySet()) {
            long wonCount = entry.getValue().stream()
                .filter(AerialDuel::isWon)
                .count();
            double rate = (double) wonCount / entry.getValue().size() * 100;
            successRates.put(entry.getKey(), rate);
        }
        return successRates;
    }
    // 按身高分组统计争顶成功率
    public Map<String, Double> calculateHeightGroupSuccessRate() {
        Map<String, List<AerialDuel>> heightGroups = new LinkedHashMap<>();
        Map<Integer, Player> playerMap = players.stream()
            .collect(Collectors.toMap(Player::getId, p -> p));
        for (AerialDuel duel : duels) {
            Player attacker = playerMap.get(duel.getAttackerId());
            if (attacker != null) {
                String group = getHeightGroup(attacker.getHeight());
                heightGroups.computeIfAbsent(group, k -> new ArrayList<>()).add(duel);
            }
        }
        Map<String, Double> successRates = new LinkedHashMap<>();
        for (Map.Entry<String, List<AerialDuel>> entry : heightGroups.entrySet()) {
            long wonCount = entry.getValue().stream()
                .filter(AerialDuel::isWon)
                .count();
            double rate = (double) wonCount / entry.getValue().size() * 100;
            successRates.put(entry.getKey(), rate);
        }
        return successRates;
    }
    // 获取身高分组
    private String getHeightGroup(double height) {
        if (height < 1.75) return "低于1.75m";
        if (height < 1.85) return "1.75-1.85m";
        if (height < 1.95) return "1.85-1.95m";
        return "1.95m以上";
    }
    // 生成详细报告
    public String generateDetailedReport() {
        StringBuilder report = new StringBuilder();
        report.append("=".repeat(60)).append("\n");
        report.append("高球传中争顶成功率统计报告\n");
        report.append("=".repeat(60)).append("\n\n");
        // 球队统计
        report.append("【球队争顶成功率】\n");
        Map<String, Double> teamStats = calculateTeamSuccessRate();
        teamStats.entrySet().stream()
            .sorted(Map.Entry.<String, Double>comparingByValue().reversed())
            .forEach(entry -> {
                report.append(String.format("%-20s: %.2f%%\n", entry.getKey(), entry.getValue()));
            });
        // 位置统计
        report.append("\n【位置争顶成功率】\n");
        Map<String, Double> positionStats = calculatePositionSuccessRate();
        positionStats.entrySet().stream()
            .sorted(Map.Entry.<String, Double>comparingByValue().reversed())
            .forEach(entry -> {
                report.append(String.format("%-25s: %.2f%%\n", entry.getKey(), entry.getValue()));
            });
        // 身高统计
        report.append("\n【身高分组争顶成功率】\n");
        Map<String, Double> heightStats = calculateHeightGroupSuccessRate();
        heightStats.forEach((group, rate) -> {
            report.append(String.format("%-15s: %.2f%%\n", group, rate));
        });
        // 个人排名
        report.append("\n【个人争顶成功率排名 TOP 10】\n");
        Map<Integer, Double> playerStats = new HashMap<>();
        for (Player player : players) {
            double rate = calculatePlayerSuccessRate(player.getId());
            playerStats.put(player.getId(), rate);
        }
        playerStats.entrySet().stream()
            .sorted(Map.Entry.<Integer, Double>comparingByValue().reversed())
            .limit(10)
            .forEach(entry -> {
                Player player = players.stream()
                    .filter(p -> p.getId() == entry.getKey())
                    .findFirst()
                    .orElse(null);
                if (player != null) {
                    report.append(String.format("%-15s (%s): %.2f%%\n", 
                        player.getName(), player.getPosition(), entry.getValue()));
                }
            });
        return report.toString();
    }
}

数据模拟和主程序

import java.util.*;
public class AerialDuelStatisticsSystem {
    public static void main(String[] args) {
        AerialDuelStatisticsService service = new AerialDuelStatisticsService();
        // 模拟球员数据
        List<Player> players = generatePlayers();
        players.forEach(service::addPlayer);
        // 分配球队
        Map<String, List<String>> teamPlayers = new HashMap<>();
        teamPlayers.put("皇家马德里", Arrays.asList("C罗", "本泽马", "贝尔", "拉莫斯", "马塞洛"));
        teamPlayers.put("巴塞罗那", Arrays.asList("梅西", "苏亚雷斯", "格列兹曼", "皮克", "阿尔巴"));
        teamPlayers.put("利物浦", Arrays.asList("萨拉赫", "马内", "菲尔米诺", "范戴克", "罗伯逊"));
        teamPlayers.put("曼城", Arrays.asList("德布劳内", "热苏斯", "斯特林", "迪亚斯", "坎塞洛"));
        // 分配球员到球队
        for (Map.Entry<String, List<String>> entry : teamPlayers.entrySet()) {
            String team = entry.getKey();
            for (String playerName : entry.getValue()) {
                Optional<Player> player = players.stream()
                    .filter(p -> p.getName().equals(playerName))
                    .findFirst();
                player.ifPresent(p -> service.assignPlayerToTeam(p.getId(), team));
            }
        }
        // 生成模拟争顶事件
        Random random = new Random(2024);
        List<AerialDuel> duels = generateDuelData(players, random);
        duels.forEach(service::addDuel);
        // 输出统计报告
        String report = service.generateDetailedReport();
        System.out.println(report);
        // 额外展示:特定球员的详细统计
        System.out.println("\n" + "=".repeat(60));
        System.out.println("个人详细统计示例");
        System.out.println("=".repeat(60));
        Player samplePlayer = players.get(0); // C罗
        double successRate = service.calculatePlayerSuccessRate(samplePlayer.getId());
        System.out.printf("%s的争顶成功率为:%.2f%%%n", 
            samplePlayer.getName(), successRate);
        // 统计各球员的争顶次数和成功数
        System.out.println("\n【球员争顶统计汇总】");
        for (Player player : players) {
            double rate = service.calculatePlayerSuccessRate(player.getId());
            System.out.printf("%-15s 身高: %.2fm  位置: %-6s 争顶成功率: %.2f%%%n",
                player.getName(), player.getHeight(), player.getPosition(), rate);
        }
    }
    // 生成球员数据
    private static List<Player> generatePlayers() {
        List<Player> players = new ArrayList<>();
        // 皇家马德里
        players.add(new Player(1, "C罗", "前锋", 1.87));
        players.add(new Player(2, "本泽马", "前锋", 1.85));
        players.add(new Player(3, "贝尔", "边锋", 1.83));
        players.add(new Player(4, "拉莫斯", "后卫", 1.84));
        players.add(new Player(5, "马塞洛", "后卫", 1.75));
        // 巴塞罗那
        players.add(new Player(6, "梅西", "前锋", 1.70));
        players.add(new Player(7, "苏亚雷斯", "前锋", 1.82));
        players.add(new Player(8, "格列兹曼", "前锋", 1.76));
        players.add(new Player(9, "皮克", "后卫", 1.94));
        players.add(new Player(10, "阿尔巴", "后卫", 1.68));
        // 利物浦
        players.add(new Player(11, "萨拉赫", "边锋", 1.75));
        players.add(new Player(12, "马内", "边锋", 1.75));
        players.add(new Player(13, "菲尔米诺", "前锋", 1.81));
        players.add(new Player(14, "范戴克", "后卫", 1.93));
        players.add(new Player(15, "罗伯逊", "后卫", 1.78));
        // 曼城
        players.add(new Player(16, "德布劳内", "中场", 1.81));
        players.add(new Player(17, "热苏斯", "前锋", 1.75));
        players.add(new Player(18, "斯特林", "边锋", 1.70));
        players.add(new Player(19, "迪亚斯", "后卫", 1.87));
        players.add(new Player(20, "坎塞洛", "后卫", 1.82));
        return players;
    }
    // 生成模拟争顶事件
    private static List<AerialDuel> generateDuelData(List<Player> players, Random random) {
        List<AerialDuel> duels = new ArrayList<>();
        Map<Integer, String> teamMap = new HashMap<>();
        // 球队分配
        teamMap.put(1, "皇家马德里"); teamMap.put(2, "皇家马德里");
        teamMap.put(3, "皇家马德里"); teamMap.put(4, "皇家马德里");
        teamMap.put(5, "皇家马德里");
        teamMap.put(6, "巴塞罗那"); teamMap.put(7, "巴塞罗那");
        teamMap.put(8, "巴塞罗那"); teamMap.put(9, "巴塞罗那");
        teamMap.put(10, "巴塞罗那");
        teamMap.put(11, "利物浦"); teamMap.put(12, "利物浦");
        teamMap.put(13, "利物浦"); teamMap.put(14, "利物浦");
        teamMap.put(15, "利物浦");
        teamMap.put(16, "曼城"); teamMap.put(17, "曼城");
        teamMap.put(18, "曼城"); teamMap.put(19, "曼城");
        teamMap.put(20, "曼城");
        // 生成1000次争顶事件
        for (int i = 0; i < 1000; i++) {
            int attackerId = random.nextInt(20) + 1;
            int defenderId;
            // 确保防守球员来自不同球队
            do {
                defenderId = random.nextInt(20) + 1;
            } while (teamMap.get(defenderId).equals(teamMap.get(attackerId)));
            Player attacker = players.stream()
                .filter(p -> p.getId() == attackerId)
                .findFirst()
                .orElse(null);
            Player defender = players.stream()
                .filter(p -> p.getId() == defenderId)
                .findFirst()
                .orElse(null);
            // 基于身高差和随机因素计算成功率
            double baseRate = 0.5;
            if (attacker != null && defender != null) {
                double heightAdvantage = (attacker.getHeight() - defender.getHeight()) * 0.2;
                baseRate += heightAdvantage;
            }
            boolean isWon = random.nextDouble() < baseRate;
            String timestamp = String.format("%02d:%02d", 
                random.nextInt(90) + 1, random.nextInt(60));
            duels.add(new AerialDuel(attackerId, defenderId, isWon, timestamp, i));
        }
        return duels;
    }
}

高级分析扩展(可选)

// 高级统计分析
class AdvancedAerialAnalysis {
    // 趋势分析
    public Map<String, Double> analyzeTrend(List<AerialDuel> duels, Player player) {
        Map<String, Double> trends = new HashMap<>();
        // 按时间段统计
        // 按对手强度统计
        return trends;
    }
    // 预测模型(简单线性回归)
    public double predictSuccessRate(double height) {
        // 基于历史数据的简单预测
        return 0.45 + (height - 1.80) * 0.3;
    }
}

这个Java案例提供了完整的高球传中争顶成功率统计功能,包括:

  1. 多维度统计:球队、位置、身高分组
  2. 个人排名:TOP 10球员
  3. 详细的报告生成
  4. 面向对象设计:清晰的数据模型
  5. 模拟数据:包含真实球员数据进行演示

运行后可以生成详细的统计报告,帮助分析球员和球队的争顶能力。

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