本文目录导读:

这是一个非常经典的足球数据统计问题,要判断“上半场是否有进球”,核心逻辑在于比较上半场的比分与全场比分,或者获取精确的事件时间。
下面我给你提供 3 种不同场景 的 Java 实现案例,从最简单到最实用:
仅有全场和半场比分(最常用)
如果你只有 homeHalf(主队半场比分)、awayHalf(客队半场比分)这两个数据,判断逻辑最简单:只要半场比分之和大于 0,就说明有进球。
public class HalfTimeGoalChecker {
/**
* 判断上半场是否有进球
* @param homeHalfScore 主队上半场比分
* @param awayHalfScore 客队上半场比分
* @return true 表示上半场有进球
*/
public static boolean hasGoalInFirstHalf(int homeHalfScore, int awayHalfScore) {
// 核心逻辑:总进球数 > 0
return (homeHalfScore + awayHalfScore) > 0;
}
public static void main(String[] args) {
// 测试用例
System.out.println("案例1 (利物浦 0:0 曼联): " + hasGoalInFirstHalf(0, 0)); // false
System.out.println("案例2 (皇马 2:1 巴萨): " + hasGoalInFirstHalf(2, 1)); // true
System.out.println("案例3 (拜仁 1:0 多特): " + hasGoalInFirstHalf(1, 0)); // true
}
}
基于事件时间戳(比赛事件流)
这是更专业的做法,假设你有一场比赛的所有事件列表(进球、红牌、换人等),每条事件带有“分钟数”和“事件类型”,此时需要筛选出 分钟数 <= 45(或小于 45+补时)的“进球”事件。
import java.util.ArrayList;
import java.util.List;
// 1. 先定义事件类
class MatchEvent {
int minute; // 发生分钟 (1-90)
String eventType; // "goal", "red_card", "yellow_card" 等
public MatchEvent(int minute, String eventType) {
this.minute = minute;
this.eventType = eventType;
}
}
public class EventBasedGoalChecker {
/**
* 基于事件列表判断上半场是否有进球
* @param events 比赛所有事件
* @return true 表示上半场有进球
*/
public static boolean hasGoalInFirstHalf(List<MatchEvent> events) {
// 判断标准:存在某个事件,类型是goal,且发生时间在45分钟以内(含45分钟)
return events.stream()
.anyMatch(e -> "goal".equals(e.eventType) && e.minute <= 45);
}
public static void main(String[] args) {
// 模拟一场比赛:第30分钟有进球,第67分钟有进球
List<MatchEvent> events = new ArrayList<>();
events.add(new MatchEvent(12, "yellow_card")); // 黄牌不算
events.add(new MatchEvent(30, "goal")); // 上半场进球
events.add(new MatchEvent(67, "goal")); // 下半场进球
boolean firstHalfGoal = hasGoalInFirstHalf(events);
System.out.println("上半场是否有进球? " + firstHalfGoal); // 输出 true
}
}
处理复杂情况(含伤停补时)
在真实比赛中,上半场补时可能到 45+2、45+3 等,严格意义上,上半场结束时间是 第 45 分钟的最后一次进攻结束,但通常用 minute <= 45 统一处理。
如果你需要兼容补时,可以增加一个 isFirstHalf 布尔字段来判断是否属于上半场,而不单纯看分钟数:
class AdvancedMatchEvent {
int minute;
String eventType;
boolean isFirstHalf; // 明确标记是否属于上半场
public AdvancedMatchEvent(int minute, String eventType, boolean isFirstHalf) {
this.minute = minute;
this.eventType = eventType;
this.isFirstHalf = isFirstHalf;
}
}
// 省略其余代码...
// 判断逻辑改为:
// e.isFirstHalf == true && "goal".equals(e.eventType)
总结对比
| 场景 | 核心思路 | 适用场景 |
|---|---|---|
| 场景一 | 半场比分之和 > 0 |
仅有赛果数据,最简单 |
| 场景二 | 事件过滤 (goal & minute<=45) |
实时数据流,有事件推送 |
| 场景三 | 明确的上半场标记 |
有详细的数据结构,最精确 |
在实际开发中,如果对接的是第三方 API(如 SportRadar、API-Football),通常同时提供 score.halftime 和 events 字段。调接口时优先取半场比分(场景一),因为它已经由数据商帮你聚合好了。