什么是函数式接口:
其实之前在讲Lambda表达式的时候提到过,所谓的函数式接口,当然首先是一个接口,然后就是在这个接口里面只能有一个抽象方法。这种类型的接口也称为SAM接口,即Single Abstract Method interfaces。
用途:
1、不同业务实现
创建一个函数式的接口,注意只有一个抽象方法
@FunctionalInterface
public interface Convert {
void convert();
}
那么传统的业务实现方式是,创建一个实现类,(或者我们可以使用匿名内部类的方式实现)
public class ConvertImpl implements Convert{
@Override
public void convert() {
// TODO Auto-generated method stub
System.out.println("bbbb");
}
}
那么使用方式是:
public class Test {
public static void main(String[] args) {
Convert convert = new ConvertImpl();
convert.convert();
}
}
那么我们前面说个Lambda表达式,我们可以采用的新的方式实现业务,不需要构建新类,直接使用
public class Test {
public static void main(String[] args) {
Convert convert1 = ()->System.out.println("aaa");
convert1.convert();
}
}
结合::的使用
创建函数式接口:传参为类型 F,返回类型 T。
@FunctionalInterface
public interface Convert<F,T> {
T convert(F f);
}
创建一个实体类
@Data
public class People {
Integer age = 0;
public People() {
}
public People(Integer age) {
super();
this.age = age;
}
static String say(String name) {
return name+"aa";
}
Integer addAge(Integer age) {
return this.age+age;
}
}
调用静态方法:
Convert<String, String> con = People::say;
String name = con.convert("张三");
System.out.println(name);
调用对象方法
Convert<Integer, Integer> agecon = new People()::addAge;
Integer newAge = agecon.convert(11);
System.out.println(newAge);
调用构造方法
Convert<Integer, People> cus = People::new;
People people = cus.convert(10);
关于@FunctionalInterface注解
Java 8为函数式接口引入了一个新注解@FunctionalInterface,主要用于编译级错误检查,加上该注解,当你写的接口不符合函数式接口定义的时候,编译器会报错。
那么对于函数式接口,主要又以下特点:
- 只有一个抽象方法
-
允许定义默认的方法,因为默认方法不是抽象的(default修饰的)
-
允许定义静态方法,因为静态方法不是抽象
-
函数式接口里是可以包含Object里的public方法,这些方法对于函数式接口来说,不被当成是抽象方法(虽然它们是抽象方法);因为任何一个函数式接口的实现,默认都继承了Object类,包含了来自java.lang.Object里对这些抽象方法的实现
JDK中的函数式接口举例
java.lang.Runnable,
java.awt.event.ActionListener,
java.util.Comparator,
java.util.concurrent.Callable
java.util.function包下的接口,如Consumer、Predicate、Supplier等