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

帮助理解Java中的函数对象或函子

汪信鸥
2023-03-14
问题内容

有人可以解释函子是什么,并提供一个简单的例子吗?


问题答案:

函数对象就是这样。既是对象又是功能的东西。

另外:将函数对象称为“函子”是对术语的严重滥用:另一种“函子”是数学的中心概念,并且在计算机科学中具有直接作用(请参阅“
Haskell函子”)。该术语在ML中的使用也略有不同,因此,除非您正在Java中实现这些概念之一(可以!),否则请停止使用此术语。它使简单的事情变得复杂。

返回答案:Java没有“一流的函数”,也就是说,您不能将函数作为参数传递给函数。从语法上讲,这在字节代码表示的多个级别上都适用,并且类型系统缺少“函数构造函数”

换句话说,您不能这样写:

 public static void tentimes(Function f){
    for(int i = 0; i < 10; i++)
       f();
 }
 ...
 public static void main{
    ...
    tentimes(System.out.println("hello"));
    ...
 }

这确实很烦人,因为我们希望能够做一些事情,例如拥有图形用户界面库,您可以在其中将“回调”功能与单击按钮相关联。

那么我们该怎么办?

好吧,一般的解决方案(由其他发布者讨论)是用一个我们可以调用的方法定义一个接口。例如,Java一直在使用Runnable用于此类事情的接口,它看起来像:

public interface Runnable{
    public void run();
}

现在,我们可以从上面重写我的示例:

public static void tentimes(Runnable r){
    for(int i = 0; i < 10; i++)
       r.run();
}
...
public class PrintHello implements Runnable{
    public void run{
       System.out.println("hello")
    }
}
---
public static void main{
    ...
    tentimes(new PrintHello());
    ...
 }

显然,这个例子是人为的。我们可以使用匿名内部类使此代码更好一些,但这可以理解。

Here is where this breaks down: Runnable is only usable for functions that
don’t take any arguments, and don’t return anything useful, so you end up
defining a new interface for each job. For example, the interface Comparator
in Mohammad Faisal’s answer. Providing a more general approach, and one that
takes syntax, is a major goal for Java 8 (The next version of Java), and was
heavily pushed to be included in Java 7. This is called a “lambda” after the
function abstraction mechanism in the Lambda Calculus. Lambda Calculus is both
(perhaps) the oldest programming language, and the theoretical basis of much
of Computer Science. When Alonzo Church (one of the main founders of computer
science) invented it, he used the Greek letter lambda for functions, hence the
name.

其他语言,包括功能语言(Lisp,ML,Haskell,Erlang等),大多数主要动态语言(Python,Ruby,JavaScript等)和其他应用程序语言(C#,Scala,Go,D等)支持某种形式的“
Lambda文字”。甚至C 现在都拥有它们(自C 11起),尽管在这种情况下它们会更加复杂,因为C
++缺乏自动内存管理功能,并且不会为您保存堆栈框架。



 类似资料:
  • 问题内容: 我希望有人可以帮助我解决我遇到的问题。我有大量的元组(> 500),看起来像这样: 我的代码片段显示为: 我意识到上面的代码是不正确的。我正在尝试找到一种方法,使用zip函数将所有A值,B的所有值,C的所有值以及D的所有值相加。例如,我要打印如下内容: 忙吗?非常感谢你花时间陪伴。 问题答案: 为此,使用任意大的元组集: 旁注:在python3中,请注意zip返回一个懒惰的可迭代对象,

  • 问题内容: 我正在尝试编写一个PHP函数。这很简单。这只是一个查询数据库的准备好的语句,但是我无法使它正常工作。我一直收到非对象上的错误消息,调用成员函数prepare()。这是代码: 每当我调用该函数时,都会收到该错误。有人可以帮忙吗? 问题答案: 这是一个范围错误。您正在创建一个全局变量。因此,当您输入函数时,全局变量不可用。您有5个真实选择。 1.使用全局关键字 这不是一个好主意,因为它使维

  • 本文向大家介绍详解JavaScript中的函数、对象,包括了详解JavaScript中的函数、对象的使用技巧和注意事项,需要的朋友参考一下 JS中的函数声明方式 方式一 function 函数名(){ 函数体 } 方式二 var 函数名=function(){ 函数体 } 方式三 var 函数名=new Function(“函数体”); 执行方式 函数名(); JS中的对象 类似Java中的一些系

  • 我很难理解以下函数的递归工作流程,以及它如何遍历排列排序数组。 让我感到困惑的一件特别的事情是“返回[nums[:]]”调用在递归函数中的行为。由于第9行再次调用自己,直到“start==2”,它什么时候继续执行第9行之后的行,以及它为哪个递归函数执行这些继续行? 抱歉,如果我的问题有点让人困惑,我最近才开始学习Python,希望更好地了解“return”调用在递归函数中的工作方式。任何建议都将不

  • 本文向大家介绍详解JavaScript函数对象,包括了详解JavaScript函数对象的使用技巧和注意事项,需要的朋友参考一下 函数 函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块。 注释:   形参不需要加上类型;   return语句为可选,没有return语句的函数返回undefined;  局部变量与全局变量   在函数内声明:局部变量   在函数外声明:全局变量   向一个新