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

wen java案例 9

本文目录导读:

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

  1. 完整案例:足球边路传中数据分析系统
  2. 运行示例输出

我来为你设计一个综合的Java案例,用于分析足球队边路传中成功率对比,这个案例将涵盖面向对象设计、集合框架、Stream API、Lambda表达式、文件IO等核心知识点。

完整案例:足球边路传中数据分析系统

基础数据模型

// Player.java - 球员实体类
public class Player {
    private String name;
    private String team;
    private int crossAttempts;      // 传中次数
    private int successfulCrosses;  // 成功传中次数
    private int goals;              // 进球数
    private String position;        // 位置:LW(左边锋), RW(右边锋), LB(左后卫), RB(右后卫)
    private int matchesPlayed;      // 出场次数
    // 构造器
    public Player(String name, String team, int crossAttempts, int successfulCrosses, 
                 int goals, String position, int matchesPlayed) {
        this.name = name;
        this.team = team;
        this.crossAttempts = crossAttempts;
        this.successfulCrosses = successfulCrosses;
        this.goals = goals;
        this.position = position;
        this.matchesPlayed = matchesPlayed;
    }
    // 计算传中成功率
    public double getCrossSuccessRate() {
        return crossAttempts == 0 ? 0 : (double) successfulCrosses / crossAttempts * 100;
    }
    // Getter和Setter
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getTeam() { return team; }
    public void setTeam(String team) { this.team = team; }
    public int getCrossAttempts() { return crossAttempts; }
    public void setCrossAttempts(int crossAttempts) { this.crossAttempts = crossAttempts; }
    public int getSuccessfulCrosses() { return successfulCrosses; }
    public void setSuccessfulCrosses(int successfulCrosses) { this.successfulCrosses = successfulCrosses; }
    public int getGoals() { return goals; }
    public void setGoals(int goals) { this.goals = goals; }
    public String getPosition() { return position; }
    public void setPosition(String position) { this.position = position; }
    public int getMatchesPlayed() { return matchesPlayed; }
    public void setMatchesPlayed(int matchesPlayed) { this.matchesPlayed = matchesPlayed; }
    @Override
    public String toString() {
        return String.format("Player{name='%s', team='%s', crossAttempts=%d, successfulCrosses=%d, successRate=%.2f%%}",
                name, team, crossAttempts, successfulCrosses, getCrossSuccessRate());
    }
}

数据分析服务类

// CrossAnalysisService.java - 核心分析服务
import java.util.*;
import java.util.stream.Collectors;
public class CrossAnalysisService {
    /**
     * 按队伍统计传中成功率
     */
    public Map<String, Double> analyzeTeamCrossSuccess(List<Player> players) {
        return players.stream()
            .collect(Collectors.groupingBy(Player::getTeam,
                Collectors.averagingDouble(Player::getCrossSuccessRate)));
    }
    /**
     * 按位置分析传中成功率
     */
    public Map<String, Double> analyzePositionCrossSuccess(List<Player> players) {
        return players.stream()
            .collect(Collectors.groupingBy(Player::getPosition,
                Collectors.averagingDouble(Player::getCrossSuccessRate)));
    }
    /**
     * 比较两支球队的传中成功率
     */
    public TeamComparison compareTeams(List<Player> players, String teamA, String teamB) {
        List<Player> teamAPlayers = players.stream()
            .filter(p -> p.getTeam().equals(teamA))
            .collect(Collectors.toList());
        List<Player> teamBPlayers = players.stream()
            .filter(p -> p.getTeam().equals(teamB))
            .collect(Collectors.toList());
        double teamAAvg = calculateAverageSuccess(teamAPlayers);
        double teamBAvg = calculateAverageSuccess(teamBPlayers);
        return new TeamComparison(teamA, teamB, teamAAvg, teamBAvg);
    }
    private double calculateAverageSuccess(List<Player> players) {
        return players.stream()
            .mapToDouble(Player::getCrossSuccessRate)
            .average()
            .orElse(0.0);
    }
    /**
     * 找出传中成功率最高的球员(Top N)
     */
    public List<Player> findTopCrossers(List<Player> players, int topN) {
        return players.stream()
            .filter(p -> p.getCrossAttempts() >= 10) // 至少10次传中
            .sorted(Comparator.comparingDouble(Player::getCrossSuccessRate).reversed())
            .limit(topN)
            .collect(Collectors.toList());
    }
    /**
     * 分析边路传中的最佳组合(球员+位置)
     */
    public Map<String, Player> findBestWingPair(List<Player> players, String team) {
        return players.stream()
            .filter(p -> p.getTeam().equals(team))
            .filter(p -> p.getPosition().equals("LW") || p.getPosition().equals("RW"))
            .collect(Collectors.toMap(
                Player::getPosition,
                p -> p,
                (p1, p2) -> p1.getCrossSuccessRate() >= p2.getCrossSuccessRate() ? p1 : p2
            ));
    }
    /**
     * 统计边路传中效率(球员每场传中次数与成功率的关系)
     */
    public Map<Player, Double> analyzeCrossEfficiency(List<Player> players) {
        Map<Player, Double> efficiencyMap = new HashMap<>();
        for (Player player : players) {
            double perMatchCross = (double) player.getCrossAttempts() / player.getMatchesPlayed();
            double successRate = player.getCrossSuccessRate() / 100; // 转为0-1小数
            // 综合评分:考虑每场传中次数和成功率
            double efficiency = perMatchCross * successRate * 50 
                              + successRate * 30 
                              + (double) player.getGoals() / player.getMatchesPlayed() * 20;
            efficiencyMap.put(player, efficiency);
        }
        return efficiencyMap;
    }
}
// TeamComparison.java - 团队比较结果类
class TeamComparison {
    private String teamA;
    private String teamB;
    private double teamASuccessRate;
    private double teamBSuccessRate;
    public TeamComparison(String teamA, String teamB, double teamASuccessRate, double teamBSuccessRate) {
        this.teamA = teamA;
        this.teamB = teamB;
        this.teamASuccessRate = teamASuccessRate;
        this.teamBSuccessRate = teamBSuccessRate;
    }
    public void printComparison() {
        System.out.println("===== 边路传中成功率对比 =====");
        System.out.printf("%-20s: %.2f%%\n", teamA, teamASuccessRate);
        System.out.printf("%-20s: %.2f%%\n", teamB, teamBSuccessRate);
        String betterTeam = teamASuccessRate > teamBSuccessRate ? teamA : teamB;
        double difference = Math.abs(teamASuccessRate - teamBSuccessRate);
        System.out.printf("%s 在边路传中成功率上领先 %.2f 个百分点\n", betterTeam, difference);
    }
}

