【问题标题】:Looking for "consumer that returns value" abstraction in Java在 Java 中寻找“返回价值的消费者”抽象
【发布时间】:2019-07-30 08:13:54
【问题描述】:

在 Java 8+ 中是否存在用于返回值的消费者的内置或健壮的第三方抽象?

P.S. 对于延迟执行,它也可能返回 Future

Update. Function 接口具有完美的句法匹配,但需要考虑语义。在这种情况下使用 Function 显然会破坏 don't change external state 的约定。怎么处理?

【问题讨论】:

  • 你的意思是一个函数?
  • 您可以使用 Function 来使用其参数并返回您需要的任何值。
  • 对于延迟版本,这将是 Function<T, CompletableFuture<R>>。然后,您可以将这些东西组合/链接在一起。如果一个特定的实现实际上不需要延迟,它可以返回一个已经完成的未来和结果。
  • Java 类型系统中没有任何东西可以阻止代码“改变外部状态”。您必须自己查看 Function 实现及其文档。我想你可以找到一个“效果系统”(比如 Scala ZIO),但这些在 Javaland 中非常奇特(甚至它们也不能真正强制执行功能纯度)。

标签: java producer-consumer abstraction functional-interface


【解决方案1】:

您可能正在寻找Function<T, R>-interface。它是通用的,接受一个参数,同时返回一个值。它可以用于 lambda 表达式,例如映射:

Integer input = 1;
Function<Integer, Integer> myMapping = a -> a * 2;
Integer myInt = myMapping.apply(input);
// myInt == 2

看一下java util.function包:https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html

有许多不同的预定义功能接口。 @FunctionalInterface 是标记此类接口的注释,这些接口肯定只有一个非默认方法。此类接口可用于 lambda 表达式。

这里有一些顶级候选人:

  • 消费者:接受一个参数,返回 void。
  • 功能:取一个参数,返回一个值。
  • 供应商:什么都不拿,返回一个值。
  • 谓词:接受一个参数并返回一个布尔值。

及其各种派生词。

所有这些都可以存储为“值”,以便以后执行。从某种意义上说,如果需要,它们可以成为回调。

编辑: 因为 Function 预计不会改变其执行的外部状态,所以一些 API 应用程序似乎很棘手。但是,如果您打算以这种方式使用函数,您可以定义一个参数类,它基本上是所有期望更改的值的包装器。如果它们中的任何一个在执行期间发生更改,则外部状态会根据这些更改进行更新。然而,这似乎更像是一种模式,而不是简单的一类/接口语言功能。我以前甚至在 lambda 表达式之前使用过参数类,如果正确描述了正确的 javadocs,它会很好地工作。

【讨论】:

  • 我确实看到了您的更新,并会询问您指定的确切含义。哪个接口的合约要求不改变外部状态?另外:函数不能通过返回值或修改对象来改变外部状态。永远不能阻止函数,例如,修改参数Collection 或数组,除非您传递不可修改的Collection。你根本无法在技术上阻止它。但是,它应该通过合同加以阻止。请问您的用例到底是什么?这将有助于回答您的基本问题。
  • 对于 PredicateFunction 更改外部状态没有技术限制。但这样做似乎违反了最佳实践,并可能造成线程安全问题,并可能导致内存泄漏。另一方面,Consumer 预计会改变状态。所以我更关心的是编写良好和健壮代码的良好实践,而不是语言的技术限制。
  • 哦,我明白了。您的用例需要输入和输出,但您需要 更改外部状态(或明确允许)并希望表明这一点?在这种情况下,您可以使用明确允许(并且预期)修改外部状态的接口扩展Function 接口。你可以称它为VolatileFunction 或类似的名称。更多内容在我的编辑中。
猜你喜欢
  • 2022-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多