首页 > 解决方案 > Java流高阶函数

问题描述

我正在尝试处理具有 2 层深度的嵌套列表的对象。例如我的对象可以分解成这样的:

TopLevel: [
    MidLevel: [
        LowLevel,
        LowLevel,
        .
        .
    ],
    MidLevel: [
        LowLevel,
        LowLevel,
        .
        .
    ]
    .
    .
]

本质上TopLevel包含一个对象列表,MidLevel每个对象又包含一个LowLevel对象列表。在处理结束时,我想SomeObj为每个LowLevel对象构建。但是SomeObj需要来自TopLevelMidLevel和的信息LowLevel

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

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

我打算以如下方式使用这个函数(假设我有提供列表流的实用函数):

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

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

有什么解决方案吗?或者当它不太适合它时,我是否试图在功能上解决这个问题?有没有办法既应用该函数,又可以访问应用于该函数的原始对象?

标签: javafunctional-programmingjava-stream

解决方案


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( ... );

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


推荐阅读