如何使用 Stream 从与特定条件匹配的嵌套列表中获取所有列表?

How to use Stream to get all Lists from a nested List that match a specific condition?

提问人:camelCase 提问时间:7/19/2022 最后编辑:Alexander IvanchenkocamelCase 更新时间:7/19/2022 访问量:1098

问:

如何仅使用 Streams 在代码中实现相同的逻辑,而不使用下面的代码所示的循环?for

我试过使用 ,但我卡在条件部分,因为只返回一个 .flatMapallMatch()boolean

如何在不使用循环的情况下从传递条件的嵌套中检索所有行?ArrayListfor

ArrayList<ArrayList<Tile>> completeRows = new ArrayList<>();
for (ArrayList<Tile> rows: getGridTiles()) {
    if (rows.stream().allMatch(p -> p.getOccupiedBlockType() != BlockType.EMPTY)) {
        completeRows.add(rows);
    }
}
Java 列表 java-stream 嵌套列表

评论


答:

2赞 Alexander Ivanchenko 7/19/2022 #1

可以使用将嵌套流(与代码中用作条件的流完全相同)作为 传递给它来应用,以验证列表是否仅包含非空磁贴。filter()Predicate

然后使用 收集所有已将谓词传递到 List 中的列表()。collect()

public static List<List<Tile>> getNonEmptyRows(List<List<Tile>> rows) {
    
    return rows.stream()
        .filter(row -> row.stream().allMatch(tile -> tile.getOccupiedBlockType() != BlockType.EMPTY))
        .collect(Collectors.toList()); // or .toList() with Java 16+
}

我试过使用flatMap

当您的目标是将集合(或包含对集合的引用的对象)的蒸汽展平到这些集合的元素流时,您需要使用。在这些情况下,将切片列表流转换为切片流。flatMapStream<List<Tile>>Stream<Tile>

从你的代码来看,这不是你想要的,因为你正在将(磁贴列表)累积到另一个列表中,而不是“展平”它们。

但以防万一,这就是可以做到的:

public static List<Tile> getNonEmptyTiles(List<List<Tile>> rows) {
    
    return rows.stream()
        .filter(row -> row.stream().allMatch(tile -> tile.getOccupiedBlockType() != BlockType.EMPTY))
        .flatMap(List::stream)
        .collect(Collectors.toList()); // or .toList() with Java 16+
}

旁注:利用抽象数据类型 - 针对接口编写代码。“编程到接口”是什么意思?