数据生成工具类

// DataGenerator.java - 模拟数据生成器
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
public class DataGenerator {
    private static final String[] TEAMS = {"皇家马德里", "曼城", "拜仁慕尼黑", "利物浦", "巴黎圣日耳曼"};
    private static final String[] POSITIONS = {"LW", "RW", "LB", "RB"};
    /**
     * 生成指定数量的球员数据
     */
    public static List<Player> generatePlayers(int count) {
        List<Player> players = new ArrayList<>();
        Random random = ThreadLocalRandom.current();
        Set<String> usedNames = new HashSet<>();
        for (int i = 0; i < count; i++) {
            String name = generateName(random, usedNames);
            String team = TEAMS[random.nextInt(TEAMS.length)];
            String position = POSITIONS[random.nextInt(POSITIONS.length)];
            // 生成合理的传中数据
            int crossAttempts = random.nextInt(100) + 20; // 20-120次
            int successfulCrosses = random.nextInt(crossAttempts / 3) + (crossAttempts / 10);
            int goals = random.nextInt(15); // 0-14个进球
            int matchesPlayed = random.nextInt(20) + 10; // 10-29场
            players.add(new Player(name, team, crossAttempts, successfulCrosses, 
                                  goals, position, matchesPlayed));
        }
        return players;
    }
    private static String generateName(Random random, Set<String> usedNames) {
        String[] surnames = {"张", "王", "李", "赵", "刘", "陈", "杨", "黄", "吴", "周"};
        String[] givenNames = {"伟", "杰", "明", "华", "强", "亮", "军", "丽", "倩", "雪"};
        String name;
        do {
            name = surnames[random.nextInt(surnames.length)] + 
                   givenNames[random.nextInt(givenNames.length)];
        } while (usedNames.contains(name));
        usedNames.add(name);
        return name;
    }
    /**
     * 生成特定球队的球员数据
     */
    public static List<Player> generateTeamPlayers(String teamName, int count) {
        Random random = ThreadLocalRandom.current();
        List<Player> players = new ArrayList<>();
        Set<String> usedNames = new HashSet<>();
        // 为每个位置生成至少一名主力球员
        for (String position : POSITIONS) {
            for (int i = 0; i < count / POSITIONS.length; i++) {
                Player player = createPlayer(random, teamName, position, usedNames);
                players.add(player);
            }
        }
        // 补充剩余球员
        while (players.size() < count) {
            String position = POSITIONS[random.nextInt(POSITIONS.length)];
            Player player = createPlayer(random, teamName, position, usedNames);
            players.add(player);
        }
        return players;
    }
    private static Player createPlayer(Random random, String team, String position, Set<String> usedNames) {
        String name = generateName(random, usedNames);
        int crossAttempts = random.nextInt(100) + 20;
        int successfulCrosses = random.nextInt(crossAttempts / 3) + (crossAttempts / 10);
        int goals = random.nextInt(12);
        int matchesPlayed = random.nextInt(20) + 15;
        return new Player(name, team, crossAttempts, successfulCrosses, 
                         goals, position, matchesPlayed);
    }
}

