Java案例:变向突破次数对比分析
下面我用一个完整的Java案例,来对比不同球员/不同算法的变向突破次数,并做统计分析。

场景设计
假设我们要统计篮球运动员在比赛中变向突破(Crossover Drive)的次数,对比:
- 球员A vs 球员B
- 或者 算法统计 vs 人工统计
实体类设计
import java.util.*;
import java.util.stream.Collectors;
/**
* 球员变向突破记录
*/
class Player {
private String name; // 球员姓名
private int crossoverCount; // 变向突破次数
private int games; // 比赛场次
private int points; // 得分
public Player(String name, int crossoverCount, int games, int points) {
this.name = name;
this.crossoverCount = crossoverCount;
this.games = games;
this.points = points;
}
// 场均变向突破次数
public double avgCrossover() {
return games == 0 ? 0 : (double) crossoverCount / games;
}
// getter / setter
public String getName() { return name; }
public int getCrossoverCount() { return crossoverCount; }
public int getGames() { return games; }
public int getPoints() { return points; }
@Override
public String toString() {
return String.format("%-10s 总变向:%-4d 场次:%-3d 场均:%.2f 得分:%d",
name, crossoverCount, games, avgCrossover(), points);
}
}
对比分析主程序
public class CrossoverCompare {
public static void main(String[] args) {
// 1. 准备数据
List<Player> players = Arrays.asList(
new Player("欧文", 156, 20, 512),
new Player("库里", 132, 20, 480),
new Player("哈登", 148, 20, 498),
new Player("东契奇", 120, 20, 460),
new Player("莫兰特", 140, 20, 455)
);
System.out.println("========== 球员变向突破数据 ==========");
players.forEach(System.out::println);
// 2. 排序:按总变向次数降序
System.out.println("\n========== 按总变向次数排名 ==========");
players.stream()
.sorted(Comparator.comparingInt(Player::getCrossoverCount).reversed())
.forEach(p -> System.out.println(
p.getName() + " → " + p.getCrossoverCount() + " 次"));
// 3. 排序:按场均变向次数降序
System.out.println("\n========== 按场均变向次数排名 ==========");
players.stream()
.sorted(Comparator.comparingDouble(Player::avgCrossover).reversed())
.forEach(p -> System.out.printf("%s → %.2f 次/场%n",
p.getName(), p.avgCrossover()));
// 4. 平均值 / 最大值 / 最小值
IntSummaryStatistics stat = players.stream()
.mapToInt(Player::getCrossoverCount)
.summaryStatistics();
System.out.println("\n========== 统计分析 ==========");
System.out.println("总变向次数之和: " + stat.getSum());
System.out.println("平均总变向次数: " + String.format("%.2f", stat.getAverage()));
System.out.println("最高: " + stat.getMax());
System.out.println("最低: " + stat.getMin());
// 5. 分组对比:高于平均 vs 低于平均
double avg = stat.getAverage();
Map<String, List<Player>> group = players.stream()
.collect(Collectors.groupingBy(
p -> p.getCrossoverCount() >= avg ? "高于平均" : "低于平均"));
System.out.println("\n========== 分组对比 ==========");
group.forEach((k, v) -> {
System.out.println("【" + k + "】");
v.forEach(p -> System.out.println(" " + p.getName()
+ " (" + p.getCrossoverCount() + "次)"));
});
// 6. 两两对比示例:欧文 vs 哈登
System.out.println("\n========== 两两对比:欧文 vs 哈登 ==========");
Player kyrie = players.get(0);
Player harden = players.get(2);
compareTwo(kyrie, harden);
}
/**
* 两名球员对比
*/
public static void compareTwo(Player a, Player b) {
int diff = a.getCrossoverCount() - b.getCrossoverCount();
String winner = diff > 0 ? a.getName() : (diff < 0 ? b.getName() : "平局");
System.out.printf("%s: %d 次 | %s: %d 次%n",
a.getName(), a.getCrossoverCount(),
b.getName(), b.getCrossoverCount());
System.out.println("差值: " + Math.abs(diff) + " 次");
System.out.println("胜者: " + winner);
// 场均对比
System.out.printf("场均: %s=%.2f %s=%.2f%n",
a.getName(), a.avgCrossover(),
b.getName(), b.avgCrossover());
}
}
运行结果示例
========== 球员变向突破数据 ==========
欧文 总变向:156 场次:20 场均:7.80 得分:512
库里 总变向:132 场次:20 场均:6.60 得分:480
哈登 总变向:148 场次:20 场均:7.40 得分:498
东契奇 总变向:120 场次:20 场均:6.00 得分:460
莫兰特 总变向:140 场次:20 场均:7.00 得分:455
========== 按总变向次数排名 ==========
欧文 → 156 次
哈登 → 148 次
莫兰特 → 140 次
库里 → 132 次
东契奇 → 120 次
========== 按场均变向次数排名 ==========
欧文 → 7.80 次/场
哈登 → 7.40 次/场
莫兰特 → 7.00 次/场
库里 → 6.60 次/场
东契奇 → 6.00 次/场
========== 统计分析 ==========
总变向次数之和: 696
平均总变向次数: 139.20
最高: 156
最低: 120
========== 分组对比 ==========
【高于平均】
欧文 (156次)
哈登 (148次)
莫兰特 (140次)
【低于平均】
库里 (132次)
东契奇 (120次)
========== 两两对比:欧文 vs 哈登 ==========
欧文: 156 次 | 哈登: 148 次
差值: 8 次
胜者: 欧文
场均: 欧文=7.80 哈登=7.40
进阶:两种"识别算法"对变向次数的对比
如果你要做的是算法识别变向突破次数的对比(如 YOLO vs 关键点检测),可以这样设计:
class DetectionResult {
String algorithm; // 算法名称
int detectedCount; // 识别到的变向次数
int groundTruth; // 人工标注真实值
public DetectionResult(String algorithm, int detectedCount, int groundTruth) {
this.algorithm = algorithm;
this.detectedCount = detectedCount;
this.groundTruth = groundTruth;
}
public double accuracy() {
return groundTruth == 0 ? 0 :
1 - Math.abs(detectedCount - groundTruth) / (double) groundTruth;
}
}
public class AlgorithmCompare {
public static void main(String[] args) {
List<DetectionResult> results = Arrays.asList(
new DetectionResult("YOLOv8", 142, 156),
new DetectionResult("OpenPose", 128, 156),
new DetectionResult("MediaPipe",135, 156)
);
System.out.println("算法\t\t识别次数\t真实值\t准确率");
results.forEach(r -> System.out.printf("%-12s\t%d\t\t%d\t%.2f%%%n",
r.algorithm, r.detectedCount, r.groundTruth, r.accuracy() * 100));
// 找最准的算法
results.stream()
.max(Comparator.comparingDouble(DetectionResult::accuracy))
.ifPresent(best -> System.out.println("\n最准算法: " + best.algorithm));
}
}
输出:
算法 识别次数 真实值 准确率
YOLOv8 142 156 91.03%
OpenPose 128 156 82.05%
MediaPipe 135 156 86.54%
最准算法: YOLOv8
核心知识点总结
| 知识点 | 用途 |
|---|---|
Comparator.comparingInt |
按整数字段排序对比 |
stream().summaryStatistics() |
一次性获取总数/均值/最大/最小 |
Collectors.groupingBy |
按条件分组对比 |
Math.abs + if-else |
两两差值对比 |
| 面向对象封装 | 用类描述"变向突破"业务数据 |
如果你需要具体某个方向的对比,
- 🏀 球员 vs 球员
- 🤖 算法 vs 算法(YOLO/OpenPose/MediaPipe)
- 📊 赛季 vs 赛季
告诉我具体场景,我可以给你定制一份更贴合需求的代码。