1. 函数的基本概念
函数就是将输入转换一种形式进行输出。以数学中的函数为例,假设有一个函数
f
(
x
)
=
3
x
+
1
f(x) = 3x + 1
f(x)=3x+1,当输入
x
=
1
x = 1
x=1 时,输出
f
(
x
)
=
4
f(x) = 4
f(x)=4。Java 中函数的概念类似,以 Comparator
类为例,下面代码是一个函数式接口。其中方法 applyAsInt 表示一种转换关系,相当于数学函数中的
f
f
f,value 就是输入的参数,组合在一起就是
f
(
x
)
f(x)
f(x)。当然输入可能是多个,可以写成
f
(
x
,
y
)
f(x, y)
f(x,y),int 就是输出的类型。
@FunctionalInterface
public interface ToIntFunction<T> {
/**
* Applies this function to the given argument.
*
* @param value the function argument
* @return the function result
*/
int applyAsInt(T value);
}
这种函数式接口只是对函数的一种声明,函数的具体内容由开发者来定义,如下代码展示如何实现函数式接口。val -> val[0]
这个 lambda 表达式就是对 ToIntFunction
接口中的函数的一种实现,相当于
3
x
+
1
3x + 1
3x+1,直到这里,才真正的定义了一个函数。comparingInt
方法的入参 keyExtractor 包含了这个函数的映射规则。这个函数就是将 val 数组中的第一个元素取出来。
// 调用如下方法
Comparator.comparingInt(val -> val[0]);
// 为了便于理解,去掉了原方法的一些代码
public static <T> comparingInt(ToIntFunction<? super T> keyExtractor) {
return keyExtractor.applyAsInt(c1);
}
2. 函数的进阶
数学中有嵌套函数
f
(
g
(
x
)
)
f(g(x))
f(g(x)),Java 中的函数也有类似的嵌套,接下来看完整的 comparingInt
方法。
public static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor) {
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable)
(c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));
}
这个函数相当于 g ( f ( x ) , f ( x ) ) g(f(x), f(x)) g(f(x),f(x)),并且把新的函数 g ( x , y ) g(x, y) g(x,y) 返回。
Arrays.sort(intervals, Comparator.comparingInt(val -> val[0]));
这个返回的函数又作为参数,传到另一个函数中。
3. 自定义函数
// 表示将两个输入参数,经过特定的操作,输出一个整数
@FunctionalInterface
public interface SumFunction<T, U> {
int apply(T a, U b);
}
public static <T> int sum(SumFunction<T, T> sumFunction, T a, T b) {
return sumFunction.apply(a, b);
}
public static void main(String[] args) throws Exception {
Person person = new Person();
System.out.println(sum(Integer::sum, 1, 2));
}
这个函数就是 f ( x , y ) = x + y f(x, y) = x + y f(x,y)=x+y。函数式接口只表示一种转换关系