我们先来看下Funtion接口的定义
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
}
Funtion接口,定义了一个apply的抽象方法,接收一个泛型T对象,并且返回泛型R对象,看到这里,是不是对这个接口的描述,还是一头雾水呢,下面,我们看下几个例子,来讲述这个接口的作用
Function<Integer, Integer> function1 = x -> x * 2;
System.out.println(function1.apply(4));// 8
Function<Integer, String> function2 = x -> x * 2 + "dd";
System.out.println(function2.apply(4));//8dd
Function<String, String> strFunction1 = (str) -> new String(str);
System.out.println(strFunction1.apply("aa"));//aa
Function<String, String> strFunction2 = String::new;
System.out.println(strFunction2.apply("bb"));//bb
Function<String, Emp> objFunction1 = (str) -> new Emp(str);
System.out.println(objFunction1.apply("cc").getName());//cc
Function<String, Emp> objFunction2 = Emp::new;
System.out.println(objFunction2.apply("dd").getName());//dd
第一段代码,表示x,为传入参数的类型,也是接口中泛型T,返回的类型也是Integer,调用apply方法,传入Integer的4,做乘法操作,然后返回R的泛型,Integer类型
第二段代码,传入的泛型T是Integer的,返回的泛型R是String的,里面的做的操作是传入的参数x 乘2,然后连接一个dd的字符串,然后的就是泛型R的字符串;
后面的表示创建一个对象的两种方式,分别调用有一个参数的构造方法,和无参的构造方法,返回泛型R对象;对象Emp的定义如下
public static class Emp {
private String name;
public Emp() {
}
public Emp(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
这几段代码,可以看出,这个接口,是要传入的泛型T参数,然后做业务操作,然后泛型R;
这个接口的其他的默认方法以及静态方法的解释如下代码所示,就不在写案例测试了
R apply(T t);
/**
* 先做传入的Function类型的参数的apply操作,再做当前这个接口的apply操作
* V表示这个Function类型的参数的传入参数类型,也就是本接口的T类型
* @param before
* @return
*/
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
/**
* 先做本接口的apply操作,再做传入的Function类型的参数的apply操作
* @param after
* @return
*/
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
/**
* 静态方法表示,这个传入的泛型参数T的本身
* @return
*/
static <T> Function<T, T> identity() {
return t -> t;
}
下面我们看下Funtion这个接口的“扩展”的原始类型特化的一些函数接口
IntFunction,
IntToDoubleFunction,
IntToLongFunction,
LongFunction,
LongToDoubleFunction,
LongToIntFunction,
DoubleFunction,ToIntFunction,
ToDoubleFunction,
ToLongFunction
我们知道,我们在做基础数据处理的时候(eg: Integer i=0; Integer dd= i+1;),会对基础类型的包装类,进行拆箱的操作,转成基本类型,再做运算处理,拆箱和装箱,其实是非常消耗性能的,尤其是在大量数据运算的时候;这些特殊的Function函数式接口,根据不同的类型,避免了拆箱和装箱的操作,从而提高程序的运行效率