Java流式高阶函数

时间:2019-03-18 16:32:34

标签: java functional-programming java-stream

我正在尝试处理一个嵌套了2级深度的对象。例如,我的对象可以分解为以下形式:

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

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

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

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对象列表。

对此有任何解决方案吗?还是我不太想在功能上解决它?有没有办法既可以应用功能,又可以访问应用于该功能的原始对象?

2 个答案:

答案 0 :(得分:6)

#settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'api', ] #serializers.py from rest_framework import serializers #<---- this line is giving me error from .models import Plans class PlansSerializer(serializers.ModelSerializer): """Serializer to map the Model instance into JSON format.""" class Meta: """Meta class to map serializer's fields with the model fields.""" model = Plans fields = ('id', 'name', 'date_created', 'date_modified') read_only_fields = ('date_created', 'date_modified') 和嵌套是必经之路。试试这个:

certifi==2018.11.29
Django==2.1.7
django-crispy-forms==1.7.2
django-filter==2.1.0
django-markdown==0.8.4
django-markdown2==0.3.1
django-pagedown==1.0.6
djangorestframework==3.9.2
djangorestframework-simplejwt==4.1.0
Markdown==3.0.1
markdown2==2.3.7
olefile==0.46
Pillow==5.4.1
Pygments==2.3.1
PyJWT==1.7.1
pytz==2018.9

通过这样的嵌套,您仍然可以访问外部函数中的元素,并且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()所调用的流暴露给{{1} }。

答案 1 :(得分:1)

您可以简单地将flatMap用作:

List<SomeObj> objs = topLevel.getMidLevels().stream()
        .flatMap(a -> a.getLowLevels().stream().map(b -> topBuilder.apply(a).apply(b)))
        .collect(Collectors.toList());

您的实体类似于:

class TopLevel {
    List<MidLevel> midLevels;
}

class MidLevel {
    List<LowLevel> lowLevels;
}

class LowLevel {
}

class SomeObj {
}