如何充分利用Java Function接口?


如果您想掌握函数式编程,最好的起点是使用Java Function接口。这个例子将向您展示在代码中实现此函数接口的四种不同方法 - 从如何使用实际类开始,以及如何使用lambda函数创建非常简洁的代码。

Java Function接口非常简单。它将单个Java对象作为参数,并在方法结束时返回单个Java对象。您可以想出的任何方法都会获取一个对象并返回一个满足Java函数契约的对象。

如何使用Java的Function接口
对于这个Java Function接口示例,我们将提供一个名为“apply”的方法,该方法将Integer作为参数,将其平方并将结果作为String返回。在开始之前,让我们快速浏览java.util.function.Function的官方JavaDoc:

java.util.function.Function Java Interface Function<T,R> Parameter Types:
T - the input given to the function
R - the result running the function

Popular Subinterface of Function: UnaryOperator<T>

JavaDoc还指示Function接口有一个名为apply的非默认方法,它接受一个参数并返回一个参数:

R apply(T t)

人们常常误以为java.util.functions包中定义的接口有些神奇,但事实并非如此。它们只是普通的接口,因此,我们总是可以创建一个显式实现它们的类。

class FunctionClass implements Function<Integer, String> {
  public String apply(Integer t) {
    return Integer.toString(t*t);
  }
}

这里定义的FunctionClass实现Function并为apply方法提供实现。然后我们可以在任何具有标准语法规则的类中使用它。

Function<Integer, String> functionClass = new FunctionClass();
System.out.println(functionClass.apply(2));

运行上面的代码时,输​​出将是四

Java Function接口示例
类似地,我们可以编写一个Java函数示例,它使用内部类来实现apply方法:

Function<Integer, String> innerClass = new Function<Integer, String>(){
  public String apply(Integer t) {
    return Integer.toString(t*t);
  }
};
System.out.println(innerClass.apply(3));

运行内部类示例时,输出将为9。

Java的Function和lambda表达式示例
当然,函数接口的整个想法是将lambda表达式合并混合其中。这是使用相当详细的lambda表达式实现的Java Function示例(不需要自己再编写一个实现类了):

Function<Integer, String> verboseLambda = (Integer x)-> { return Integer.toString(x*x); };
System.out.println(verboseLambda.apply(5));

这个实现将打印出值25.当然,这个实现也非常冗长。使用Java lambda表达式时,左侧不需要对象类型,如果lambda表达式是一行长,则可以省略括号和return关键字。因此,实现此Java Function接口的更简洁的lambda表达式如下所示:

Function<Integer, String> conciseLambda = (Integer x)-> { return Integer.toString(x*x); };
System.out.println(conciseLambda.apply(5));

当代码实现Java函数并运行简洁的lambda表达式时,程序将打印出25。
这就是你真正需要了解的java.util.function.Function接口。它是一个非常简单的组件,只需要实现一个名为apply的方法 - 在单个对象中传递,运行完成并返回另一个Java对象。就是这么简单。

不要过度复杂Java的Function接口
有些人会发现Java Function接口的简单性有点令人困惑。毕竟,一种输入某个东西并返回其他东西的方法似乎是如此令人难以置信的模糊和抽象,几乎看起来毫无意义。
然而,经验丰富的Java开发人员知道,有时最简单的语言结构可能会变得最强大,就像使用抽象类和接口设计的对象模型一样。当涉及到java.util.function包中列出的各种组件时,通过简单性的功能正是如此。

您可以各种方式运行Function接口,尤其是在使用Java Streams API启动高级函数编程时。诸如map,reduce和flatMap之类的强大方法都将Java函数作为参数。因此,如果您计划使用Java进行任何map-reduce编程,函数将成为您最大的朋友之一。