java案例统计赛季累计数据对比如何?

wen java案例 2

本文目录导读:

java案例统计赛季累计数据对比如何?

  1. 数据模型设计
  2. 数据对比分析类
  3. 可视化报表生成器
  4. 主程序示例
  5. 高级功能扩展
  6. 使用注意事项

我来为您设计一个Java赛季累计数据对比的案例,包含完整的代码实现和设计思路。

数据模型设计

import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
// 球员赛季数据实体
class PlayerSeasonStats {
    private String playerId;
    private String playerName;
    private String season;  // "2023-2024"
    private int gamesPlayed;
    private int points;
    private int rebounds;
    private int assists;
    private int steals;
    private int blocks;
    private double minutesPerGame;
    private double fieldGoalPercentage;
    // 构造函数、getter/setter省略,使用Lombok或手动生成
    // 计算场均得分
    public double getPointsPerGame() {
        return gamesPlayed == 0 ? 0 : (double) points / gamesPlayed;
    }
    @Override
    public String toString() {
        return String.format("%s %s: %.1f分 %.1f板 %.1f助 %.1f断 %.1f帽 (%.1f分钟/场)",
            playerName, season, getPointsPerGame(), 
            (double) rebounds / gamesPlayed, 
            (double) assists / gamesPlayed,
            (double) steals / gamesPlayed,
            (double) blocks / gamesPlayed,
            minutesPerGame);
    }
}

数据对比分析类

