一,背景介绍
在正常使用中,我们平时定义方法都是类似这样,
public static String fixStringLength(String numberArg){
int length = numberArg.length();
switch (length){
case 1:
return "00"+numberArg;
default:
return "fix" + numberArg;
}
}
然后通过在其他代码中引用该方法来使用,例如,
public static void main(String[] args) {
fixStringLength("486");
}
Stream 中的 Function 实际上解决了一个简单的问题,那就是我们在实际书写代码的时候,一个方法一般只能作为代码中的某一行函数,用于处理里面的数值,但是并不能将一个方法作为一个参数,将方法以参数的形式,将方法传递到下一个方法中继续使用。
源码以及使用示例
@FunctionalInterface
public interface Function<T, R> {
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
R apply(T t);
/**
* Returns a composed function that first applies the {@code before}
* function to its input, and then applies this function to the result.
* If evaluation of either function throws an exception, it is relayed to
* the caller of the composed function.
*
* @param <V> the type of input to the {@code before} function, and to the
* composed function
* @param before the function to apply before this function is applied
* @return a composed function that first applies the {@code before}
* function and then applies this function
* @throws NullPointerException if before is null
*
* @see #andThen(Function)
*/
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
/**
* Returns a composed function that first applies this function to
* its input, and then applies the {@code after} function to the result.
* If evaluation of either function throws an exception, it is relayed to
* the caller of the composed function.
*
* @param <V> the type of output of the {@code after} function, and of the
* composed function
* @param after the function to apply after this function is applied
* @return a composed function that first applies this function and then
* applies the {@code after} function
* @throws NullPointerException if after is null
*
* @see #compose(Function)
*/
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
/**
* Returns a function that always returns its input argument.
*
* @param <T> the type of the input and output objects to the function
* @return a function that always returns its input argument
*/
static <T> Function<T, T> identity() {
return t -> t;
}
}
Function 是作为一种方法接口,两个泛型 T, R 在这里分别指代的是方法的入参以及返回值的泛型。
-
apply
/** * Applies this function to the given argument. * * @param t the function argument * @return the function result */ R apply(T t);
apply 的作用为执行当前方法函数,t 为入参,R 为返回值类型
示例:
public static void main(String[] args) {
// 定义函数 但没有创建实际方法而是类似于将方法(function1)作为一个变量,对以此来直接在行内引用方法对象,达到和方法一样的效果
Function<Integer, String> function1 = item -> {
item *= 100;
return item + "";
};
String apply = function1.apply(13);
System.out.println("apply = " + apply);
}
结果如下:
-
compose
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) { Objects.requireNonNull(before); return (V v) -> apply(before.apply(v)); }
compose 看内部实现,这个方法的入参也为 Function 类型,当调用时会先执行 作为入参的 Function 中的apply 方法,再将计算的结果作为原有方法的 apply 入参
示例:
public static void main(String[] args) {
// 定义函数 但没有创建实际方法而是类似于将方法 这里的 function1 作为一个变量,对象 以此来直接在行内引用方法对象 达到和方法一样的效果
Function<Integer, String> function1 = item -> {
item *= 100;
return item + "";
};
String apply = function1.apply(13);
System.out.println("apply = " + apply);
// 定义的第二个方法函数
Function<Integer, Integer> function2 = item -> item + 10;
// 先将 13 作为function2的入参 然后将结果作为function1的入参继续计算
String apply2 = function1.compose(function2).apply(13);
System.out.println("apply2 = " + apply2);
}
-
andThen
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) { Objects.requireNonNull(after); return (T t) -> after.apply(apply(t)); }
andThen 与compose 类似,但是方向相反
示例:
public static void main(String[] args) {
// 定义函数 但没有创建实际方法而是类似于将方法 这里的 function1 作为一个变量,对象 以此来直接在行内引用方法对象 达到和方法一样的效果
Function<Integer, String> function1 = item -> {
item *= 100;
return item + "";
};
String apply = function1.apply(13);
System.out.println("apply = " + apply);
// 定义的第二个方法函数
Function<Integer, Integer> function2 = item -> item + 10;
// 先将 13 作为function2的入参 然后将结果作为function1的入参继续计算
String apply2 = function1.compose(function2).apply(13);
System.out.println("apply2 = " + apply2);
// 定义的第三个方法函数
Function<String, Integer> function3 = item -> Integer.valueOf(item) + 31;
// 先将 13 作为function1的入参 然后将结果作为function3的入参继续计算
Integer apply3 = function1.andThen(function3).apply(13);
System.out.println("apply3 = " + apply3);
// 使用其他已定义的方法 示例
String apply4 = function1.andThen(App::fixStringLength).apply(13);
System.out.println("apply4 = " + apply4);
}
结果如下:
