使用四参数构造函数将四个元素的流映射到一个对象

问题描述 投票:0回答:1

我面临的问题是我想从 Stream 4 元素映射到记录数据的构造函数:

record Data(String firstname, String middlename, String lastname, String zip) {}

Function4<String, String, String, String, Data> constructor = Data::new;
List<Data> data = Stream.of("chris", "p", "bacon", "black")
                .map(constructor)
                .collect(Collectors.toList())

我找到了一个匹配的高阶函数(来自vavr的

Function4
)来描述这个至少有4个参数的构造函数。但我不知道在这种情况下如何使用它。

旁注:我试图避免的是构建 4 个元素的

Collection
并且必须“手动”传递它们。:

    List<Data> datas = rowData.stream()
                .map(row -> new Data(row.get(0), row.get(1), row.get(2), row.get(3))).toList();

我认为这不能在 Java 中完成,因为在流中的某个时刻我必须构造一个参数数量为 4 的类型。

java java-stream higher-order-functions
1个回答
0
投票

你的想法接近Applicative Functor,它已经在任何monadic库中实现,vavr也实现了它但有一个限制:你最多可以有8个arities。要解决您的问题,您必须按照以下步骤操作:

  • 将每个参数提升到 Monadic 世界。
  • 使用 Applicative Functor 完成剩下的工作
        // Validation is a monad, you lift your param here
        Validation<String,String> firstname = Validation.valid("chris");
        Validation<String,String> middlename = Validation.valid("p");
        Validation<String,String> lastname = Validation.valid("lastname");
        Validation<String,String> zip = Validation.valid("zip");

        // Here is the limitation of vavr, only Validation implement applicative functor so you can only Validation class
        // to combine four field to Data object. Beside you have to handle the error -> all the error is collected in 
        // the left side Seq<String>
        Validation<Seq<String>, Data> result = Validation.combine(firstname, middlename, lastname, zip).ap(Data::new);
© www.soinside.com 2019 - 2024. All rights reserved.