如何使用Java 8 Stream API实现球队指定位置的覆盖性校验
用Java 8 Stream API实现嵌套列表的条件检查
没问题!咱们来把你原来的Java 7循环逻辑,用Java 8的Stream API重写,让代码更简洁、更具声明式风格。
核心思路拆解
原来的逻辑是:判断所有目标位置是否都被球队覆盖,也就是每个目标位置都能在至少一名球员的胜任位置列表中找到。用Stream API的话,我们可以借助两个关键操作:
flatMap:把嵌套的列表(球队→球员→位置)扁平化为一个连续的Position流,轻松替代嵌套循环allMatch:确保所有目标位置都满足“被覆盖”的条件anyMatch:判断单个位置是否存在匹配的球员
重写后的代码实现
首先,我们可以把原来的两个方法用Stream重写,这里提供两种写法供你参考:
写法1:内联逻辑,更紧凑
import java.util.Arrays; import java.util.List; import java.util.Objects; public class Main2 { static String[] positionsThatWillBeCovered = new String[]{"RB", "LB", "MD"}; static String[] positionsThatWillNotBeCovered = new String[]{"RB", "LB", "MD", "GK"}; public static void main(String[] args) { Position p1 = new Position("RB"); Position p2 = new Position("LB"); Position p3 = new Position("MD"); Player alves = new Player(Arrays.asList(p1, p2)); Player alba = new Player(Arrays.asList(p2)); Player xavi = new Player(Arrays.asList(p3)); Team team = new Team(Arrays.asList(alves, alba, xavi)); //should print true System.out.println(testAllPositionsAreCovered(team, positionsThatWillBeCovered)); //false System.out.println(testAllPositionsAreCovered(team, positionsThatWillNotBeCovered)); } private static boolean testAllPositionsAreCovered(Team team, String[] positionsToCover) { // 将目标位置数组转为Stream,检查所有位置都被覆盖 return Arrays.stream(positionsToCover) .allMatch(targetPosition -> team.getPlayerList().stream() // 处理可能的null位置列表,避免NPE .map(Player::getPositions) .filter(Objects::nonNull) // 扁平化为所有球员的位置流 .flatMap(List::stream) // 判断是否存在匹配的位置 .anyMatch(position -> position.getPosition().equals(targetPosition)) ); } } // 以下Team、Player、Position类保持和你原来的代码一致 class Team { private List<Player> playerList; Team(List<Player> playerList){ this.playerList = playerList; } public List<Player> getPlayerList() { return playerList; } } class Player { private List<Position> positions; Player(List<Position> positions){ this.positions = positions; } public List<Position> getPositions() { return positions; } } class Position { private String position; //some other fields... public Position(String position) { this.position = position; } public String getPosition() { return position; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Position position1 = (Position) o; return Objects.equals(position, position1.position); } @Override public int hashCode() { return Objects.hash(position); } }
写法2:拆分方法,更易读
如果希望逻辑更清晰,可以把单个位置的检查逻辑抽成独立方法:
private static boolean isPositionCovered(Team team, String targetPosition) { return team.getPlayerList().stream() .map(Player::getPositions) .filter(Objects::nonNull) .flatMap(List::stream) .anyMatch(position -> position.getPosition().equals(targetPosition)); } private static boolean testAllPositionsAreCovered(Team team, String[] positionsToCover) { return Arrays.stream(positionsToCover) .allMatch(target -> isPositionCovered(team, target)); }
关键细节说明
- 空值处理:加入
filter(Objects::nonNull)是为了避免如果某个球员的positions列表为null时抛出NullPointerException,让代码更健壮。 - 声明式风格:Stream API让我们不用关心循环的执行细节,只需要表达“要做什么”(检查所有位置都被覆盖),而不是“怎么做”(嵌套循环遍历)。
- 性能对比:这个实现和你原来的Java 7逻辑性能基本一致,因为
allMatch和anyMatch都是短路操作——一旦找到不满足条件的元素就会停止遍历,不会处理所有元素。
内容的提问来源于stack exchange,提问作者xmen-5
相关产品推荐
相关产品推荐

