Lambda表达式
一、Lambda表达式简介
什么是Lambda?
Lambda是JAVA8添加的一个新的特性。说白了,Lambda就是一个匿名函数。
为什么要使用Lambda?
使用Lambda表达式可以对一个接口进行非常简洁的实现。
Lambda对接口的要求?
要求接口中定义的必须要实现的抽象方法只能是一个。
在JAVA8中,接口加了一个新特性:default
@FunctionalInterface注解
修饰函数式接口(接口中的抽象方法只有一个)的。
二、Lambda基础语法
Lambda是一个匿名函数
返回值 方法名 参数列表 方法体
( ) -> { }
() :用来描述参数列表
{} :用来描述方法体
-> :Lambda运算符,读作goes to
三、Lambda语法精简
1.参数类型
由于在接口的抽象方法中,已经定义了参数的数量和类型,所以在Lambda表达式中,参数的类型可以省略。
如果需要省略类型,则每一个参数的参数类型都要省略,千万不要出现省略一个参数类型,不省略一个参数类型。
Lambdas lambda1 = (a,b) -> { };
2.参数小括号
如果参数列表中,参数的数量只有一个,此时小括号可以省略。
Lambdass lambda2 = a -> { };
3.方法大括号
如果方法体中只有一条语句,此时大括号可以省略。
Lambdasss lambda3 = a -> System.out.println();
如果方法体中唯一的一条语句是个返回语句,则在省略掉大括号的同时,也必须省略掉return。
Lambdassss lambda4 = a -> 10;
LambdaS lambda5 = (a,b) -> a+b;
四、Lambda语法进阶
1.方法引用
可以快速的将一个Lambda表达式的实现指向一个已经实现的方法。
语法: 方法的隶属者::方法名
方法隶属者:如果这个方法是静态的方法,则方法的隶属者为类;若是动态方法,隶属者为类的对象。
注意:参数数量和类型一定要和接口中定义的方法一致;返回值的类型一定要和接口中定义的方法一致。
public class Test{
public static void main(String[] args){
Lambdas lambda1 = a -> change(a);
Lambdass lambda2 = Test::change;//引用了change方法的实现。
}
private static int change(int a){
return a * 2;
}
}
2.构造方法引用
public class Test{
public static void main(String[] args){
StudentCreater lambda1 = () -> { return new Student };
StudentCreater lambda1 = () -> new Student;
StudentCreater lambda1 = Studeng::new; //无参构造方法引用-----
StudentCreater2 lambda2 = Studeng::new; //有参构造方法引用-----
Studengt s = lambda2.getStudent("Tom",12);//赋值
}
}
interface StudentCreater{
Student getStudent();
}
interface StudentCreater2{
Student getStudent(String name,int age);
}
public class Student {
public String name;
public int age;
public Student (){}
public Studnet (String name,int age){
this.name = name;
this.age = age;
}
}
五、Lambda综合
在一个ArrayList中有若干个Student对象,按年龄排序
public class Test {
public static void main(String[] args){
ArrayList<Student> list = new ArrayList<Student>();
list.add(new Student("Tom",11));
list.add(new Student("Lily",44));
list.add(new Student("Jak",33));
list.add(new Student("Anny",22));
list.add(new Student("Jey",55));
list.sort((o1,o2) -> {
return o2.age - o1.age;
});
list.sort((o1,o2) -> o2.age - o1.age;
}
}
public class TestTreeSet {
public static void main(String[] args){
//使用Lambda表达式实现Comparator接口,并实列化一个TreeSet对象
TreeSet<Student> set = new TreeSet<Student>((o1,o2) -> o2.age - o1.age );
set.add(new Student("Tom",11));
set.add(new Student("Lily",44));
set.add(new Student("Jak",33));
set.add(new Student("Anny",22));
set.add(new Student("Jey",55));
}
}
集合的遍历(forEach):
public class Test {
public static void main(String[] args){
ArrayList<Integer> list = new ArrayList<Integer>();
Collections.addAll(list, 1,2,3,4,5);
//将集合中的每一个元素都带入到方法accept中
list.forEach(System.out::println);
//输出集合中所有的偶数
list.forEach( ele -> {
if(ele%2 == 0){
System.out.println(ele);
}
} );
}
}
删除集合中满足条件的元素(remove):
public class Test {
public static void main(String[] args){
ArrayList<Student> list = new ArrayList<Student>();
list.add(new Student("Tom",11));
list.add(new Student("Lily",44));
list.add(new Student("Jak",33));
list.add(new Student("Anny",22));
list.add(new Student("Jey",55));
//删除年龄大于30的
ListIterator<Student> it = list.listIterator();
while(it.hasNext()){
Student s = it.next();
if(ele.age > 30){
it.remove();
}
}
//Lambda实现
list.removeif( ele -> ele.age > 30);//将集合中的每一个元素都带入到test方法中,如果返回值是true,则删除这个元素。
}
开辟一条线程,做数字123的输出:
public class Test {
public static void main(String[] args){
Thread t = new Thread( () -> {
System.out.print("123");
} );
t.start();
}
}
六、系统内置函数式接口
import java.util.function.*
Predicate<T> boolean test(T t)
参数:T 返回值:boolean
IntPredicate int -> boolean
DoublePredicate double -> boolean
BiPreadicate<T,U>
参数:T,U 返回值:boolean
Consumer<T> void accept(T t)
参数:T 返回值:void
IntConsumer int -> void
DoubleConsumer double -> void
BiConsumer<T,U>
参数:T,U 返回值:void
Function<T, R> R apply(T)
参数:T 返回值:R
BiFunction<T,U,R>
参数:T,U 返回值:R
Supplier<T> T get();
参数:无 返回值:T
UnaryOperator<T>
参数:T 返回值:T
BinaryOperator<T>
参数:T,T 返回值:T
七、Lambda闭包问题
提升变量的生命周期
public class ClosureDemo{
public static void main(String[] args){
int n = getNumber().get();
}
private static Supplie<Integer> getNumber(){
int num =10;
return () -> {
return num;
}
}
}
在闭包中会默认加上final修饰
public class ClosureDemo{
public static void main(String[] args){
int a = 10; //final
Consumer<Integer> c = ele -> {
System.out.println(a);
}
a++;
c.accept(1);
}
}