我能否在Java 8中将Clojure函数用作Lambdas?

mik*_*era 13 java lambda functional-programming clojure java-8

我在Clojure中使用了许多库,它们生成符合" clojure.lang.IFn "接口的更高阶函数.

它有多个arity重载,即接口看起来像:

public interface IFn extends Callable, Runnable{
  public Object invoke() ;
  public Object invoke(Object arg1) ;
  public Object invoke(Object arg1, Object arg2) ;
  public Object invoke(Object arg1, Object arg2, Object arg3) ;
  .... etc.
  public Object applyTo(ISeq arglist) ;
}
Run Code Online (Sandbox Code Playgroud)

我能否在Java 8中直接使用这种类型的对象作为可调用的lambda函数?

Vla*_*eev 7

你是什​​么意思,使用这种类型的对象作为可调用的lambdas?

非常简单的情况下,Java 8 lambdas 可以被认为是语法糖+某些类型接口的匿名类的某种类型推断,即功能接口 [1]:

上面使用的接口ActionListener只有一个方法.许多常见的回调接口都具有此属性,例如Runnable和Comparator.我们将为只有一个方法的所有接口命名:功能接口.

备注:lambdas真的不仅仅是糖; 在内部,它们的实现方式与匿名类不同,并且还存在一些语义差异; 有关此问题的更多信息,请参阅ProgrammersExchange上的这个优秀答案.但是,在这个问题和答案的背景下,这并不重要.

在需要某些功能接口的值的任何地方(方法参数,局部变量,字段声明等),可以使用短语法来创建实现此方法的匿名类的实体,即lambda表达式:

Runnable r = () -> {
    System.out.println("Hi");
};
// Equivalent to
Runnable r = new Runnable() {
    public void run() {
        System.out.println("Hi");
    }
};

public interface Function<F, T> {
    T call(F arg);
}

Function<String, char[]> c = s -> ("<" + s + ">").toCharArray();
// Equivalent to
Function<String, char[]> c = new Function<>() {
    public char[] call(String s) {
        return ("<" + s + ">").toCharArray();
    }
};
Run Code Online (Sandbox Code Playgroud)

所以你的问题只能用以下方式解释:是否可以IFn使用Java 8 lambda语法创建类型的对象?

答案是不.只有功能接口才能使用Lambda语法.clojure.lang.IFn不是一个功能接口,因为它包含的不仅仅是单个方法,所以不可能做类似的事情

IFn f = (String s) -> s.toLowerCase();
Run Code Online (Sandbox Code Playgroud)

  • Java 8 lambdas在匿名内部类上是语法糖的想法是一个不会消失的模因.请参阅这个问题的答案:http://programmers.stackexchange.com/questions/177879/type-in​​ference-in-java-8,以解释为什么它是错误的.这显然是一个经常出现的问题; 我将在Lambda常见问题解答(http://www.lambdafaq.org)上给出答案. (6认同)