class SeasonStatsComparator {
    // 对比两个赛季数据
    public static Map<String, Object> compareSeasons(
            List<PlayerSeasonStats> season1Data, 
            List<PlayerSeasonStats> season2Data) {
        Map<String, Object> result = new HashMap<>();
        // 1. 整体数据对比
        Map<String, Double> season1Avg = calculateTeamAverages(season1Data);
        Map<String, Double> season2Avg = calculateTeamAverages(season2Data);
        // 2. 球员个人对比
        List<PlayerComparison> playerComparisons = comparePlayers(season1Data, season2Data);
        // 3. 进步最快球员
        List<PlayerComparison> mostImproved = findMostImproved(playerComparisons);
        // 4. 数据统计摘要
        Map<String, Object> summary = createSummary(season1Data, season2Data);
        result.put("season1Avg", season1Avg);
        result.put("season2Avg", season2Avg);
        result.put("playerComparisons", playerComparisons);
        result.put("mostImproved", mostImproved);
        result.put("summary", summary);
        return result;
    }
    // 计算球队平均数据
    private static Map<String, Double> calculateTeamAverages(List<PlayerSeasonStats> stats) {
        Map<String, Double> averages = new HashMap<>();
        if (stats.isEmpty()) return averages;
        double totalPoints = stats.stream().mapToDouble(PlayerSeasonStats::getPointsPerGame).sum();
        double totalRebounds = stats.stream()
            .mapToDouble(s -> (double) s.getRebounds() / s.getGamesPlayed()).sum();
        double totalAssists = stats.stream()
            .mapToDouble(s -> (double) s.getAssists() / s.getGamesPlayed()).sum();
        averages.put("points", round(totalPoints / stats.size()));
        averages.put("rebounds", round(totalRebounds / stats.size()));
        averages.put("assists", round(totalAssists / stats.size()));
        averages.put("gamesPlayed", round(stats.stream().mapToInt(PlayerSeasonStats::getGamesPlayed).average().orElse(0)));
        return averages;
    }
    // 球员对比
    private static List<PlayerComparison> comparePlayers(
            List<PlayerSeasonStats> season1, 
            List<PlayerSeasonStats> season2) {
        Map<String, PlayerSeasonStats> season2Map = season2.stream()
            .collect(Collectors.toMap(PlayerSeasonStats::getPlayerId, p -> p));
        return season1.stream()
            .filter(s1 -> season2Map.containsKey(s1.getPlayerId()))
            .map(s1 -> {
                PlayerSeasonStats s2 = season2Map.get(s1.getPlayerId());
                return createPlayerComparison(s1, s2);
            })
            .sorted(Comparator.comparingDouble(PlayerComparison::getPointsDiff).reversed())
            .collect(Collectors.toList());
    }
    // 创建球员对比对象
    private static PlayerComparison createPlayerComparison(
            PlayerSeasonStats s1, PlayerSeasonStats s2) {
        PlayerComparison pc = new PlayerComparison();
        pc.setPlayerId(s1.getPlayerId());
        pc.setPlayerName(s1.getPlayerName());
        pc.setSeason1Data(s1);
        pc.setSeason2Data(s2);
        // 计算差异
        pc.setPointsDiff(s2.getPointsPerGame() - s1.getPointsPerGame());
        pc.setReboundsDiff((double) s2.getRebounds()/s2.getGamesPlayed() - 
                          (double) s1.getRebounds()/s1.getGamesPlayed());
        pc.setAssistsDiff((double) s2.getAssists()/s2.getGamesPlayed() - 
                         (double) s1.getAssists()/s1.getGamesPlayed());
        return pc;
    }
    // 找出进步最快球员
    private static List<PlayerComparison> findMostImproved(List<PlayerComparison> comparisons) {
        return comparisons.stream()
            .sorted(Comparator.comparingDouble(PlayerComparison::getPointsDiff).reversed())
            .limit(5)
            .collect(Collectors.toList());
    }
    // 创建数据摘要
    private static Map<String, Object> createSummary(
            List<PlayerSeasonStats> season1, 
            List<PlayerSeasonStats> season2) {
        Map<String, Object> summary = new HashMap<>();
        // 总得分对比
        int totalPoints1 = season1.stream().mapToInt(PlayerSeasonStats::getPoints).sum();
        int totalPoints2 = season2.stream().mapToInt(PlayerSeasonStats::getPoints).sum();
        summary.put("totalPoints1", totalPoints1);
        summary.put("totalPoints2", totalPoints2);
        summary.put("pointsChange", totalPoints2 - totalPoints1);
        summary.put("pointsChangePercent", 
            totalPoints1 == 0 ? 0 : ((totalPoints2 - totalPoints1) / (double) totalPoints1 * 100));
        return summary;
    }
    private static double round(double value) {
        return Math.round(value * 100.0) / 100.0;
    }
    // 球员对比数据传输对象
    static class PlayerComparison {
        private String playerId;
        private String playerName;
        private PlayerSeasonStats season1Data;
        private PlayerSeasonStats season2Data;
        private double pointsDiff;
        private double reboundsDiff;
        private double assistsDiff;
        // getters and setters 省略
        @Override
        public String toString() {
            return String.format("%s: 从%.1f分提升到%.1f分 (+%.1f)",
                playerName, 
                season1Data.getPointsPerGame(),
                season2Data.getPointsPerGame(),
                pointsDiff);
        }
    }
}

