Java 映射流中的单个元素<;收藏<;T>&燃气轮机;

Java 映射流中的单个元素<;收藏<;T>&燃气轮机;,java,collections,java-stream,Java,Collections,Java Stream,在使用流时,我希望将Java8流API中的常用方法应用于流中每个集合中类型为T的每个元素。正如标题所述,我主要想映射元素,但当然所有其他方法(例如filter(Predicate)或allMatch(Predicate))也都很有趣 考虑一个2D板存储多个矩形瓷砖的示例。每个磁贴由其在电路板上的(x,y)位置定义 List<Position> tile1 = Lists.asList(tile1Pos1, tile1Pos2, ...) List<Position> ti

在使用
流时,我希望将Java8流API中的常用方法应用于流中每个集合中类型为T的每个元素。正如标题所述,我主要想映射元素,但当然所有其他方法(例如
filter(Predicate)
allMatch(Predicate)
)也都很有趣

考虑一个2D板存储多个矩形瓷砖的示例。每个磁贴由其在电路板上的(x,y)位置定义

List<Position> tile1 = Lists.asList(tile1Pos1, tile1Pos2, ...)
List<Position> tile2 = Lists.asList(tile2Pos1, tile2Pos2, ...)
...
List<List<Position>> board = Lists.asList(tile1, tile2, ...)
List tile1=Lists.asList(tile1Pos1,tile1Pos2,…)
List tile2=Lists.asList(tile2Pos1,tile2Pos2,…)
...
列表板=列表.asList(tile1,tile2,…)
旋转电路板时,我想转换瓷砖的所有位置。我需要对每个位置应用相同的x到y和y到x映射函数。但是,我必须保留瓷砖与其各自位置之间的关联

目前,我正在使用我的
收集流

List<List<Position>> rotatedBoard = board.stream().map(tile -> tile.stream().map(Position::mapperFunctionRotate).collect(toList())).collect(toList());
List rotatedBoard=board.stream().map(tile->tile.stream().map(Position::mapprovancerotate).collect(toList()).collect(toList());
请注意,我保留了数据的原始布局。每个位置仍然与它所属的一个特定磁贴相关联

概括而言,对于任何
,我希望修改类型T的所有单个元素,同时将它们保留在它们的集合中。 理想情况下,我希望能够单独执行
board.stream().map(Position::mapperFunctionRotate)
,它与Java stream API中的
flatMap
具有类似的方法签名,但不会展平我的列表流

有什么方便的方法来简化上述映射功能吗?

我也在寻找能完成这项工作的库或框架。在我看来,JavaAPI不支持这样的东西,我认为其他库实际上是这个问题的主要范围


我已经看过guava,它提供了类似于
Multimap
的数据结构,其行为类似于
Map
,但我没有找到Java Stream API的扩展。

您不是在这里寻找flatmap吗

 .stream().flatMap(Collection::stream).collect(Collectors.toList());

不清楚你的目标是什么。您显示的解决方案已经是规范解决方案。如果要重复执行类似的操作,可以将其抽象为一个方法:

public static <T,R> List<List<R>> applyToAll(
    Collection<? extends Collection<? extends T>> source,
    Function<? super T, ? extends R> op) {

    return source.stream()
        .map(c -> c.stream().map(op).collect(Collectors.toList()))
        .collect(Collectors.toList());
}

我不这么认为,因为
flatMap(t::maptoo)
没有保留我的集合结构。毕竟,我不想要所有元素的列表,而是将它们分组到单独的子列表中。@1Darco1是的,我已经重读了问题,您想保留初始布局吗。Sill不能简单地说出您想要什么?您可以修改
mapperFunctionRotate
以接受
集合
。您查看了吗?@谢谢,我现在已经查看了它提供的功能。这个问题的目的可以通过
EntryStream
来实现,但该解决方案不会比普通Java更短,也不会更具可读性。事实上,必须为每个集合分配一个键(最有可能是整数),然后创建“平面”入口流。不同之处在于,与普通集合相反,每个值都有一个关联的键,指定它是前一个集合的一部分。然后,我的映射函数可以应用于每个值,保持键不变。最后,转换回来。当使用需要每个键有多个值的map-like数据时,
map
也是实现这一点的标准方法。然而,guava已经创建了一个更简单的解决方案,它可以产生更可读的代码,并且比普通Java解决方案效率更高。因此,我认为可能已经存在一个库,以类似的方式扩展Java Streams API。但显然没有。非常感谢
mapAll()
方法!我更喜欢像
board.stream().map(mapAll(Position::mapprovancerotate)).collect(toList())
那样使用它。
List<List<Position>> rotatedBoard = applyToAll(board, Position::mapperFunctionRotate);
public static <T,R> List<R> mapAll(
    Collection<T> source, Function<? super T, ? extends R> op) {
    return source.stream().map(op).collect(Collectors.toList());
}
List<List<Position>> rotatedBoard
    = mapAll(board, l -> mapAll(l, Position::mapperFunctionRotate));
public static <T,R,C extends Collection<T>>
    Function<C, List<R>> mapAll(Function<? super T, ? extends R> op) {
    return source -> source.stream().map(op).collect(Collectors.toList());
}
Function<List<List<Position>>,List<List<Position>>> f
    = mapAll(mapAll(Position::mapperFunctionRotate));
List<List<Position>> rotatedBoard = f.apply(board);
List<List<Position>> rotatedBoard = mapAll(board, mapAll(Position::mapperFunctionRotate));