Guava 的 Function 接口
光是看一些博客容易打瞌睡,为此边记录边学习。
最近在研究 springfox 的源码,在其源码中多次看到了 Guava 的 Function 接口的使用,今天就来学习学习 Guava 的 Function 接口。
首先,需要搞明白的一个问题:什么是 Guava?
查阅博客得知,Guava 是对 Java API 的扩展,为 Java 中的一些常见 API 提供了更优雅的实现,Guava 中包含了 Google 正在其公司项目中使用的核心库。
要使用 Guava 库的 Function 接口,需要导入 Guava 依赖:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency>
回到主题,Function 接口。
首先来看一下这函数的源码:
@GwtCompatible
public interface Function<F, T> {
@Nullable
T apply(@Nullable F var1);
boolean equals(@Nullable Object var1);
}
可以看到,这个接口提供了两个抽象方法,我们主要实现的是 apply 方法。
Function 接口是一个泛型接口,有两个泛型:F 和 T 。下面举个具体的例子,让一个类实现该接口,从而对比 F 和 T 的含义。
例如:
public class DateFormatFunction implements Function<Date, String> {
@Override
public String apply(Date date) {
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
return dateFormat.format(date);
}
}
可以看到 F 其实是 apply 方法的形参的类型。T 是 apply 方法的返回值类型。
那么 Function 接口有哪些用处?Function 接口的用法是什么?
在这里,我们可以在 main 方法中,直接定义一个 Function 接口的匿名类,然后调用这个匿名类对象,例如:
public class Main {
public static void main(String[] args) {
Function<Date, String> function = new Function<Date, String>() {
@Override
public String apply(Date date) {
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
return dateFormat.format(date);
}
};
System.out.println(function.apply(new Date())); // output: 29/09/2021
}
}
除了定义匿名类以外,还有一种方式,定义一个 Function 接口的实现类:
public class DateFormatFunction implements Function<Date, String> {
@Override
public String apply(Date date) {
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
return dateFormat.format(date);
}
}
然后在 main 方法中使用该实现类:
public class Main {
public static void main(String[] args) {
DateFormatFunction function = new DateFormatFunction();
System.out.println(function.apply(new Date()));
}
}
也可以用多态的写法:
public class Main {
public static void main(String[] args) {
Function<Date, String> function = new DateFormatFunction();
System.out.println(function.apply(new Date()));
}
}
好,对于下面这个实现类,其实它的 apply 方法所做的事情就是将 Date 对象转化为 Date 格式化后的 String 对象,这体现出使用 Function 接口的一个好处:能够转换对象,并且隐藏具体的细节。
public class DateFormatFunction implements Function<Date, String> {
@Override
public String apply(Date date) {
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
return dateFormat.format(date);
}
}
但对 Guava 的 Function 接口理解到这一步,这种理解太过于简单了,我觉得还不够。我想知道,在实际开发中如何使用 Function 接口,以及 Function 接口能为我们开发程序带来切切实实的好处是什么?
附带一提,这篇博客提到使用 Function 接口的一个优点是,可以使用依赖注入传递一个函数接口到一个类中,使得代码高内聚。但具体是怎么样的?我需要实际例子。
对于 Function 接口,据我目前所知,我们常用的是实现其 apply 方法,Function apply 所做的事情其实就是将一个对象转化为另一个对象,这也正符合函数(function)的特点:输入一些东西,经过函数处理,得到输出。但要注意,一个好功能,应当没有副作用,这就意味着一个对象传入 apply 方法后,应当是保持不变的。
有一种编程风格叫函数式编程,Guava 的 Function 接口使得在 Java 中进行函数式编程成为可能。
-
Java 的 API 库也提供了 Function 接口,在 java.util.function 包下,也得研究研究,看看其与
Guava 的 Function 接口有什么区别。
上一篇: 数据导入引发slave实例异常crash的bug定位与修复
下一篇: ArrayList源码研究