目录
Lambda表达式的概念:
Lambda表达式的类型是一个接口类型,简而言之Lambda表达式本身就会为了实现接口中的抽象方法的,但是这个接口只能有一个抽象方法,换句话来说,Lambda可以在大多数场景下替换匿名内部类,使得代码更加简洁
@FunctionalInterface:
因为Lambda表达式是为了实现接口中的一个抽象方法且这个接口只能有一个抽象方法,Java称这种只有一个抽象方法的接口为“函数式接口” —— @FunctionalInterface,而这个注解修饰的接口里只允许有一个抽象方法
Lambda表达式的语法:
():用来描述参数列表,多个参数逗号分隔,如果没有参数,留空即可
->:(goes to)表示指向的意思,为lambda运算符,固定写法
{}:具体要做的事;
主要特征:
可选类型声明:不需要声明参数类型,编译器可以识别参数值
可选的参数圆括号:一个参数无需定义圆括号,多个参数需要定义圆括号,多个元素逗号隔开
可选的大括号:当只有一条语句的时候,就可以省略大括号
Lambda通过外部方法实现抽象方法:
1、语法:
方法归属者::方法名
静态方法的归属者为类
非静态方法的归属者为对象
2、要求:
1、参数的个数以及类型需要与函数式接口中的抽象方法一致
2、返回值类型与函数接口中的抽象方法一致
3、案例:
我们通过这个函数式接口进行实现
Lambda创建线程:
1、以往实现线程:
2、通过Lambda实现线程:
通过对比我们可以发现,通过Lambda表达式实现线程代码更加紧凑
闭包问题:
Lambda表达式或匿名内部类引用了外部变量,那么此外部变量不可改变,相当于final修饰
Consumer接口的使用:
如果我们想遍历集合中的元素,我们可以使用集合中的forEach()方法,而forEach()方法需要给定参数:实现了Consumer接口的对象,因为forEach()读到了元素并不知道我们需要对元素进行如何操作,而这个实现了Consumer接口的对象就是用来描述我们对元素如何操作的
class ConsumerImpl implements Consumer{
@Override
public void accept(Object o){
System.out.println(o);
}
}
public static void main( String[] args ){
List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
//这有三种方法通过使用forEach()对集合进行遍历
//1、通过传递实现了Consumer类的对象,外部需要创建类实现Consumer接口,并且实现accept方法
list.forEach(new ConsumerImpl( ));
//2、Lambda语法内部实现Consumer对象
list.forEach( ( o ) -> {
System.out.println( ( String ) o);
} );
//3、通过System.out::println
//System.out是方法归属者,System.out会返回一个PrintStream对象
//PrintStream对象有一个方法println
//所以可以使用System.out::println进行调用
list.forEach(System.out::println);
}
Predicate接口的使用:
如果我们需要移除元素是可以使用removeIf()方法,removeIf()方法需要实现了Predicate接口的对象为参数,删除元素我们需要判断集合中是否有此元素吧,所以实现了Predicate接口的对象就是用来判断集合中是否有我们需要删除的元素的有返回true,并且删除,没有返回false
class PredicateImpl implements Predicate{
@Override
public boolean test(Object o){
return o.equals("b");
}
}
public static void main( String[] args ){
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
//1、我们可以通过实例化实现了Predicate接口的类进行删除
PredicateImpl pi = new PredicateImpl();
list.removeIf(pi);
list.forEach(System.out::println);
//2、我们可以通过lambda语法进行删除
list.removeIf(o->o.equals("a"));
list.forEach(System.out::println);
//1和2是相同的效果
}
Comparator接口的使用:
当我们需要对集合进行排序时,可以使用集合的sorted()方法,对集合进行排序,而sorted()方法需要给定比较器对象:实现了Comparator接口下的compare()方法
Class ComparatorImpl implements Comparator<String>{
@Override
publicintcompare(Stringo1,Stringo2){
returno1.compareTo(o2);
}
}
public static void main( String[] args ){
List<String>list=newArrayList<>();
list.add("a");
list.add("c");
list.add("d");
list.add("b");
//1、我们可以通过实例化实现了Comparator接口的类传递比较器对象
list.sort(new ComparatorImpl());
//2、我们可以通过Lambda语法进行实现
list.sort( (o1,o2) -> o1.compareTo( o2 ));
list.forEach(System.out::println);
}
总结:Lambda表达式可以在大部分场景下替代匿名内部类,可使代码更加紧凑,更加整洁,但是当我们进行调试的时候因为代码过于紧凑不像普通代码那样一步一步实现的,所以调试的时候会比较麻烦