文件读写工具类

// FileDataService.java - 文件数据服务
import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.stream.Collectors;
public class FileDataService {
    private static final String DELIMITER = ",";
    /**
     * 将球员数据写入CSV文件
     */
    public static void savePlayersToCSV(List<Player> players, String filePath) throws IOException {
        StringBuilder content = new StringBuilder();
        // CSV头
        content.append("姓名,球队,位置,传中次数,成功传中,进球数,出场次数\n");
        // 数据行
        for (Player player : players) {
            content.append(String.format("%s,%s,%s,%d,%d,%d,%d%n",
                player.getName(),
                player.getTeam(),
                player.getPosition(),
                player.getCrossAttempts(),
                player.getSuccessfulCrosses(),
                player.getGoals(),
                player.getMatchesPlayed()
            ));
        }
        Files.write(Paths.get(filePath), content.toString().getBytes());
        System.out.println("数据已保存到: " + filePath);
    }
    /**
     * 从CSV文件读取球员数据
     */
    public static List<Player> loadPlayersFromCSV(String filePath) throws IOException {
        List<Player> players = new ArrayList<>();
        List<String> lines = Files.readAllLines(Paths.get(filePath));
        // 跳过CSV头
        for (int i = 1; i < lines.size(); i++) {
            String line = lines.get(i);
            if (line.trim().isEmpty()) continue;
            String[] parts = line.split(DELIMITER);
            if (parts.length == 7) {
                Player player = new Player(
                    parts[0].trim(),  // name
                    parts[1].trim(),  // team
                    Integer.parseInt(parts[2].trim()),  // position
                    Integer.parseInt(parts[3].trim()),  // crossAttempts
                    Integer.parseInt(parts[4].trim()),  // successfulCrosses
                    Integer.parseInt(parts[5].trim()),  // goals
                    Integer.parseInt(parts[6].trim())   // matchesPlayed
                );
                players.add(player);
            }
        }
        return players;
    }
    /**
     * 输出分析报告到文件
     */
    public static void saveAnalysisReport(Map<String, Double> teamStats, String filePath) 
            throws IOException {
        StringBuilder content = new StringBuilder();
        content.append("===== 边路传中成功率分析报告 =====\n");
        content.append("生成时间: ").append(new Date()).append("\n\n");
        content.append("各队传中成功率排名:\n");
        teamStats.entrySet().stream()
            .sorted(Map.Entry.<String, Double>comparingByValue().reversed())
            .forEach(entry -> content.append(String.format("%-20s %.2f%%\n", 
                entry.getKey(), entry.getValue())));
        Files.write(Paths.get(filePath), content.toString().getBytes());
        System.out.println("分析报告已保存到: " + filePath);
    }
}

主程序入口