可视化报表生成器

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
class SeasonReportGenerator {
    // 生成文本报告
    public static String generateTextReport(Map<String, Object> comparison) {
        StringBuilder report = new StringBuilder();
        report.append("========== 赛季数据对比报告 ==========\n\n");
        // 球队平均数据
        report.append("【球队平均数据】\n");
        @SuppressWarnings("unchecked")
        Map<String, Double> season1Avg = (Map<String, Double>) comparison.get("season1Avg");
        @SuppressWarnings("unchecked")
        Map<String, Double> season2Avg = (Map<String, Double>) comparison.get("season2Avg");
        report.append(String.format("赛季1: 得分%.1f 篮板%.1f 助攻%.1f\n",
            season1Avg.get("points"), season1Avg.get("rebounds"), season1Avg.get("assists")));
        report.append(String.format("赛季2: 得分%.1f 篮板%.1f 助攻%.1f\n",
            season2Avg.get("points"), season2Avg.get("rebounds"), season2Avg.get("assists")));
        // 个人对比
        report.append("\n【球员对比】\n");
        @SuppressWarnings("unchecked")
        List<SeasonStatsComparator.PlayerComparison> comparisons = 
            (List<SeasonStatsComparator.PlayerComparison>) comparison.get("playerComparisons");
        comparisons.stream()
            .limit(10)
            .forEach(pc -> report.append(pc.toString()).append("\n"));
        // 进步最快球员
        report.append("\n【进步最快球员 TOP5】\n");
        @SuppressWarnings("unchecked")
        List<SeasonStatsComparator.PlayerComparison> improved = 
            (List<SeasonStatsComparator.PlayerComparison>) comparison.get("mostImproved");
        improved.forEach(pc -> report.append(pc.toString()).append("\n"));
        // 数据摘要
        report.append("\n【数据摘要】\n");
        @SuppressWarnings("unchecked")
        Map<String, Object> summary = (Map<String, Object>) comparison.get("summary");
        report.append(String.format("总得分变化: %d (%.1f%%)\n",
            summary.get("pointsChange"), summary.get("pointsChangePercent")));
        return report.toString();
    }
    // 生成HTML报告
    public static String generateHtmlReport(Map<String, Object> comparison) {
        StringBuilder html = new StringBuilder();
        html.append("<!DOCTYPE html><html><head><title>赛季数据对比</title>");
        html.append("<style>body{font-family:sans-serif;margin:20px}table{border-collapse:collapse}")
            .append("th,td{border:1px solid #ddd;padding:8px;text-align:center}")
            .append("th{background-color:#f2f2f2}</style></head><body>");
        html.append("<h1>赛季数据对比报告</h1>");
        // 球队平均数据表格
        html.append("<h2>球队平均数据</h2><table><tr><th>指标</th><th>赛季1</th><th>赛季2</th><th>变化</th></tr>");
        @SuppressWarnings("unchecked")
        Map<String, Double> s1Avg = (Map<String, Double>) comparison.get("season1Avg");
        @SuppressWarnings("unchecked")
        Map<String, Double> s2Avg = (Map<String, Double>) comparison.get("season2Avg");
        String[] metrics = {"points", "rebounds", "assists"};
        String[] metricNames = {"得分", "篮板", "助攻"};
        for (int i = 0; i < metrics.length; i++) {
            double diff = s2Avg.get(metrics[i]) - s1Avg.get(metrics[i]);
            String color = diff >= 0 ? "green" : "red";
            html.append(String.format(
                "<tr><td>%s</td><td>%.1f</td><td>%.1f</td><td style='color:%s'>%+.1f</td></tr>",
                metricNames[i], s1Avg.get(metrics[i]), s2Avg.get(metrics[i]), color, diff));
        }
        html.append("</table>");
        // 球员对比表格
        html.append("<h2>主要球员对比</h2><table><tr><th>球员</th><th>赛季1得分</th><th>赛季2得分</th><th>变化</th></tr>");
        @SuppressWarnings("unchecked")
        List<SeasonStatsComparator.PlayerComparison> comparisons = 
            (List<SeasonStatsComparator.PlayerComparison>) comparison.get("playerComparisons");
        comparisons.stream().limit(15).forEach(pc -> {
            String color = pc.getPointsDiff() >= 0 ? "green" : "red";
            html.append(String.format(
                "<tr><td>%s</td><td>%.1f</td><td>%.1f</td><td style='color:%s'>%+.1f</td></tr>",
                pc.getPlayerName(), 
                pc.getSeason1Data().getPointsPerGame(),
                pc.getSeason2Data().getPointsPerGame(),
                color, pc.getPointsDiff()));
        });
        html.append("</table>");
        html.append("</body></html>");
        return html.toString();
    }
}

