java案例统计任意球直接得分几次?

wen java案例 2

Java案例:统计任意球直接得分次数

下面通过一个完整的Java案例,演示如何统计足球比赛中任意球直接得分的次数。

java案例统计任意球直接得分几次?

需求分析

在足球比赛中,任意球分为两种得分方式:

  • 直接任意球得分:任意球直接射入球门(不经过其他球员触碰)
  • 间接任意球得分:任意球发出后经其他球员触碰后进球

我们需要从比赛事件记录中,统计出任意球直接得分的次数。

完整代码实现

import java.util.ArrayList;
import java.util.List;
/**
 * 足球比赛事件记录
 */
class MatchEvent {
    private String playerName;      // 球员姓名
    private String teamName;        // 球队名称
    private EventType eventType;    // 事件类型
    private int minute;             // 发生分钟
    public MatchEvent(String playerName, String teamName, EventType eventType, int minute) {
        this.playerName = playerName;
        this.teamName = teamName;
        this.eventType = eventType;
        this.minute = minute;
    }
    public String getPlayerName() { return playerName; }
    public String getTeamName() { return teamName; }
    public EventType getEventType() { return eventType; }
    public int getMinute() { return minute; }
    @Override
    public String toString() {
        return String.format("%d' [%s] %s - %s", minute, teamName, playerName, eventType);
    }
}
/**
 * 事件类型枚举
 */
enum EventType {
    FREE_KICK_GOAL,        // 任意球直接得分
    FREE_KICK_ASSIST,      // 任意球助攻(间接得分)
    FREE_KICK_MISS,        // 任意球射失
    PENALTY_GOAL,          // 点球得分
    NORMAL_GOAL            // 普通进球
}
/**
 * 任意球得分统计器
 */
class FreeKickStatistics {
    private List<MatchEvent> events = new ArrayList<>();
    public void addEvent(MatchEvent event) {
        events.add(event);
    }
    /**
     * 统计任意球直接得分总次数
     */
    public long countDirectFreeKickGoals() {
        return events.stream()
                .filter(e -> e.getEventType() == EventType.FREE_KICK_GOAL)
                .count();
    }
    /**
     * 按球队统计任意球直接得分
     */
    public java.util.Map<String, Long> countByTeam() {
        return events.stream()
                .filter(e -> e.getEventType() == EventType.FREE_KICK_GOAL)
                .collect(java.util.stream.Collectors.groupingBy(
                        MatchEvent::getTeamName,
                        java.util.stream.Collectors.counting()
                ));
    }
    /**
     * 按球员统计任意球直接得分
     */
    public java.util.Map<String, Long> countByPlayer() {
        return events.stream()
                .filter(e -> e.getEventType() == EventType.FREE_KICK_GOAL)
                .collect(java.util.stream.Collectors.groupingBy(
                        MatchEvent::getPlayerName,
                        java.util.stream.Collectors.counting()
                ));
    }
    /**
     * 打印所有任意球直接得分事件
     */
    public void printDirectFreeKickGoals() {
        System.out.println("=== 任意球直接得分事件列表 ===");
        events.stream()
                .filter(e -> e.getEventType() == EventType.FREE_KICK_GOAL)
                .forEach(System.out::println);
    }
}
/**
 * 主程序:演示任意球得分统计
 */
public class FreeKickDemo {
    public static void main(String[] args) {
        FreeKickStatistics stats = new FreeKickStatistics();
        // 模拟一场比赛的事件记录
        stats.addEvent(new MatchEvent("梅西", "阿根廷", EventType.FREE_KICK_GOAL, 23));
        stats.addEvent(new MatchEvent("C罗", "葡萄牙", EventType.FREE_KICK_GOAL, 45));
        stats.addEvent(new MatchEvent("内马尔", "巴西", EventType.FREE_KICK_MISS, 60));
        stats.addEvent(new MatchEvent("梅西", "阿根廷", EventType.FREE_KICK_ASSIST, 72)); // 间接得分不算
        stats.addEvent(new MatchEvent("姆巴佩", "法国", EventType.NORMAL_GOAL, 78));
        stats.addEvent(new MatchEvent("贝克汉姆", "英格兰", EventType.FREE_KICK_GOAL, 85));
        stats.addEvent(new MatchEvent("梅西", "阿根廷", EventType.FREE_KICK_GOAL, 90));
        // 1. 统计任意球直接得分总次数
        long total = stats.countDirectFreeKickGoals();
        System.out.println("任意球直接得分总次数: " + total);
        // 2. 打印详细事件
        System.out.println();
        stats.printDirectFreeKickGoals();
        // 3. 按球队统计
        System.out.println("\n=== 按球队统计 ===");
        stats.countByTeam().forEach((team, count) ->
                System.out.println(team + ": " + count + " 次"));
        // 4. 按球员统计
        System.out.println("\n=== 按球员统计 ===");
        stats.countByPlayer().forEach((player, count) ->
                System.out.println(player + ": " + count + " 次"));
    }
}

运行结果

任意球直接得分总次数: 4
=== 任意球直接得分事件列表 ===
23' [阿根廷] 梅西 - FREE_KICK_GOAL
45' [葡萄牙] C罗 - FREE_KICK_GOAL
85' [英格兰] 贝克汉姆 - FREE_KICK_GOAL
90' [阿根廷] 梅西 - FREE_KICK_GOAL
=== 按球队统计 ===
葡萄牙: 1 次
英格兰: 1 次
阿根廷: 2 次
=== 按球员统计 ===
梅西: 2 次
C罗: 1 次
贝克汉姆: 1 次

核心思路解析

事件建模

将每个比赛事件抽象为 MatchEvent 对象,用 EventType 枚举区分事件类型,FREE_KICK_GOAL 表示任意球直接得分。

关键区分点

// 直接得分 vs 间接得分 vs 射失
FREE_KICK_GOAL,      // ✅ 直接射入 → 计数
FREE_KICK_ASSIST,    // ❌ 助攻(间接) → 不计数
FREE_KICK_MISS       // ❌ 射失 → 不计数

使用Stream过滤统计

events.stream()
      .filter(e -> e.getEventType() == EventType.FREE_KICK_GOAL)
      .count();

分组统计

使用 Collectors.groupingBy 按球队/球员维度分类计数。

扩展建议

如果需要从真实数据源读取,可以考虑:

// 从文本文件读取,每行格式:球员,球队,事件类型,分钟
public void loadFromFile(String path) throws IOException {
    Files.lines(Paths.get(path))
         .map(line -> line.split(","))
         .forEach(arr -> addEvent(new MatchEvent(
             arr[0], arr[1], EventType.valueOf(arr[2]), Integer.parseInt(arr[3])
         )));
}

如果想要统计整个赛季的数据,只需将 FreeKickStatistics 中的 events 不断累积,最后调用统计方法即可,逻辑完全不变。

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