当前位置: 首页 > 面试题库 >

Java 8:java.util.function中的TriFunction(和亲属)在哪里?还是有什么选择?

洪俊能
2023-03-14
问题内容

我看到了java.util.function.BiFunction,所以我可以这样做:

BiFunction<Integer, Integer, Integer> f = (x, y) -> { return 0; };

如果那还不够好并且我需要TriFunction怎么办?它不存在!

TriFunction<Integer, Integer, Integer, Integer> f = (x, y, z) -> { return 0; };

我想我应该补充一点,我知道我可以定义自己的TriFunction,我只是想了解不将其包含在标准库中的原因。


问题答案:

据我所知,只有两种功能,破坏性的和建设性的。

顾名思义,建设性功能可以构造某些东西,而破坏性功能可以破坏某些东西,但是不会像您现在想的那样。

例如功能

Function<Integer,Integer> f = (x,y) -> x + y

建设性的 。如您需要构造的东西。在示例中,构造了元组 (x,y)
。构造函数具有无法处理无限参数的问题。但最糟糕的是,您不能只留下一个争论。您不能只说“好吧,让x:= 1”并尝试每个可能尝试的y。您必须每次使用构造整个元组
x := 1。因此,如果您想查看函数返回的内容,y := 1, y := 2, y := 3则必须编写f(1,1) , f(1,2) , f(1,3)

在Java
8中,应该使用方法引用来处理构造函数(大部分时间),因为使用构造性lambda函数没有太多优势。它们有点像静态方法。您可以使用它们,但是它们没有真实状态。

另一种是破坏性的,需要采取一些措施并根据需要将其拆除。例如, 破坏性 功能

Function<Integer, Function<Integer, Integer>> g = x -> (y -> x + y)

与具有f建设性的功能相同。破坏性函数的好处是,您现在可以处理无限个参数,这对于流来说特别方便,并且您可以仅打开参数。因此,如果您再次想查看if x := 1和if的结果y := 1 , y := 2 , y := 3,您可以说h = g(1)and h(1)是for y := 1h(2)for y := 2h(3)for 的结果y := 3

所以这里您有一个固定的状态!这是非常动态的,并且在大多数情况下是我们从lambda中想要的。

如果您只需放入一个可以为您完成工作的函数,那么像Factory这样的模式就容易得多。

破坏性元素很容易彼此结合。如果类型正确,则可以根据需要进行组合。使用它,您可以轻松定义使(具有不变的值)测试变得容易得多的态射!

您也可以用一个建设性的结构来做到这一点,但是破坏性的结构看起来更好,更像是列表或装饰器,而建设性的结构看起来很像一棵树。带有构造函数的回溯之类的事情就不好了。您可以只保存破坏性函数的部分功能(动态编程),而在“回溯”中仅使用旧的破坏性功能。这使代码更小,更易读。使用构造函数,您或多或少会记住所有参数,这可能很多。

那么,为什么需要BiFunction更多的问题而不是为什么没有问题TriFunction呢?

首先,很多时候您只有几个值(小于3)并且只需要一个结果,因此根本不需要常规的破坏函数,而建设性函数就可以了。诸如monad之类的东西确实需要构造功能。但是除此之外,实际上并没有很多充分的理由说明为什么会有一个BiFunction。这并不意味着应该将其删除!我为我的Monad战斗,直到我死!

因此,如果您有很多参数,不能将它们组合到一个逻辑容器类中,并且您需要函数具有构造性,请使用方法引用。否则,尝试使用新获得的破坏性功能,您可能会发现自己用更少的代码行来做很多事情。



 类似资料:
  • 问题内容: Angularjs中angular.bind的用途是什么。请提供一个例子。无法从https://docs.angularjs.org/api/ng/function/angular.bind了解 问题答案: Angular.bind是一种实用功能,它结合了function.bind和部分功能应用程序中的功能。 绑定 (通常)是您想将当前上下文绑定到函数,但实际上在以后执行的想法。 在进

  • 在Java8中,可以返回而不是。Java8文档说,可选的是“一个容器对象,它可以包含非空值,也可以不包含非空值。如果存在一个值,isPresent()将返回true,而get()将返回该值。” 在实践中,这为什么有用呢?另外,有没有使用作为首选项的情况?那表演呢?

  • 问题内容: 在sql关系中,父级是什么,子级是什么? 就我而言,我有一个零件(说螺丝)和产品材料。出于争论的考虑,一种产品材料(例如钢)只能属于一个零件(但不能属于现实世界)。所以这是1:n。该零件的pk将在ProductMaterial表中以fk表示。 在这种情况下,哪个是父母,哪个是孩子? 问题答案: 您可以通过以下方式解释数据库中的1:n关系:子代始终是该模型,该模型保存着外键,因为它表明了

  • 问题内容: 我对java8流中和方法之间的区别感到困惑。例如, 我得到空的输出在这里,但如果我改变地图就像 我可以得到 {1 = 1,2 = 2} 为什么只是没有运行方法?它们之间有什么区别? 问题答案: 什么都不做,因为在执行终端操作之前不会处理流管道。因此,残留物为空。 在流管道中添加终端操作将导致针对终端操作所需的每个元素执行操作(某些终端操作仅需要一个元素,而其他终端操作则需要的所有元素)

  • 问题内容: 本机方法与抽象方法具有相同的语法,但是在哪里实现呢? 问题答案: Java中的本机方法是什么,应在哪里使用? 一旦看到一个小例子,就很清楚了: Main.java : Main.c : 编译并运行 : 输出 : 在Ubuntu 14.04上使用Oracle JDK 1.8.0_45进行了测试。 因此很明显,它允许您执行以下操作: 使用Java中的任意汇编代码调用经过编译的动态加载的库(

  • 问题内容: 我知道方法的局部变量和参数驻留在堆栈中,但是我无法弄清楚在Java情况下方法实际上在哪里? 如果我声明任何Thread对象,例如: 因此,这意味着除了主方法之外,我还创建了一个单独的方法调用。这是什么意思?这是否意味着在堆栈内存上调用单独的方法序列?我对吗? 问题答案: 每个线程都分配有自己的堆栈。 本文对Java进程中的内存分离进行了很好的介绍。 在Java虚拟机内部,每个线程都被授