主程序示例

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class SeasonComparisonDemo {
    public static void main(String[] args) {
        // 模拟数据生成
        List<PlayerSeasonStats> season2022 = generateMockData("2022-2023");
        List<PlayerSeasonStats> season2023 = generateMockData("2023-2024");
        // 数据对比
        Map<String, Object> comparison = SeasonStatsComparator.compareSeasons(season2022, season2023);
        // 输出报告
        System.out.println(SeasonReportGenerator.generateTextReport(comparison));
        // 生成HTML报告
        String htmlReport = SeasonReportGenerator.generateHtmlReport(comparison);
        System.out.println("HTML报告已生成,长度:" + htmlReport.length() + " 字符");
    }
    // 模拟数据生成器
    private static List<PlayerSeasonStats> generateMockData(String season) {
        List<PlayerSeasonStats> players = new ArrayList<>();
        // 模拟球员数据 - 实际情况从数据库或文件读取
        String[][] playerNames = {
            {"001", "张三"}, {"002", "李四"}, {"003", "王五"},
            {"004", "赵六"}, {"005", "孙七"}, {"006", "周八"},
            {"007", "吴九"}, {"008", "郑十"}, {"009", "王明"},
            {"010", "李华"}, {"011", "张伟"}, {"012", "刘洋"}
        };
        Random random = new Random();
        for (String[] player : playerNames) {
            PlayerSeasonStats stats = new PlayerSeasonStats();
            stats.setPlayerId(player[0]);
            stats.setPlayerName(player[1]);
            stats.setSeason(season);
            stats.setGamesPlayed(70 + random.nextInt(10));
            stats.setPoints(500 + random.nextInt(800));
            stats.setRebounds(200 + random.nextInt(300));
            stats.setAssists(150 + random.nextInt(250));
            stats.setSteals(30 + random.nextInt(50));
            stats.setBlocks(20 + random.nextInt(40));
            stats.setMinutesPerGame(25 + random.nextDouble() * 10);
            stats.setFieldGoalPercentage(40 + random.nextDouble() * 15);
            players.add(stats);
        }
        return players;
    }
}

高级功能扩展

// 趋势分析
class SeasonTrendAnalyzer {
    // 分析多赛季趋势
    public static Map<String, PlayerTrend> analyzeTrend(
            Map<String, List<PlayerSeasonStats>> seasonData) {
        Map<String, PlayerTrend> trends = new HashMap<>();
        seasonData.forEach((playerId, seasons) -> {
            PlayerTrend trend = new PlayerTrend();
            trend.setPlayerId(playerId);
            trend.setPlayerName(seasons.get(0).getPlayerName());
            // 计算得分趋势
            List<Double> pointsBySeason = seasons.stream()
                .map(PlayerSeasonStats::getPointsPerGame)
                .collect(Collectors.toList());
            trend.setPointsTrend(pointsBySeason);
            // 线性回归预测
            trend.setPredictedPoints(linearRegressionPredict(pointsBySeason));
            trends.put(playerId, trend);
        });
        return trends;
    }
    // 线性回归预测
    private static double linearRegressionPredict(List<Double> data) {
        if (data.size() < 2) return data.get(0);
        int n = data.size();
        double sumX = 0, sumY = 0, sumXY = 0, sumXX = 0;
        for (int i = 0; i < n; i++) {
            sumX += i;
            sumY += data.get(i);
            sumXY += i * data.get(i);
            sumXX += i * i;
        }
        double slope = (n * sumXY - sumX * sumY) / (n * sumXX - sumX * sumX);
        double intercept = (sumY - slope * sumX) / n;
        // 预测下一赛季
        return slope * n + intercept;
    }
    static class PlayerTrend {
        private String playerId;
        private String playerName;
        private List<Double> pointsTrend;
        private double predictedPoints;
        // getters and setters 省略
    }
}

使用注意事项

  1. 数据源处理:实际项目中,数据通常来自数据库或API,需要建立相应的数据访问层。

  2. 性能优化:对于大量数据,考虑使用并行流或数据库聚合查询。

  3. 缓存机制:频繁查询的数据可以使用缓存(如Redis)提高性能。

  4. 数据验证:确保数据的完整性和准确性,处理缺失值。

  5. 报表定制:根据实际需求,可以扩展图表(使用JFreeChart等库)和导出功能。

这个案例涵盖了赛季数据对比的核心功能,您可以根据实际需求进行扩展和优化,需要我详细解释某个部分吗?

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