java案例统计扑救次数门将谁更忙?

wen java案例 2

足球比赛门将扑救次数统计案例

下面用一个完整的 Java 案例来统计多名门将的扑救次数,并找出"最忙"的门将。

java案例统计扑救次数门将谁更忙?

需求分析

在一场足球赛事(或多场比赛)中,需要:

  1. 记录每位门将的扑救次数
  2. 统计总扑救数、平均扑救数
  3. 找出扑救次数最多(最忙)的门将
  4. 按扑救次数排序输出

完整代码实现

import java.util.*;
import java.util.stream.Collectors;
/**
 * 门将扑救统计案例
 */
public class GoalkeeperSaveStats {
    // 门将实体类
    static class Goalkeeper {
        private String name;      // 门将姓名
        private String team;      // 所属球队
        private int saveCount;    // 扑救次数
        public Goalkeeper(String name, String team, int saveCount) {
            this.name = name;
            this.team = team;
            this.saveCount = saveCount;
        }
        public String getName() { return name; }
        public String getTeam() { return team; }
        public int getSaveCount() { return saveCount; }
        @Override
        public String toString() {
            return String.format("%-10s(%s) 扑救 %d 次", name, team, saveCount);
        }
    }
    public static void main(String[] args) {
        // 1. 模拟一场比赛中各门将的扑救数据
        List<Goalkeeper> keepers = new ArrayList<>();
        keepers.add(new Goalkeeper("王大雷", "山东泰山", 6));
        keepers.add(new Goalkeeper("颜骏凌", "上海海港", 3));
        keepers.add(new Goalkeeper("刘殿座", "武汉三镇", 8));
        keepers.add(new Goalkeeper("韩佳奇", "北京国安", 5));
        keepers.add(new Goalkeeper("鲍亚雄", "上海申花", 2));
        System.out.println("========== 原始扑救数据 ==========");
        keepers.forEach(System.out::println);
        // 2. 总扑救数
        int totalSaves = keepers.stream()
                .mapToInt(Goalkeeper::getSaveCount)
                .sum();
        System.out.println("\n总扑救次数: " + totalSaves);
        // 3. 平均扑救数
        double avg = keepers.stream()
                .mapToInt(Goalkeeper::getSaveCount)
                .average()
                .orElse(0);
        System.out.printf("平均扑救次数: %.2f%n", avg);
        // 4. 找出"最忙"的门将(扑救次数最多)
        Optional<Goalkeeper> busiest = keepers.stream()
                .max(Comparator.comparingInt(Goalkeeper::getSaveCount));
        busiest.ifPresent(k ->
                System.out.println("\n🏆 最忙的门将: " + k.getName()
                        + " (" + k.getTeam() + ")  扑救 " + k.getSaveCount() + " 次"));
        // 5. 排序输出(从多到少)
        System.out.println("\n========== 扑救排行 ==========");
        List<Goalkeeper> sorted = keepers.stream()
                .sorted(Comparator.comparingInt(Goalkeeper::getSaveCount).reversed())
                .collect(Collectors.toList());
        int rank = 1;
        for (Goalkeeper k : sorted) {
            System.out.println("第" + rank++ + "名: " + k);
        }
        // 6. 筛选出"忙碌"门将(扑救次数 >= 平均值)
        System.out.println("\n========== 高于平均水平的门将 ==========");
        keepers.stream()
                .filter(k -> k.getSaveCount() >= avg)
                .forEach(k -> System.out.println(k.getName() + " - 扑救 " + k.getSaveCount() + " 次"));
        // 7. 按球队分组统计(多队场景)
        System.out.println("\n========== 按球队汇总 ==========");
        Map<String, Integer> teamTotal = keepers.stream()
                .collect(Collectors.groupingBy(
                        Goalkeeper::getTeam,
                        Collectors.summingInt(Goalkeeper::getSaveCount)
                ));
        teamTotal.forEach((team, count) ->
                System.out.println(team + ": " + count + " 次"));
    }
}

运行结果示例

========== 原始扑救数据 ==========
王大雷    (山东泰山) 扑救 6 次
颜骏凌    (上海海港) 扑救 3 次
刘殿座    (武汉三镇) 扑救 8 次
韩佳奇    (北京国安) 扑救 5 次
鲍亚雄    (上海申花) 扑救 2 次
总扑救次数: 24
平均扑救次数: 4.80
🏆 最忙的门将: 刘殿座 (武汉三镇)  扑救 8 次
========== 扑救排行 ==========
第1名: 刘殿座     (武汉三镇) 扑救 8 次
第2名: 王大雷     (山东泰山) 扑救 6 次
第3名: 韩佳奇     (北京国安) 扑救 5 次
第4名: 颜骏凌     (上海海港) 扑救 3 次
第5名: 鲍亚雄     (上海申花) 扑救 2 次
========== 高于平均水平的门将 ==========
刘殿座 - 扑救 8 次
王大雷 - 扑救 6 次
韩佳奇 - 扑救 5 次
========== 按球队汇总 ==========
上海申花: 2 次
北京国安: 5 次
山东泰山: 6 次
武汉三镇: 8 次
上海海港: 3 次

核心知识点解析

功能 使用的方法 说明
求和 mapToInt().sum() 统计总扑救次数
平均值 average().orElse(0) 计算场均扑救
最大值 max(Comparator) 找最忙门将
排序 sorted() 扑救排行
筛选 filter() 找出高于均值者
分组 groupingBy() 按球队汇总

扩展思路

  1. 多场比赛统计:把每场比赛的扑救数累加,用 Map<String, Integer> 汇总。
  2. 读写文件:从 CSV 读取比赛数据,王大雷,山东泰山,6。
  3. 按扑救率排名:加入"射正次数"字段,用 saveCount / shotsOnTarget 计算扑救率,更公平评价门将表现。
  4. 平局处理:如果多个门将扑救次数相同,可以并列显示"最忙"。

更公平的"谁更忙"判据

单纯看扑救次数不够准确 —— 面对 20 次射正扑出 5 次,和面对 6 次射正扑出 5 次,前者其实更辛苦,可加一个字段:

class Goalkeeper {
    String name;
    int saveCount;        // 扑救次数
    int shotsOnTarget;    // 面对射正次数
    // 扑救率
    double saveRate() {
        return shotsOnTarget == 0 ? 0 : (double) saveCount / shotsOnTarget;
    }
}

然后按 saveRate() 排序,就能得到"效率最高"的门将。


需要我把它改造成读取 CSV 文件或多场比赛汇总的版本吗?

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