Java流式高阶函数

wea*_*bob 4 java functional-programming java-stream

我正在尝试处理具有嵌套列表深2级的对象。例如,我的对象可以分解为以下形式:

TopLevel: [
    MidLevel: [
        LowLevel,
        LowLevel,
        .
        .
    ],
    MidLevel: [
        LowLevel,
        LowLevel,
        .
        .
    ]
    .
    .
]
Run Code Online (Sandbox Code Playgroud)

本质上TopLevel包含一个MidLevel对象列表,而每个对象又包含一个LowLevel对象列表。在处理结束时,我想SomeObj为每个LowLevel对象构建一个。然而SomeObj,需要从信息TopLevelMidLevelLowLevel

在过去的几个月中,我一直在尝试以更具功能性的风格编写代码,因此我的第一个想法是创建一个可以在对象的每个级别上构建的更高阶函数。该函数如下所示:

Function<MidLevel, Function<LowLevel, SomeObj>> buildObjects(TopLevel topLevel) {
    return midLevel ->
        lowLevel -> {
            return buildSomeObj(topLevel, midLevel, lowLevel);
        };
}
Run Code Online (Sandbox Code Playgroud)

我打算以类似以下方式的方式使用此功能(假设我有提供列表流的实用程序功能):

Function<MidLevel, Function<LowLevel, SomeObj>> topBuilder = buildObjects(topLevel);
List<SomeObj> objs = topLevel.streamMid()
    .map(topBuilder)
    .streamLow()
    .map(Function::apply)
    .collect(/*collect to list*/);
Run Code Online (Sandbox Code Playgroud)

但是,这显然不起作用,因为一旦将MidLevel对象应用于topBuilder函数后,我的流现在是函数流,而不是MidLevel对象流,因此我再也无法访问LowLevel该流中的对象列表。

有什么解决办法吗?还是我不太想在功能上解决这个问题?有没有办法既可以应用功能,又可以访问应用于该功能的原始对象?

Tho*_*mas 6

flatMap()和嵌套是要走的路。尝试这个:

topLevelStream() //create a stream of top level elements
  .flatMap( top -> top.streamMid() //create a stream of mid level elements
    .flatMap( mid -> mid.streamLow() //create a stream of low level elements
      .map(low -> "use top, mid and low here") 
    ) 
  )
  .collect( ... );
Run Code Online (Sandbox Code Playgroud)

通过这样嵌套,您仍然可以访问外部函数中的元素以及的组合,flatMap()map()公开map()被调用的流collect()

  • 如果我正确地理解了这个问题,那么就没有顶级流了,因此一个“ flatMap”就可以做到这一点。 (2认同)