函数式接口
简介
函数式接口是指仅仅只包含一个抽象方法的接口,jdk1.8提供了一个@FunctionalInterface注解来定义函数式接口,如果我们定义的接口不符合函数式的规范便会报错。配合Lambda表达式一起使用
四大核心函数式接口
函数式接口 | 参数类型 | 返回类型 | 用途 |
---|---|---|---|
Consumer 消费型接口 | T | void | void accept(T t); |
Supplier 供给型接口 | void | T | T get(); |
Function<T, R> 函数型接口 | T | R | R apply(T t); |
Predicate 断言型接口 | T | boolean | booelan test(T t); |
BiConsumer<T, U> | T,U | void | 对类型为T,U参数应用操作。包含方法为void accept(T t,U u); |
BiFunction<T, U, R> | T,U | R | 对类型为T,U参数应用操作,并返回R类型的结果。包含方法为R apply(T t,U u); |
UnaryOperator extends Function<T, T> | T | T | 对类型为T的对象进行一元运算,并返回T类型的结果。包含方法为T apply(T t); |
BinaryOperator extends BiFunction<T,T,T> | T,T | T | 对类型为T的对象进行二元运算,并返回T类型的结果。包含方法为T apply(T t1,T t2); |
ToIntFunction ToLongFunction ToDoubleFunction | T | int long double | 分别计算int、long、double值的函数 |
IntFunction LongFunction DoubleFunction | int long double | R | 参数为int、long、double类型的函数 |
应用场景
当我们编写一个接口,这个接口只有一个抽象方法时,就可以使用函数式接口去替代
方法、构造方法和数组引用
方法、构造方法和数组引用就是Lamdba的另一种表现形式
方法引用
若Lamdba表达式中的内容由方法已经实现了,可以使用方法引用这个技能
当你需要使用方法引用时,目标引用放在分隔符::前,方法的名称放在后面
对象::实例方法
Lambda表达式中调用方法的参数类型和返回值必须和函数式接口中的抽象方法一致
public class Test1 {
@Test
public void test01() {
// I1 i1 = (x)->System.out.println(x);
// i1.method("abcd");
//println里的参数列表和返回值类型必须和method方法一致才行
PrintStream ps = System.out;
I1 i1 = ps::println;//对象::实例方法
i1.method("abcd");
}
}
interface I1{
public void method(String str);
}
类名::静态方法
Lambda表达式中调用方法的参数类型和返回值必须和函数式接口中的抽象方法一致
public class Test1 {
@Test
public void test01() {
// Comparator<Integer> com = (x,y)-> Integer.compare(x, y);
// int compare = com.compare(10, 20);
// System.out.println(compare);
//类名::静态方法
Comparator<Integer> com = Integer::compare;
int compare = com.compare(10, 20);
System.out.println(compare);
}
}
类名::实例方法
Lambda表达式参数列表中第一个参数必须是实例方法的调用者
Lambda表达式参数列表中第二个参数必须是实例方法的参数
public class Test1 {
@Test
public void test01() {
// I1<String> i1 = (x,y) -> x.equals(y);
// boolean method = i1.method("abc", "abc");
// System.out.println(method);
//类名::实例方法
//注意:Lambda表达式参数列表中第一个参数是equals方法的调用者,
// Lambda表达式参数列表中第二个参数是equals方法的参数
I1<String> i1 = String::equals;
boolean method = i1.method("abc", "abc");
System.out.println(method);
}
}
interface I1<T>{
public boolean method(T t1,T t2);
}
构造方法引用
类名::new
需要调用的构造方法的参数列表必须和函数式接口中抽象方法的参数列表一致
public class Test1 {
@Test
public void test01() {
//需求:创建学生对象
I1<Student> i1 = Student::new;
// System.out.println(i1.method());
// System.out.println(i1.method("桥本有菜",24));
System.out.println(i1.method("桥本有菜",24,8888,Course.JAVA));
}
}
interface I1<T>{
// public T method();
public T method(String name,int age,double salary,Course course);
}
enum Course{//课程枚举
JAVA,HTML,PYTHON;
}
class Student{//学生类
private String name;
private int age;
private double salary;
private Course course;
...
}
数组引用
语法格式:type[]::new
public class Test1 {
@Test
public void test01() {
//创建数组
I1<String[]> i1 = String[]::new;
System.out.println(Arrays.toString(i1.method(10)));
}
}
interface I1<T>{
public T method(int capacity);
}