首先查找不同集合类型的多个流

时间:2018-09-26 13:03:38

标签: concurrency java-8 java-stream

public class ImmutableCrazySquares { 
   private final List<Square> xraySquare;
   private final Map<String, Set<Square>> yankeSquare
   private final Map<String, Set<Square>> zuloSquare;
    .
    .
    .
   @VisibleForTesting
   private boolean exists(String squareId) {
    boolean matches = yankeSquare.values().stream().anyMatch(squares ->
        squares.stream().anyMatch(square -> square.getId().equals(squareId)));
    if (!matches) {
        matches = xraySquare.stream()
            .anyMatch(square -> square.getId().equals(squareId));
    }
    if (!matches) {
        matches = zuloSquare.values().stream().anyMatch(squares ->
            squares.stream().anyMatch(square -> square.getId().equals(squareId)));
    }
    return matches;
   }
}

上面的类有十二个方法,但是现在我只想重点介绍这个存在的方法。 本质上,我想查看xraySquare,yankeSquare,zuloSquare的3个集合,如果我发送的id在其中的任何一个中,我都想返回true。 遗憾的是,两个地图上的键都不是ID,因此不能用于此操作。要获取ID,我需要钻取值并调用getId()。由于这是一种测试方法,因此我不想使用具有所有id的addicional集合来污染类。 是否有一种简单的方法可以同时查看所有3个集合并在1个发现结果后立即停止?

1 个答案:

答案 0 :(得分:2)

同时

可能会比顺序运行慢,因此您的代码IMO就可以了。可以稍作改进:

return 
   yankeSquare.values()
              .stream()
              .flatMap(Set::stream)
              .map(Square::getId)
              .anyMatch(Predicate.isEqual(squareId)) ||

   xraySquare.stream()
             .map(Square::getId)
             .anyMatch(Predicate.isEqual(squareId)) ||

   zuluSquare.values()
              .stream()
              .flatMap(Set::stream)
              .map(Square::getId)
              .anyMatch(Predicate.isEqual(squareId))

或更简单,但不像代码中那样懒:

  Stream.concat(xraySquare.stream(), 
                Stream.of(yankeSquare, zuloSquare)
                      .flatMap(map -> map.values().stream().flatMap(Set::stream))
        .map(Square::getId)
        .anyMatch(Predicate.isEqual(squareId))
  )

基本上,它将所有收藏集展平为Stream<String>,并使用anyMatch进行对比