#Lambd表达式
Lambda表达式是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码 像数据一样进行传递)。可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升。
##1. 格式
‘->’ :lambda操作符或箭头操作符
'->'的左边: Lambda形参列表(其实就是接口中的抽象方法的形参列表)
'->'的右边: Lambda体 (其实就是 重写的抽象方法的方法体)
##2. Lambda表达式的使用
Lambda表达式的使用为了方便理解,分为6种情况介绍,通过内置函数式接口来举例,也可以对比匿名函数来理解。
语法格式一:无参,无返回值,Lambda体只需一条语句
Runnable r2 = ()->{
System.out.println("Test1");
};
语法格式二:Lambda需要一个参数,并且无返回值
Consumer<String> con2 = (String s)->{
System.out.println(s);
};
con2.accept("test2");
语法格式三:Lambda只需要一个参数时,参数的小括号可以省略,同时省略参数变量类型(类型推断)
Consumer<String> con2 = s->{
System.out.println(s);
};
con2.accept("test2");
语法格式四:Lambda需要两个参数,并且有返回值
Comparator<Integer> com2 = (Integer o1,Integer o2) -> {
return o1.compareTo(o2);
};
语法格式五:当 Lambda 体只有一条语句时,return 与大括号可以省略
Comparator<Integer> com2 = (Integer o1,Integer o2) -> o1.compareTo(o2);
语法格式五:数据类型可以省 略,因为可由编译器推断得出, 称为“类型推断
// 数据类型可以省略,因为可由编 译器推断得出, 称为“类型推断
Comparator<Integer> com2 = (o1,o2) -> o1.compareTo(o2);
上述 Lambda 表达式中的参数类型都是由编译器推断得出的。Lambda 表达式中无需指定类型,程序依然可以编译,这是因为 javac 根据程序的上下文,在后台推断出了参数的类型。Lambda 表达式的类型依赖于上下文环境,是由编译器推断出来的。这就是所谓的“类型推断”
##3. 函数式接口
###3.1 什么是函数式接口
只包含一个抽象方法的接口,称为函数式接口。
你可以通过 Lambda 表达式来创建该接口的对象。(若 Lambda 表达式抛出一个受检异常,那么该异常需要在目标接口的抽象方法上进行声明)。Lambda表达式也是依赖于函数式接口的。
我们可以在任意函数式接口上使用 @FunctionalInterface 注解, 这样做可以检查它是否是一个函数式接口,同时javadoc也会包含一条声明,说明这个接口是一个函数式接口。
###3.2 如何理解函数式接口
1.Java从诞生口起就是一直倡导“一切皆对象”,在Java里面面向对象(OOP)编程是一切。但是随着python、 scala等语言的兴起和新技术的挑战,Java不得不做出调整以便支持更加广泛的技术要求,也即Java不但可以支持OOP还可以支持OOF(面向函数编程)
2.在函数式编程语言当中,函数被当做一等公民对待。在将函数作为一等公民的编程语言中,Lambda表达式的类型是函数。但是在Java8中,有所不同。在Java8中,Lambda表达式是对象,而不是函数,它们必须依附于一类特别的对象类型-函数式接口。
3.简单的说,在Java8中,Lambda表达式就是一个函数式接口的实例。这就是Lambda表达式和函数式接口的关系。也就是说,只要一少对象是函数式接口的实例,那么该对象就可以用Lambda表达式来表示。
所以以前用匿名实现类表示的现在都可以用Lambda表达式来写。
###3.3 自定义函数式接口
/**
这个接口里只能写一个方法,写多个方法注解会爆红,注解的作用是验证该接口是否是函数接口
若果不写该注解,并且接口只有一个方法则该接口也是函数式接口
*/
@FunctionalInterface
public interface MyInterface {
void method();
}
//泛型写法
@FunctionalInterface
public interface MyInterface<T> {
T method(T t);
}
###3.4 Java 内置四大核心函数式接口
举两个简单的例子
public void test4(){
Consume(500, new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
System.out.println("消费了"+integer);
}
});
//lambda表达式写法
Consume(400,money-> System.out.println("赚了"+money));
}
public static void Consume(int money, Consumer<Integer> consumer){
consumer.accept(money);
}
public void test5(){
List<String> list = Arrays.asList("sss","rrr","yyyyy","ssdasds","sd");
list = predit(list, new Predicate<String>() {
@Override
public boolean test(String s) {
return s.length()>3;
}
});
System.out.println(list.toString());
//lambda表达式写法
List<String> list1 = Arrays.asList("12","13","14","15","16","17");
list1 = predit(list1,i->Integer.parseInt(i)>14);
System.out.println(list1.toString());
}
public static List<String> predit(List<String> strings, Predicate<String> predicate){
List<String> list = new ArrayList<>();
for (String s:strings){
if (predicate.test(s)){
list.add(s);
}
}
return list;
}