本文目录导读:

看两队历史交锋记录,在Java中通常有几种不同的场景,我先帮你梳理一下最常见的三种情况,以及对应的解决方案:
数据在数据库中(最常见)
如果历史交锋数据存储在数据库(如MySQL)中,通常有类似 match_history 表,包含 home_team_id、away_team_id、match_date 等字段。
核心SQL思路: 你需要查询 A队作为主队 vs B队作为客队 和 B队作为主队 vs A队作为客队 的所有比赛,然后合并排序。
完整Java示例(使用 MyBatis-Plus 或 JDBC):
// 1. 实体类
@Data
@TableName("match_history")
public class MatchHistory {
@TableId
private Long id;
private Long homeTeamId;
private Long awayTeamId;
private Integer homeScore;
private Integer awayScore;
private Date matchDate;
// ... 其他字段
}
// 2. Mapper 接口
@Mapper
public interface MatchHistoryMapper extends BaseMapper<MatchHistory> {
}
// 3. Service 核心逻辑
@Service
public class MatchService {
@Autowired
private MatchHistoryMapper matchHistoryMapper;
public List<MatchHistory> getHeadToHead(Long teamAId, Long teamBId) {
// 方法一:组合查询(推荐)
LambdaQueryWrapper<MatchHistory> wrapper = new LambdaQueryWrapper<>();
wrapper.and(w -> w
.eq(MatchHistory::getHomeTeamId, teamAId)
.eq(MatchHistory::getAwayTeamId, teamBId))
.or(o -> o
.eq(MatchHistory::getHomeTeamId, teamBId)
.eq(MatchHistory::getAwayTeamId, teamAId));
wrapper.orderByDesc(MatchHistory::getMatchDate);
return matchHistoryMapper.selectList(wrapper);
// 方法二:原生SQL(适合复杂统计)
// List<Map<String, Object>> list = matchHistoryMapper.selectMaps(
// new QueryWrapper<MatchHistory>()
// .inSql("(home_team_id = " + teamAId + " AND away_team_id = " + teamBId +
// ") OR (home_team_id = " + teamBId + " AND away_team_id = " + teamAId + ")")
// .orderByDesc("match_date"));
}
}
数据在接口返回的JSON中(调用第三方API)
如果历史记录来自外部API(如足球数据API),返回的 JSONArray 中每条记录包含两队ID。
public class ApiMatchService {
// 假设API返回 [{homeTeamId:1, awayTeamId:2, ...}, ...]
public List<Match> filterHeadToHead(JSONArray allMatches, Long teamAId, Long teamBId) {
List<Match> result = new ArrayList<>();
for (int i = 0; i < allMatches.size(); i++) {
JSONObject obj = allMatches.getJSONObject(i);
Long homeId = obj.getLong("homeTeamId");
Long awayId = obj.getLong("awayTeamId");
// 关键判断:只要两队相遇就加入
if ((homeId.equals(teamAId) && awayId.equals(teamBId)) ||
(homeId.equals(teamBId) && awayId.equals(teamAId))) {
result.add(obj.toJavaObject(Match.class));
}
}
// 按日期排序(假设有 date 字段)
result.sort(Comparator.comparing(Match::getDate).reversed());
return result;
}
}
数据在Excel/CSV文件中
如果历史记录在本地文件,需要先读取文件,然后按队伍ID过滤。
// 使用 Apache POI 或 EasyExcel 读取
public List<MatchHistory> readFromExcel(String filePath) {
// EasyExcel 读取示例
List<MatchHistory> list = EasyExcel.read(filePath)
.head(MatchHistory.class)
.sheet()
.doReadSync();
// 然后过滤出交锋记录
return list.stream()
.filter(m -> (m.getHomeTeamId().equals(teamA) && m.getAwayTeamId().equals(teamB))
|| (m.getHomeTeamId().equals(teamB) && m.getAwayTeamId().equals(teamA)))
.sorted(Comparator.comparing(MatchHistory::getMatchDate).reversed())
.collect(Collectors.toList());
}
进阶需求:统计战绩(胜平负)
如果还需要统计总战绩(比如A队3胜2平1负),可以在查询后加入统计逻辑:
public Map<String, Integer> getHeadToHeadStats(Long teamAId, Long teamBId) {
List<MatchHistory> matches = getHeadToHead(teamAId, teamBId);
int win = 0, draw = 0, lose = 0;
for (MatchHistory m : matches) {
// 判断A队是否为主队
boolean isHome = m.getHomeTeamId().equals(teamAId);
int teamA_score = isHome ? m.getHomeScore() : m.getAwayScore();
int teamB_score = isHome ? m.getAwayScore() : m.getHomeScore();
if (teamA_score > teamB_score) win++;
else if (teamA_score == teamB_score) draw++;
else lose++;
}
return Map.of("win", win, "draw", draw, "lose", lose);
}
补充提示
- 注意主场优势:如果字段中有
neutral(中立场)标记,要记得考虑。 - 排序:
ORDER BY match_date DESC排序,最新的比赛显示在最前面。 - 性能优化:如果数据量很大,建议在数据库层就通过
(home_team_id, away_team_id)建立联合索引。
如果你能补充说明一下你的数据具体存在哪里(数据库表结构 / JSON / Excel),以及你是用 Spring Boot 还是纯 Java 环境,我可以给你更精确的代码。