函数式接口:
- 定义:
- 只包含一个抽象方法的接口,称为函数式接口
- 可以使用@FunctionalInterface注解,这样做可以检查它是否是一个函数式接口。同时javadoc会包含说明,这是一个函数式接口
- 如何理解函数式接口:
- Java 面向对象。随着其他语言的兴起,为了支持更加广泛的技术要求,java不但支持OOP也可以支持OOF(面向函数编程)
- lambda表示式是对象,而不是函数,它们必须依附于一类特别的对象类型函数式接口
- Java中,lambda表达式是一个函数式接口的实例。只要一个对象是函数式接口的实例,那么该对象就可以用lambda表达式来表示
Lambda使用:
- 格式
- -> lanmbda操作符或箭头操作符
- 左边:lambda形参列表(接口中的抽象方法的形参列表)
- 右边:lambda体(重写方法的方法体)
- lambda本质是:
- 作为函数式接口的实例(只有一个抽象方法)
- 如果一个接口中只声明了一个抽象方法,此接口就称为函数式接口
- 方法引用:
- 当传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!
- 方法引用可以看为lambda表达式的深层次表达,方法引用就是Lambda表达式,也就是函数式接口的一个实例,通过方法的名字来指向一个方法
- 要求:
- 实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致
- 格式:
- 使用操作符"::"将类(对象)与方法名分割开
- 对象::实例方法名(非静态)
- 类::静态方法
- 类::实例方法名(非静态)
方式一
- 无参数,无返回值
public void test1(){
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("谎言和誓言的区别是什么");
}
};
runnable.run();
System.out.println("**************************");
Runnable runnable1 = () -> System.out.println("听的人信了,说的人信了");
runnable1.run();
}
- 需要参数,没有返回值
public void test2(){
Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
};
consumer.accept("当你凝望深渊时");
System.out.println("*********************************");
Consumer<String> consumer1 = (String s) -> System.out.println(s);
consumer1.accept("深渊也凝望着你");
}
- 数据类型可以省略,因为可由编译器推断得出,成为类型推断
public void test3(){
Consumer<String> consumer = (s) -> System.out.println(s);
consumer.accept("在自己的身上克服这个时代");
}
- lambda 如果只需要一个参数,参数的小括号可以省略
public void test4(){
Consumer<String> consumer = s -> System.out.println(s);
consumer.accept("每一个不曾起舞的日子,都是对生命的辜负");
}
- lambda 如果需要两个或者两个以上的参数,多条执行语句,并且可以有返回值
public void test5(){
Comparator<Integer> comparator = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
System.out.println(o1);
System.out.println(o2);
return o1.compareTo(o2);
}
};
System.out.println("************************");
Comparator<Integer> comparator1 = (o1,o2) -> {
System.out.println(o1);
System.out.println(o2);
return o1.compareTo(o2);
};
}
- 当lambda 体只有一条语句时,return 与 大括号若有,都可以省略
public void test6(){
Comparator<Integer> c1 = (o1, o2) -> o1.compareTo(o2);
System.out.println(c1.compare(13,12));
}
方式二
方法引用:
使用情况:当传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!
- 对象::实例方法
public void test1(){
Consumer<String> co1 = str -> System.out.println(str);
co1.accept("咸鱼");
System.out.println("**************************");
Consumer<String> co2 = System.out :: println;
co2.accept("xianyu");
}
public void test2(){
Employee employee = new Employee(999,"小明",18,666);
Supplier<String> su1 = () -> employee.getName();
System.out.println(su1.get());
System.out.println("************************");
Supplier<String> su2 = employee ::getName;
System.out.println(su2.get());
}
- 类::静态方法
public void test3(){
Comparator<Integer> com1 = (t1,t2) -> Integer.compare(t1,t2);
System.out.println(com1.compare(22,21));
System.out.println("************************");
Comparator<Integer> com2 = Integer::compare;
System.out.println(com2.compare(22,21));
}
public void test4(){
Function<Double,Long> fun = new Function<Double, Long>() {
@Override
public Long apply(Double aDouble) {
return Math.round(aDouble);
}
};
System.out.println(fun.apply(9.9));
System.out.println("*******************");
Function<Double,Long> function = Math::round;
System.out.println(function.apply(9.9));
}
- 类::非静态方法
public void test5(){
Comparator<String> com = (c1,c2) -> c1.compareTo(c2);
System.out.println(com.compare("adc","acd"));
System.out.println("******************");
Comparator<String> com1 = String::compareTo;
System.out.println(com1.compare("abd","adm"));
}
public void test6(){
BiPredicate<String,String> biPredicate = (b1,b2) -> b1.equals(b2);
System.out.println(biPredicate.test("abc","abc"));
System.out.println("**********************");
BiPredicate<String,String> bi = biPredicate::test;
System.out.println(bi.test("abc","abc"));
}
public void test7(){
Employee employee = new Employee(888, "小李", 18, 880);
Function<Employee,String> stringFunction = e -> e.getName();
System.out.println(stringFunction.apply(employee));
System.out.println("***********************");
Function<Employee,String> function = Employee::getName;
System.out.println(function.apply(employee));
}
- 构造器引用
- 和方法引用类似,函数式接口的抽象方法的形参列表和构造器的形参列表一致。
public void test1(){
Supplier<Employee> sup = () -> new Employee();
System.out.println(sup.get());
System.out.println("*********************");
Supplier<Employee> sup1 = Employee::new;
System.out.println(sup1.get());
}
public void test2(){
Function<Integer,String[]> function = Length -> new String[Length];
String[] apply = function.apply(6);
System.out.println(Arrays.toString(apply));
System.out.println("*********************");
Function<Integer,String[]> function1 = String[]::new;
String[] apply1 = function1.apply(6);
System.out.println(apply1);
}