You can apply filter()
with a nested stream (exactly the same as you've used as a condition in your code) passed to it as a Predicate
to verify that a list consists of only non-empty tiles.
And then collect all the lists (rows) that have passed the predicate into a List using 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+
}
I have tried using flatMap
You need to use flatMap
when your goal is to flatten the steam of collections (or objects holding a reference to a collection) to a stream of elements of these collections. In these case, turn a stream of lists of tiles Stream<List<Tile>>
into a stream of tiles Stream<Tile>
.
Judging by your code, it's not you what you want because you're accumulating the rows (lists of tiles) into another list and not "flattening" them.
But just in case, that's how it can be done:
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+
}
Sidenote: leverage abstract data types - write your code against interfaces. What does it mean to "program to an interface"?