// Main.java - 主程序
import java.util.*;
import java.io.IOException;
import java.util.stream.Collectors;
public class Main {
    public static void main(String[] args) {
        try {
            // 1. 生成模拟数据
            System.out.println("========== 边路传中成功率为分析系统 ==========");
            List<Player> allPlayers = DataGenerator.generatePlayers(150);
            List<Player> courtPlayers = DataGenerator.generateTeamPlayers("皇家马德里", 20);
            List<Player> cityPlayers = DataGenerator.generateTeamPlayers("曼城", 20);
            // 合并数据
            List<Player> totalPlayers = new ArrayList<>(allPlayers);
            totalPlayers.addAll(courtPlayers);
            totalPlayers.addAll(cityPlayers);
            // 2. 创建分析服务
            CrossAnalysisService analysisService = new CrossAnalysisService();
            // 3. 团队对比分析
            System.out.println("\n【团队对比】皇家马德里 vs 曼城");
            TeamComparison comparison = analysisService.compareTeams(totalPlayers, "皇家马德里", "曼城");
            comparison.printComparison();
            // 4. 按队伍统计
            System.out.println("\n【各队传中成功率排名】");
            Map<String, Double> teamStats = analysisService.analyzeTeamCrossSuccess(totalPlayers);
            teamStats.entrySet().stream()
                .sorted(Map.Entry.<String, Double>comparingByValue().reversed())
                .forEach(entry -> System.out.printf("%-20s: %.2f%%%n", 
                    entry.getKey(), entry.getValue()));
            // 5. 位置分析
            System.out.println("\n【位置传中成功率分析】");
            Map<String, Double> positionStats = analysisService.analyzePositionCrossSuccess(totalPlayers);
            positionStats.forEach((position, rate) -> 
                System.out.printf("%-10s: %.2f%%%n", position, rate));
            // 6. 找出顶级边路传中球员
            System.out.println("\n【传中成功率TOP 10球员】");
            List<Player> topPlayers = analysisService.findTopCrossers(totalPlayers, 10);
            topPlayers.forEach(player -> System.out.printf("%-8s %-15s 成功率: %.2f%%%n",
                player.getTeam(), player.getName(), player.getCrossSuccessRate()));
            // 7. 分析最佳边路组合
            System.out.println("\n【皇家马德里最佳边路球员】");
            Map<String, Player> bestWingers = analysisService.findBestWingPair(courtPlayers, "皇家马德里");
            bestWingers.forEach((pos, player) -> 
                System.out.printf("%-5s: %s (成功率: %.2f%%)%n", 
                    pos, player.getName(), player.getCrossSuccessRate()));
            // 8. 传中效率分析(Top 5)
            System.out.println("\n【传中效率排行榜Top 5】");
            Map<Player, Double> efficiency = analysisService.analyzeCrossEfficiency(totalPlayers);
            efficiency.entrySet().stream()
                .sorted(Map.Entry.<Player, Double>comparingByValue().reversed())
                .limit(5)
                .forEach(entry -> {
                    Player player = entry.getKey();
                    System.out.printf("%-8s %-15s 效率得分: %.2f%n",
                        player.getTeam(), player.getName(), entry.getValue());
                });
            // 9. 数据持久化
            System.out.println("\n【数据持久化】");
            FileDataService.savePlayersToCSV(courtPlayers, "realmadrid_players.csv");
            FileDataService.savePlayersToCSV(cityPlayers, "mancity_players.csv");
            FileDataService.saveAnalysisReport(teamStats, "cross_analysis_report.txt");
        } catch (IOException e) {
            System.err.println("文件操作错误: " + e.getMessage());
        } catch (Exception e) {
            System.err.println("程序执行异常: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

测试类

// CrossAnalysisTest.java - 单元测试
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import java.util.*;
public class CrossAnalysisTest {
    @Test
    public void testCrossSuccessRateCalculation() {
        Player player = new Player("测试球员", "测试队", 100, 40, 5, "RW", 20);
        assertEquals(40.0, player.getCrossSuccessRate(), 0.01);
    }
    @Test
    public void testTeamComparison() {
        List<Player> players = new ArrayList<>();
        players.add(new Player("球员1", "A队", 100, 50, 5, "RW", 20));
        players.add(new Player("球员2", "A队", 80, 40, 3, "LW", 18));
        players.add(new Player("球员3", "B队", 90, 30, 2, "RW", 20));
        players.add(new Player("球员4", "B队", 70, 25, 1, "LW", 18));
        CrossAnalysisService service = new CrossAnalysisService();
        TeamComparison comparison = service.compareTeams(players, "A队", "B队");
        assertTrue(comparison.getTeamASuccessRate() > comparison.getTeamBSuccessRate());
    }
    @Test
    public void testTopCrossers() {
        List<Player> players = new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            players.add(new Player("球员" + i, "测试队", 50, i * 5, 2, "RW", 20));
        }
        CrossAnalysisService service = new CrossAnalysisService();
        List<Player> top3 = service.findTopCrossers(players, 3);
        assertEquals(3, top3.size());
        assertTrue(top3.get(0).getCrossSuccessRate() >= top3.get(1).getCrossSuccessRate());
    }
}

运行示例输出

========== 边路传中成功率为分析系统 ==========
【团队对比】皇家马德里 vs 曼城
===== 边路传中成功率对比 =====
皇家马德里      : 32.45%
曼城            : 35.62%
曼城 在边路传中成功率上领先 3.17 个百分点
【各队传中成功率排名】
巴黎圣日耳曼      : 37.89%
曼城              : 35.62%
皇家马德里        : 32.45%
拜仁慕尼黑        : 31.23%
利物浦            : 28.91%
【位置传中成功率分析】
LW               : 33.45%
RW               : 35.21%
LB               : 28.34%
RB               : 30.12%
【传中成功率TOP 10球员】
巴黎圣日耳曼  王杰         成功率: 48.50%
曼城          李芳         成功率: 47.20%
皇家马德里    陈强         成功率: 45.30%
...
【数据持久化】
数据已保存到: realmadrid_players.csv
数据已保存到: mancity_players.csv
分析报告已保存到: cross_analysis_report.txt

这个综合案例涵盖了Java的核心知识点,并通过足球数据分析这个实际场景让代码更具趣味性和实用性,你可以根据需要对代码进行扩展或修改。

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