1,lambda表达式的分类
简单的Lambda表达式 (str)->str.toUpperCase();
->号称之为lambda操作符或者成为剪头符。
这个符号的左侧我们称之为lambda表达式的参数侧,而右侧我们称之为lambda表达式的lambda体,,这个测体我门只要使用来表示lambda表达式的操作以及功能。
准备:
函数式接口:只含有一个抽象方法的接口称为函数式接口。
Lambda:通过Lambda表达式可以创建函数式接口的对象。如果Lambda表达式是一个受检异常那么就应该在抽象方法中进行声明。同时我们可以在任意的函数式接口上使用
@FunctionInterface注解来标识以及检查它是否是一个函数式接口。javadoc也会有一条声明标识是否就是一个函数式接口。
注意:当函数式接口里面得方法已经实现了那么我们就可以直接使用方法的引用。
注意:接受Lambda表达式的参数类型一定要与Lambda表达式兼容的接口类型相匹配。
(1)消费型接口Consumer,,提供类型为T,无返回值类型或者返回值类型为void。抽象方法就是accept。
(2)供给型接口supplier接口,没有参数类型或者参数类型为空,有返回值类型一般返回值类型为T.。抽象方法就是get。
(3)函数式接口,Function<T,R> fun,,就是将T类型的对象然后执行以系列操作最后就是返回结果。而这个结果就是R类型的对象。
(4)断言式接口:predictate pre:,断言式接口其实就是对某一个对象对象T进行判断然后就可以确定它是否满足某种约束。返回值类型就是boolean类型的,符合约束就是True
,,反之就是false。
2,注意:一些特殊简写,
(1)当lambda表达式的参数只有唯一一个时候,那么就可以将小括号去掉。
(2)当lambda函数体里面只有一条执行语句那么就可以省略return语句以及大括号。
(3)由于lambda表达式可以在编译阶段通过编译器根据上下文内容进行类性推断。因此小括号里面得参数类型也是可以进行类型擦除的。
3,方法引用以及构造器引用
(str)->str.toUpperCase();
(1)当lambda体的操作已经实现那么我们就可以使用方法引用,实现抽象方法的参数列表一定要与方法引用的方法的参数列表保持一致。
方法引用(格式):使用操作符 :: 将对象或类名与实例方法以及静态方法分隔开来。
一般存在三种方法引用方式:类::静态方法,类::实例方法,对象::实例方法
4,面试以及笔试中以及JDK8编程中最喜欢问的问题
在一个list集合里面有一些学生student,,我门需要找出成绩分数大于90的学生。。(要求使用最简便的方式)–也就是Lambda编程。
断言型接口:Predicate 来实现
package 比较器java特性;
// 使用JDK8新特性,Lambda表达式来编写代码果然有效,简洁灵活
import java.util.*;
import java.util.function.Predicate;
public class Lambda寻找符合条件的对象 {
public static void main(String[] args) {
List<student2> list=new ArrayList<>();
student2 s1=new student2("lzq",92);
list.add(s1);
student2 s2=new student2("zwj",92);
list.add(s2);
student2 s3=new student2("hehe",89);
list.add(s3);
List<student2> ans=filterstudent(list,(s)->s.grade>90);
for(student2 s:ans) {
System.out.print(s.name+" ");
}
}
public static List<student2> filterstudent(List<student2> list,Predicate<student2> pre){
List<student2> list2=new ArrayList<>();
for(student2 s:list) {
if(pre.test(s))
list2.add(s);
}
return list2;
}
}
class student2{
String name;
int grade;
student2(String name,int grade){
this.name=name;
this.grade=grade;
}
}