Java案例:统计区域防守漏洞出现次数
下面是一个完整的Java案例,用于统计篮球/足球等运动中区域防守漏洞出现的次数,包含数据模型、统计逻辑和测试示例。

数据模型
import java.util.*;
import java.util.stream.Collectors;
/**
* 防守事件记录
*/
class DefenseEvent {
private final String zone; // 防守区域,如 "左侧禁区"、"中路"
private final boolean isVulnerable; // 是否为漏洞(true=漏洞, false=正常防守)
private final String timestamp; // 发生时间
public DefenseEvent(String zone, boolean isVulnerable, String timestamp) {
this.zone = zone;
this.isVulnerable = isVulnerable;
this.timestamp = timestamp;
}
public String getZone() { return zone; }
public boolean isVulnerable() { return isVulnerable; }
public String getTimestamp() { return timestamp; }
@Override
public String toString() {
return String.format("[%s] 区域=%s 漏洞=%s", timestamp, zone, isVulnerable);
}
}
统计服务
/**
* 区域防守漏洞统计器
*/
class DefenseAnalyzer {
/**
* 统计所有防守漏洞出现的总次数
*/
public long countTotalVulnerabilities(List<DefenseEvent> events) {
if (events == null || events.isEmpty()) return 0;
return events.stream()
.filter(DefenseEvent::isVulnerable)
.count();
}
/**
* 按区域分组统计漏洞次数(只统计漏洞事件)
* 返回:区域 -> 漏洞次数(按次数降序)
*/
public Map<String, Long> countByZone(List<DefenseEvent> events) {
if (events == null || events.isEmpty()) return Collections.emptyMap();
return events.stream()
.filter(DefenseEvent::isVulnerable)
.collect(Collectors.groupingBy(
DefenseEvent::getZone,
Collectors.counting()))
.entrySet().stream()
.sorted(Map.Entry.<String, Long>comparingByValue().reversed())
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(a, b) -> a,
LinkedHashMap::new));
}
/**
* 计算某区域的漏洞率 = 漏洞次数 / 该区域总事件数
*/
public double getVulnerabilityRate(List<DefenseEvent> events, String zone) {
if (events == null || events.isEmpty()) return 0.0;
long totalInZone = events.stream()
.filter(e -> e.getZone().equals(zone))
.count();
if (totalInZone == 0) return 0.0;
long vulnInZone = events.stream()
.filter(e -> e.getZone().equals(zone) && e.isVulnerable())
.count();
return (double) vulnInZone / totalInZone;
}
/**
* 找出漏洞最多的区域
*/
public Optional<String> findMostVulnerableZone(List<DefenseEvent> events) {
return countByZone(events).entrySet().stream()
.max(Map.Entry.comparingByValue())
.map(Map.Entry::getKey);
}
/**
* 打印统计报告
*/
public void printReport(List<DefenseEvent> events) {
System.out.println("========= 区域防守漏洞统计报告 =========");
System.out.println("漏洞总次数: " + countTotalVulnerabilities(events));
System.out.println("\n--- 各区域漏洞次数 ---");
countByZone(events).forEach((zone, count) ->
System.out.printf("%-10s : %d 次 (漏洞率 %.1f%%)\n",
zone, count, getVulnerabilityRate(events, zone) * 100));
findMostVulnerableZone(events)
.ifPresent(z -> System.out.println("\n⚠ 漏洞最严重区域: " + z));
System.out.println("========================================");
}
}
测试主程序
public class DefenseVulnerabilityDemo {
public static void main(String[] args) {
List<DefenseEvent> events = Arrays.asList(
new DefenseEvent("左侧禁区", true, "10:01"),
new DefenseEvent("左侧禁区", true, "10:15"),
new DefenseEvent("左侧禁区", false, "10:30"),
new DefenseEvent("中路", true, "11:02"),
new DefenseEvent("中路", true, "11:20"),
new DefenseEvent("中路", true, "11:45"),
new DefenseEvent("右侧禁区", false, "12:05"),
new DefenseEvent("右侧禁区", true, "12:30"),
new DefenseEvent("右侧禁区", false, "12:50"),
new DefenseEvent("中路", false, "13:10")
);
DefenseAnalyzer analyzer = new DefenseAnalyzer();
analyzer.printReport(events);
// 单项查询示例
System.out.println("\n[查询] 中路漏洞率: "
+ String.format("%.1f%%",
analyzer.getVulnerabilityRate(events, "中路") * 100));
}
}
运行结果
========= 区域防守漏洞统计报告 =========
漏洞总次数: 6
--- 各区域漏洞次数 ---
中路 : 3 次 (漏洞率 75.0%)
左侧禁区 : 2 次 (漏洞率 66.7%)
右侧禁区 : 1 次 (漏洞率 33.3%)
⚠ 漏洞最严重区域: 中路
========================================
[查询] 中路漏洞率: 75.0%
核心思路说明
| 功能 | 实现方式 |
|---|---|
| 总漏洞次数 | stream().filter(isVulnerable).count() |
| 按区域分组计数 | Collectors.groupingBy(zone, counting()) |
| 排序输出 | 转成 LinkedHashMap 按值降序 |
| 漏洞率 | 该区域漏洞数 / 该区域总事件数 |
| 最严重区域 | max(comparingByValue()) |
扩展建议
- 真实场景:把
DefenseEvent替换成数据库中读取的数据(如从List<DefenseEvent>换成 JDBC/MyBatis 查询结果)。 - 时间维度:可按半场、节次或时间窗口分组,用
Collectors.groupingBy(event -> event.getPeriod())。 - 权重统计:给不同区域设置权重(如禁区权重 3、中场权重 1),用
weightedCounting变体。 - 可视化:结果输出到前端热力图,或用 JFreeChart 生成柱状图。
如果你能告诉我具体领域(篮球?足球?电竞?)和数据来源(数据库/Excel/JSON),我可以进一步定制这个案例。