如何从 java 8 中的双重嵌套映射中收集对象?
How to collect objects from a doubly nested map in java 8?
我打算在我的程序中利用并行流的好处,我想像这样替换循环:
for (int gridY = gridYFrom; gridY <= gridYTo; gridY++) {
for (int gridX = gridXFrom; gridX <= gridXTo; gridX++) {
coordinates.add(Coordinate.from(gridX, gridY));
}
}
像这样:
IntStream.rangeClosed(gridYFrom, gridYTo).parallel().map(y ->
IntStream.rangeClosed(gridXFrom, gridXTo).mapToObj(x -> {
return Coordinate.from(x, y);
}
)).collect(Collectors.toSet());
我的问题是这里出现 cyclic inference
错误。我知道我应该从内部地图 return 一个 int
与外部地图兼容,但我想 return 一个 Coordinate
对象(因此 mapToObj
呼叫)。是否可以使用 collect
而不使用 forEach
结构来做到这一点?
你要做的是这些:
首先,当你在 IntStream
上调用 map
时,它仍然是 returns 一个 IntStream
,这不是你想要的。相反,外循环也使用 mapToObj
。
其次,内部循环 returns 是一个不完整的 Stream<Coordinate>
,我认为这也不是您想要的。因此,您也需要为此调用 .collect(Collectors.toSet())
。
最后,您需要 flatMap
将 Stream<Set<Coordinate>>
合并为一个 Stream<Coordinate>
,您可以使用
stream.flatmap(Set::stream);
这一切归结为
IntStream.rangeClosed(0, 10).parallel().mapToObj(y ->
IntStream.rangeClosed(0, 20).mapToObj(x ->
Coordinate.from(x,y)).collect(Collectors.toSet())
).flatMap(Set::stream).collect(Collectors.toSet());
编辑:
其实,忘了里面的collect
。只是 flatmap
到 Stream::sequential
.
你最终会得到
IntStream.rangeClosed(0, 10).parallel().mapToObj(y ->
IntStream.rangeClosed(0, 20).mapToObj(x ->
Coordinate.from(x, y))).flatMap(Stream::sequential).collect(Collectors.toSet())
您不需要收集两次。
不幸的是,问题是 IntStream
与 java 中的任何其他流都不一样。因此,您必须先将其转换为普通流,然后才能执行 flatMap
:
IntStream.rangeClosed(gridYFrom, gridYTo)
.mapToObj( y -> Integer.valueOf(y) )
.flatMap( y ->
IntStream.rangeClosed(gridXFrom, gridXTo)
.mapToObj(x -> Coordinate.from(x,y))
)
.collect(Collectors.toSet())
我打算在我的程序中利用并行流的好处,我想像这样替换循环:
for (int gridY = gridYFrom; gridY <= gridYTo; gridY++) {
for (int gridX = gridXFrom; gridX <= gridXTo; gridX++) {
coordinates.add(Coordinate.from(gridX, gridY));
}
}
像这样:
IntStream.rangeClosed(gridYFrom, gridYTo).parallel().map(y ->
IntStream.rangeClosed(gridXFrom, gridXTo).mapToObj(x -> {
return Coordinate.from(x, y);
}
)).collect(Collectors.toSet());
我的问题是这里出现 cyclic inference
错误。我知道我应该从内部地图 return 一个 int
与外部地图兼容,但我想 return 一个 Coordinate
对象(因此 mapToObj
呼叫)。是否可以使用 collect
而不使用 forEach
结构来做到这一点?
你要做的是这些:
首先,当你在 IntStream
上调用 map
时,它仍然是 returns 一个 IntStream
,这不是你想要的。相反,外循环也使用 mapToObj
。
其次,内部循环 returns 是一个不完整的 Stream<Coordinate>
,我认为这也不是您想要的。因此,您也需要为此调用 .collect(Collectors.toSet())
。
最后,您需要 flatMap
将 Stream<Set<Coordinate>>
合并为一个 Stream<Coordinate>
,您可以使用
stream.flatmap(Set::stream);
这一切归结为
IntStream.rangeClosed(0, 10).parallel().mapToObj(y ->
IntStream.rangeClosed(0, 20).mapToObj(x ->
Coordinate.from(x,y)).collect(Collectors.toSet())
).flatMap(Set::stream).collect(Collectors.toSet());
编辑:
其实,忘了里面的collect
。只是 flatmap
到 Stream::sequential
.
你最终会得到
IntStream.rangeClosed(0, 10).parallel().mapToObj(y ->
IntStream.rangeClosed(0, 20).mapToObj(x ->
Coordinate.from(x, y))).flatMap(Stream::sequential).collect(Collectors.toSet())
您不需要收集两次。
不幸的是,问题是 IntStream
与 java 中的任何其他流都不一样。因此,您必须先将其转换为普通流,然后才能执行 flatMap
:
IntStream.rangeClosed(gridYFrom, gridYTo)
.mapToObj( y -> Integer.valueOf(y) )
.flatMap( y ->
IntStream.rangeClosed(gridXFrom, gridXTo)
.mapToObj(x -> Coordinate.from(x,y))
)
.collect(Collectors.toSet())