Java案例:变向突破次数对比分析
下面通过一个完整的Java案例,来对比不同球员/场景下的变向突破次数(以篮球运动为背景),涵盖数据建模、统计计算和对比分析。

需求场景
假设我们有一组篮球运动员的比赛数据,需要:
- 统计每位球员的变向突破次数
- 对比不同球员/球队的突破能力
- 按突破次数排序并输出分析结果
实体类设计
// 球员实体类
public class Player {
private String name; // 球员姓名
private String team; // 所属球队
private int crossoverCount; // 变向突破次数
private int gameCount; // 出场次数
private int successCount; // 突破成功次数
public Player(String name, String team, int crossoverCount,
int gameCount, int successCount) {
this.name = name;
this.team = team;
this.crossoverCount = crossoverCount;
this.gameCount = gameCount;
this.successCount = successCount;
}
// 场均突破次数
public double getAvgCrossover() {
return gameCount == 0 ? 0 : (double) crossoverCount / gameCount;
}
// 突破成功率
public double getSuccessRate() {
return crossoverCount == 0 ? 0 : (double) successCount / crossoverCount * 100;
}
// getter
public String getName() { return name; }
public String getTeam() { return team; }
public int getCrossoverCount() { return crossoverCount; }
public int getGameCount() { return gameCount; }
public int getSuccessCount() { return successCount; }
@Override
public String toString() {
return String.format("%-10s | %-8s | 总突破:%-4d | 场均:%.2f | 成功率:%.1f%%",
name, team, crossoverCount, getAvgCrossover(), getSuccessRate());
}
}
核心分析类
import java.util.*;
import java.util.stream.Collectors;
public class CrossoverAnalyzer {
// 1. 按总突破次数降序排序
public static List<Player> sortByTotalCrossover(List<Player> players) {
return players.stream()
.sorted(Comparator.comparingInt(Player::getCrossoverCount).reversed())
.collect(Collectors.toList());
}
// 2. 按场均突破次数排序
public static List<Player> sortByAvgCrossover(List<Player> players) {
return players.stream()
.sorted(Comparator.comparingDouble(Player::getAvgCrossover).reversed())
.collect(Collectors.toList());
}
// 3. 按球队分组统计突破总数
public static Map<String, Integer> groupByTeam(List<Player> players) {
return players.stream()
.collect(Collectors.groupingBy(
Player::getTeam,
Collectors.summingInt(Player::getCrossoverCount)
));
}
// 4. 找出突破王(场均最高)
public static Optional<Player> findTopCrossoverPlayer(List<Player> players) {
return players.stream()
.max(Comparator.comparingDouble(Player::getAvgCrossover));
}
// 5. 对比两名球员
public static void compareTwoPlayers(Player p1, Player p2) {
System.out.println("\n===== 球员对比 =====");
System.out.println(p1);
System.out.println(p2);
System.out.println("-------------------");
System.out.printf("总突破差值: %d 次 (差 %.1f%%)%n",
p1.getCrossoverCount() - p2.getCrossoverCount(),
Math.abs(p1.getCrossoverCount() - p2.getCrossoverCount()) * 100.0 /
Math.max(p1.getCrossoverCount(), p2.getCrossoverCount()));
System.out.printf("场均差值: %.2f 次%n",
p1.getAvgCrossover() - p2.getAvgCrossover());
System.out.printf("成功率差值: %.1f%%%n",
p1.getSuccessRate() - p2.getSuccessRate());
}
// 6. 分组对比:不同球队的场均突破能力
public static void compareTeams(List<Player> players) {
Map<String, Double> teamAvg = players.stream()
.collect(Collectors.groupingBy(
Player::getTeam,
Collectors.averagingDouble(Player::getAvgCrossover)
));
System.out.println("\n===== 球队场均突破对比 =====");
teamAvg.entrySet().stream()
.sorted(Map.Entry.<String, Double>comparingByValue().reversed())
.forEach(e -> System.out.printf("%-8s : %.2f 次/场%n",
e.getKey(), e.getValue()));
}
}
测试主程序
import java.util.*;
public class Main {
public static void main(String[] args) {
List<Player> players = Arrays.asList(
new Player("郭艾伦", "辽宁", 156, 30, 98),
new Player("赵睿", "广东", 132, 30, 79),
new Player("孙铭徽", "广厦", 174, 30, 105),
new Player("吴前", "浙江", 118, 30, 65),
new Player("赵继伟", "辽宁", 128, 30, 76),
new Player("胡明轩", "广东", 105, 30, 62)
);
// 1. 按总突破次数排序
System.out.println("===== 按总突破次数排名 =====");
CrossoverAnalyzer.sortByTotalCrossover(players)
.forEach(System.out::println);
// 2. 按场均突破次数排序
System.out.println("\n===== 按场均突破次数排名 =====");
CrossoverAnalyzer.sortByAvgCrossover(players)
.forEach(System.out::println);
// 3. 球队分组统计
System.out.println("\n===== 球队突破总数 =====");
CrossoverAnalyzer.groupByTeam(players)
.forEach((team, cnt) -> System.out.printf("%-8s : %d 次%n", team, cnt));
// 4. 突破王
CrossoverAnalyzer.findTopCrossoverPlayer(players)
.ifPresent(p -> System.out.println("\n🏆 突破王: " + p.getName()
+ " (场均 " + String.format("%.2f", p.getAvgCrossover()) + " 次)"));
// 5. 双人对比
CrossoverAnalyzer.compareTwoPlayers(players.get(0), players.get(2));
// 6. 球队对比
CrossoverAnalyzer.compareTeams(players);
}
}
运行结果示例
===== 按总突破次数排名 =====
孙铭徽 | 广厦 | 总突破:174 | 场均:5.80 | 成功率:60.3%
郭艾伦 | 辽宁 | 总突破:156 | 场均:5.20 | 成功率:62.8%
赵睿 | 广东 | 总突破:132 | 场均:4.40 | 成功率:59.8%
赵继伟 | 辽宁 | 总突破:128 | 场均:4.27 | 成功率:59.4%
吴前 | 浙江 | 总突破:118 | 场均:3.93 | 成功率:55.1%
胡明轩 | 广东 | 总突破:105 | 场均:3.50 | 成功率:59.0%
===== 球队场均突破对比 =====
广厦 : 5.80 次/场
辽宁 : 4.73 次/场
广东 : 3.95 次/场
浙江 : 3.93 次/场
技术要点总结
| 维度 | 实现方式 |
|---|---|
| 数据建模 | Player 类封装原始数据 + 派生指标方法 |
| 排序对比 | Stream.sorted() + Comparator.comparingInt/Double |
| 分组对比 | Collectors.groupingBy + summingInt/averagingDouble |
| 极值查找 | Stream.max() + Optional 防空 |
| 差值分析 | 双人差值对比方法,输出百分比差距 |
| 流式处理 | 全部基于 Java 8+ Stream API |
可扩展方向
- 加入时间维度:按赛季/月份对比突破次数趋势
- 可视化输出:结合 JFreeChart 生成柱状图对比
- 突破方式细分:Crossover / Behind-the-back / Between-the-legs 分类统计
- 引入权重:结合成功率、失误率做综合评分
- 接入数据库:使用 JDBC / MyBatis 从实际比赛数据读取
如果需要具体某个方向(如加入图表、接入数据库、多维度评分模型)的扩展实现,可以告诉我进一步细化。