【问题标题】:Constructor as higher-order function构造函数作为高阶函数
【发布时间】:2022-07-15 19:59:21
【问题描述】:

我面临的问题是我想从 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 的类型。

【问题讨论】:

  • Stream::map 不是这样工作的。 Stream::map每个 流元素上一个接一个地执行映射器。
  • 阅读文档! Java 开发人员编写它是有原因的
  • @Turing85 但我不想一个一个。我想应用 4 个元素。这就是问题
  • @one1on 我知道。这就是为什么我说这不是Stream::map 的工作方式。 Streams 处理单个元素。一些终端操作(如Collectors.toMap(...))使用一些状态信息。但总的来说,流应该是无状态的。而且“将 x 个元素组合在一起”并不是无状态的。

标签: java stream higher-order-functions


【解决方案1】:

你的想法接近 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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-07
    相关资源
    最近更新 更多