Java案例:统计假动作晃过防守次数
下面是一个完整的Java示例,模拟篮球比赛中统计球员通过假动作(如投篮假动作、突破假动作)晃过防守的次数。

需求分析
- 每次防守对抗时,判断进攻球员是否使用了假动作
- 假动作成功后,防守球员被晃开,计为一次"晃过防守"
- 支持统计单个球员和全队的晃过次数
完整代码实现
import java.util.*;
/**
* 假动作类型枚举
*/
enum FakeMoveType {
SHOOT_FAKE("投篮假动作"),
DRIVE_FAKE("突破假动作"),
PASS_FAKE("传球假动作");
private final String desc;
FakeMoveType(String desc) {
this.desc = desc;
}
public String getDesc() {
return desc;
}
}
/**
* 球员类
*/
class Player {
private final String name;
private int fakeSuccessCount = 0; // 晃过防守成功次数
private int fakeTotalCount = 0; // 假动作总次数
public Player(String name) {
this.name = name;
}
public String getName() { return name; }
public int getFakeSuccessCount() { return fakeSuccessCount; }
public int getFakeTotalCount() { return fakeTotalCount; }
/**
* 记录一次假动作尝试
* @param success 是否成功晃过防守
*/
public void recordFake(boolean success) {
fakeTotalCount++;
if (success) {
fakeSuccessCount++;
}
}
/** 假动作成功率 */
public double getSuccessRate() {
return fakeTotalCount == 0 ? 0 :
(double) fakeSuccessCount / fakeTotalCount * 100;
}
@Override
public String toString() {
return String.format("%s:假动作 %d 次,晃过防守 %d 次,成功率 %.1f%%",
name, fakeTotalCount, fakeSuccessCount, getSuccessRate());
}
}
/**
* 假动作统计管理器
*/
class FakeMoveStatistics {
private final Map<String, Player> players = new LinkedHashMap<>();
// 按假动作类型统计成功次数
private final Map<FakeMoveType, Integer> typeSuccessCount = new EnumMap<>(FakeMoveType.class);
public void addPlayer(Player player) {
players.put(player.getName(), player);
}
/**
* 记录一次假动作结果
*/
public void recordFake(String playerName, FakeMoveType type, boolean success) {
Player player = players.get(playerName);
if (player == null) {
throw new IllegalArgumentException("球员不存在: " + playerName);
}
player.recordFake(success);
if (success) {
typeSuccessCount.merge(type, 1, Integer::sum);
}
}
/** 全队晃过防守总次数 */
public int getTotalSuccessCount() {
return players.values().stream()
.mapToInt(Player::getFakeSuccessCount)
.sum();
}
/** 全队假动作总次数 */
public int getTotalFakeCount() {
return players.values().stream()
.mapToInt(Player::getFakeTotalCount)
.sum();
}
/** 打印统计报告 */
public void printReport() {
System.out.println("========= 假动作晃过防守统计 =========");
players.values().forEach(System.out::println);
System.out.println("---------------------------------------");
System.out.printf("全队:假动作 %d 次,晃过防守 %d 次,成功率 %.1f%%%n",
getTotalFakeCount(), getTotalSuccessCount(),
getTotalFakeCount() == 0 ? 0 :
(double) getTotalSuccessCount() / getTotalFakeCount() * 100);
System.out.println("--- 各类型假动作成功次数 ---");
typeSuccessCount.forEach((type, count) ->
System.out.printf("%s:%d 次%n", type.getDesc(), count));
// 找出晃过防守最多的球员
players.values().stream()
.max(Comparator.comparingInt(Player::getFakeSuccessCount))
.ifPresent(p -> System.out.println("🏆 最佳假动作球员:" + p.getName()
+ "(" + p.getFakeSuccessCount() + " 次)"));
}
}
/**
* 测试主类
*/
public class FakeMoveDemo {
public static void main(String[] args) {
FakeMoveStatistics stats = new FakeMoveStatistics();
// 添加球员
stats.addPlayer(new Player("库里"));
stats.addPlayer(new Player("欧文"));
stats.addPlayer(new Player("东契奇"));
// 模拟比赛数据
stats.recordFake("库里", FakeMoveType.SHOOT_FAKE, true);
stats.recordFake("库里", FakeMoveType.SHOOT_FAKE, true);
stats.recordFake("库里", FakeMoveType.DRIVE_FAKE, false);
stats.recordFake("欧文", FakeMoveType.DRIVE_FAKE, true);
stats.recordFake("欧文", FakeMoveType.DRIVE_FAKE, true);
stats.recordFake("欧文", FakeMoveType.PASS_FAKE, true);
stats.recordFake("欧文", FakeMoveType.SHOOT_FAKE, false);
stats.recordFake("东契奇", FakeMoveType.SHOOT_FAKE, true);
stats.recordFake("东契奇", FakeMoveType.DRIVE_FAKE, false);
// 输出统计
stats.printReport();
}
}
运行结果
========= 假动作晃过防守统计 =========
库里:假动作 3 次,晃过防守 2 次,成功率 66.7%
欧文:假动作 4 次,晃过防守 3 次,成功率 75.0%
东契奇:假动作 2 次,晃过防守 1 次,成功率 50.0%
---------------------------------------
全队:假动作 9 次,晃过防守 6 次,成功率 66.7%
--- 各类型假动作成功次数 ---
投篮假动作:3 次
突破假动作:2 次
传球假动作:1 次
🏆 最佳假动作球员:欧文(3 次)
核心设计要点
| 设计点 | 说明 |
|---|---|
枚举 FakeMoveType |
区分投篮、突破、传球三类假动作 |
Player 类 |
用 fakeSuccessCount 和 fakeTotalCount 分别记录成功/总次数 |
recordFake() 方法 |
每次尝试假动作时传入 success 布尔值决定是否计数 |
EnumMap 分类统计 |
按假动作类型统计成功次数,便于战术分析 |
| Stream API | 求总和、求最大值,代码更简洁 |
可扩展方向
- 加入防守球员维度:记录"晃过了谁",如
Map<String, Integer> beatenDefenders - 按节次统计:区分第1~4节假动作效率,分析体能影响
- 结合命中率:假动作成功后是否转化为得分,计算"假动作转化率"
- 数据持久化:将统计结果写入 CSV/JSON,供赛后复盘
如需改成"从文件/控制台输入比赛数据"或"多场比赛累计版本",可以在 recordFake 调用层再做一层数据读取解析即可。
版权声明:本站文章为原创整理,转载请注明出处。