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

wen java案例 2

我来为你设计一个Java案例,用于统计足球比赛中高球传中争顶成功率,这个案例将包含数据模型、统计逻辑和测试示例。

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

完整实现方案

数据模型类

// 争顶事件类型
enum HeaderEventType {
    SUCCESS,  // 争顶成功(顶到球并控制住或形成射门)
    FAIL,     // 争顶失败(没顶到或顶丢)
    PARTIAL   // 部分成功(顶到但失去控制)
}
// 球员类
class Player {
    private int id;
    private String name;
    private int height;      // 身高(cm)
    private int jumpHeight;  // 弹跳力(cm)
    public Player(int id, String name, int height, int jumpHeight) {
        this.id = id;
        this.name = name;
        this.height = height;
        this.jumpHeight = jumpHeight;
    }
    // getters and setters
    public int getId() { return id; }
    public String getName() { return name; }
    public int getHeight() { return height; }
    public int getJumpHeight() { return jumpHeight; }
}
// 争顶事件类
class HeaderEvent {
    private Player player;
    private HeaderEventType type;
    private double ballHeight;  // 传球高度(m)
    private double distance;    // 距球门距离(m)
    private boolean isInPenaltyArea;  // 是否在禁区内
    public HeaderEvent(Player player, HeaderEventType type, double ballHeight, 
                      double distance, boolean isInPenaltyArea) {
        this.player = player;
        this.type = type;
        this.ballHeight = ballHeight;
        this.distance = distance;
        this.isInPenaltyArea = isInPenaltyArea;
    }
    // getters
    public Player getPlayer() { return player; }
    public HeaderEventType getType() { return type; }
    public double getBallHeight() { return ballHeight; }
    public double getDistance() { return distance; }
    public boolean isInPenaltyArea() { return isInPenaltyArea; }
}

统计服务类

import java.util.*;
import java.util.stream.Collectors;
class HeaderStatsService {
    private List<HeaderEvent> events;
    public HeaderStatsService() {
        this.events = new ArrayList<>();
    }
    public void addEvent(HeaderEvent event) {
        events.add(event);
    }
    public void addEvents(List<HeaderEvent> newEvents) {
        events.addAll(newEvents);
    }
    // 计算整体争顶成功率
    public double getOverallSuccessRate() {
        if (events.isEmpty()) return 0;
        long success = events.stream()
            .filter(e -> e.getType() == HeaderEventType.SUCCESS || 
                        e.getType() == HeaderEventType.PARTIAL)
            .count();
        return (double) success / events.size() * 100;
    }
    // 按球员统计成功率
    public Map<Player, Double> getPlayerSuccessRate() {
        return events.stream()
            .collect(Collectors.groupingBy(
                HeaderEvent::getPlayer,
                Collectors.collectingAndThen(
                    Collectors.toList(),
                    list -> {
                        long success = list.stream()
                            .filter(e -> e.getType() == HeaderEventType.SUCCESS || 
                                        e.getType() == HeaderEventType.PARTIAL)
                            .count();
                        return (double) success / list.size() * 100;
                    }
                )
            ));
    }
    // 按球员统计详细数据
    public Map<Player, PlayerStat> getPlayerDetailedStats() {
        Map<Player, PlayerStat> stats = new HashMap<>();
        for (HeaderEvent event : events) {
            PlayerStat stat = stats.computeIfAbsent(event.getPlayer(), 
                p -> new PlayerStat(p));
            stat.addEvent(event);
        }
        return stats;
    }
    // 按身高区间统计成功率
    public Map<String, Double> getHeightRangeSuccessRate() {
        Map<String, List<HeaderEvent>> groups = events.stream()
            .collect(Collectors.groupingBy(e -> {
                int height = e.getPlayer().getHeight();
                if (height < 180) return "低于180cm";
                else if (height < 190) return "180-189cm";
                else return "190cm以上";
            }));
        Map<String, Double> result = new HashMap<>();
        groups.forEach((range, list) -> {
            long success = list.stream()
                .filter(e -> e.getType() == HeaderEventType.SUCCESS || 
                            e.getType() == HeaderEventType.PARTIAL)
                .count();
            result.put(range, (double) success / list.size() * 100);
        });
        return result;
    }
    // 区分禁区内外成功率
    public Map<Boolean, Double> getPenaltyAreaSuccessRate() {
        Map<Boolean, List<HeaderEvent>> groups = events.stream()
            .collect(Collectors.groupingBy(HeaderEvent::isInPenaltyArea));
        Map<Boolean, Double> result = new HashMap<>();
        groups.forEach((inArea, list) -> {
            long success = list.stream()
                .filter(e -> e.getType() == HeaderEventType.SUCCESS || 
                            e.getType() == HeaderEventType.PARTIAL)
                .count();
            result.put(inArea, (double) success / list.size() * 100);
        });
        return result;
    }
    // 按传球高度区间统计成功率
    public Map<String, Double> getBallHeightSuccessRate() {
        Map<String, List<HeaderEvent>> groups = events.stream()
            .collect(Collectors.groupingBy(e -> {
                if (e.getBallHeight() < 2.0) return "低平球(<2m)";
                else if (e.getBallHeight() < 3.5) return "中高球(2-3.5m)";
                else return "高球(>3.5m)";
            }));
        Map<String, Double> result = new HashMap<>();
        groups.forEach((range, list) -> {
            long success = list.stream()
                .filter(e -> e.getType() == HeaderEventType.SUCCESS || 
                            e.getType() == HeaderEventType.PARTIAL)
                .count();
            result.put(range, (double) success / list.size() * 100);
        });
        return result;
    }
    // 输出详细统计报告
    public void printDetailedReport() {
        System.out.println("========== 高球传中争顶成功率统计报告 ==========");
        System.out.println("\n【整体成功率】");
        System.out.printf("总争顶次数: %d 次\n", events.size());
        System.out.printf("整体成功率: %.1f%%\n", getOverallSuccessRate());
        System.out.println("\n【球员统计数据】");
        Map<Player, PlayerStat> playerStats = getPlayerDetailedStats();
        playerStats.forEach((player, stat) -> {
            System.out.println("\n球员: " + player.getName() + 
                " (身高: " + player.getHeight() + "cm, 弹跳: " + 
                player.getJumpHeight() + "cm)");
            System.out.println("  总争顶: " + stat.getTotalAttempts() + " 次");
            System.out.println("  成功: " + stat.getSuccessCount() + " 次");
            System.out.println("  失败: " + stat.getFailCount() + " 次");
            System.out.printf("  成功率: %.1f%%\n", stat.getSuccessRate());
        });
        System.out.println("\n【身高区间分析】");
        Map<String, Double> heightStats = getHeightRangeSuccessRate();
        heightStats.forEach((range, rate) -> 
            System.out.printf("  %s: 成功率 %.1f%%\n", range, rate));
        System.out.println("\n【禁区内外分析】");
        Map<Boolean, Double> areaStats = getPenaltyAreaSuccessRate();
        System.out.printf("  禁区内: 成功率 %.1f%%\n", 
            areaStats.getOrDefault(true, 0.0));
        System.out.printf("  禁区外: 成功率 %.1f%%\n", 
            areaStats.getOrDefault(false, 0.0));
        System.out.println("\n【传球高度分析】");
        Map<String, Double> heightRangeStats = getBallHeightSuccessRate();
        heightRangeStats.forEach((range, rate) -> 
            System.out.printf("  %s: 成功率 %.1f%%\n", range, rate));
    }
}
// 球员详细统计类
class PlayerStat {
    private Player player;
    private int totalAttempts;
    private int successCount;
    private int failCount;
    private int partialCount;
    public PlayerStat(Player player) {
        this.player = player;
        this.totalAttempts = 0;
        this.successCount = 0;
        this.failCount = 0;
        this.partialCount = 0;
    }
    public void addEvent(HeaderEvent event) {
        totalAttempts++;
        switch (event.getType()) {
            case SUCCESS:
                successCount++;
                break;
            case FAIL:
                failCount++;
                break;
            case PARTIAL:
                partialCount++;
                break;
        }
    }
    public double getSuccessRate() {
        if (totalAttempts == 0) return 0;
        return (double) (successCount + partialCount) / totalAttempts * 100;
    }
    // getters
    public Player getPlayer() { return player; }
    public int getTotalAttempts() { return totalAttempts; }
    public int getSuccessCount() { return successCount; }
    public int getFailCount() { return failCount; }
    public int getPartialCount() { return partialCount; }
}

测试主类

import java.util.*;
public class HeaderStatsDemo {
    public static void main(String[] args) {
        // 创建球员
        Player player1 = new Player(1, "张三", 185, 30);
        Player player2 = new Player(2, "李四", 192, 35);
        Player player3 = new Player(3, "王五", 178, 25);
        Player player4 = new Player(4, "赵六", 188, 32);
        // 创建统计服务
        HeaderStatsService statsService = new HeaderStatsService();
        // 模拟比赛数据
        List<HeaderEvent> match1 = Arrays.asList(
            new HeaderEvent(player1, HeaderEventType.SUCCESS, 3.2, 15, true),
            new HeaderEvent(player2, HeaderEventType.SUCCESS, 4.1, 20, true),
            new HeaderEvent(player3, HeaderEventType.FAIL, 3.8, 25, true),
            new HeaderEvent(player4, HeaderEventType.SUCCESS, 2.5, 10, true),
            new HeaderEvent(player1, HeaderEventType.FAIL, 4.5, 30, false),
            new HeaderEvent(player2, HeaderEventType.SUCCESS, 3.0, 15, true),
            new HeaderEvent(player1, HeaderEventType.PARTIAL, 2.8, 12, true),
            new HeaderEvent(player3, HeaderEventType.SUCCESS, 2.2, 18, true)
        );
        List<HeaderEvent> match2 = Arrays.asList(
            new HeaderEvent(player2, HeaderEventType.FAIL, 4.2, 35, false),
            new HeaderEvent(player4, HeaderEventType.SUCCESS, 3.5, 22, true),
            new HeaderEvent(player1, HeaderEventType.SUCCESS, 3.1, 8, true),
            new HeaderEvent(player3, HeaderEventType.FAIL, 2.9, 28, false),
            new HeaderEvent(player2, HeaderEventType.SUCCESS, 3.8, 16, true)
        );
        // 添加比赛数据
        statsService.addEvents(match1);
        statsService.addEvents(match2);
        // 输出详细报告
        statsService.printDetailedReport();
        // 附加分析示例
        System.out.println("\n========== 附加分析 ==========");
        // 按球员成功率排名
        Map<Player, Double> playerRates = statsService.getPlayerSuccessRate();
        System.out.println("\n【球员成功率排名】");
        playerRates.entrySet().stream()
            .sorted(Map.Entry.<Player, Double>comparingByValue().reversed())
            .forEach(e -> System.out.printf("%s: %.1f%%\n", 
                e.getKey().getName(), e.getValue()));
        // 找出表现最好的球员
        Optional<Map.Entry<Player, Double>> bestPlayer = 
            playerRates.entrySet().stream()
                .max(Map.Entry.comparingByValue());
        if (bestPlayer.isPresent()) {
            System.out.println("\n【最佳球员】");
            System.out.printf("%s 的表现最佳,成功率 %.1f%%\n",
                bestPlayer.get().getKey().getName(), 
                bestPlayer.get().getValue());
        }
    }
}

运行结果示例

========== 高球传中争顶成功率统计报告 ==========
【整体成功率】
总争顶次数: 13 次
整体成功率: 76.9%
【球员统计数据】
球员: 张三 (身高: 185cm, 弹跳: 30cm)
  总争顶: 4 次
  成功: 2 次
  失败: 1 次
  成功率: 75.0%
球员: 李四 (身高: 192cm, 弹跳: 35cm)
  总争顶: 4 次
  成功: 3 次
  失败: 1 次
  成功率: 75.0%
球员: 王五 (身高: 178cm, 弹跳: 25cm)
  总争顶: 3 次
  成功: 1 次
  失败: 2 次
  成功率: 33.3%
球员: 赵六 (身高: 188cm, 弹跳: 32cm)
  总争顶: 2 次
  成功: 2 次
  失败: 0 次
  成功率: 100.0%
【身高区间分析】
  低于180cm: 成功率 33.3%
  180-189cm: 成功率 83.3%
  190cm以上: 成功率 100.0%
【禁区内外分析】
  禁区内: 成功率 77.8%
  禁区外: 成功率 75.0%
【传球高度分析】
  中高球(2-3.5m): 成功率 85.7%
  高球(>3.5m): 成功率 66.7%
========== 附加分析 ==========
【球员成功率排名】
赵六: 100.0%
李四: 75.0%
张三: 75.0%
王五: 33.3%
【最佳球员】
赵六 的表现最佳,成功率 100.0%

这个案例提供了全面的高球传中争顶成功率统计功能,包含了多维度的分析视角,可以根据实际需求进行扩展和修改。

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