一、什么是Lambda表达式
lambda表达式是一个匿名函数,是一段可以传递的代码,可以简化大量使用的匿名内部类。
语法:()->{}
左侧:对应接口中抽象方法的参数列表
右侧:对应接口中抽象方法的实现
前提:函数式接口,接口中有且仅有一个抽象方法的接口
1、无参数,无返回值
()-> {}
public static void main(String[] args){
NoParamNoResult something = ()-> System.out.println("Hello World");
something.test();
something = ()->{System.out.println(Math.random());};
something.test();
}
interface NoParamNoResult{
void test();
}
2、带一个参数,无返回值
(参数名)->{} // 参数类型可以省略,由编译器自动推
参数名 ->{} // 当只有一个参数时,()可以省略
public class Demo1 {
public static void main(String[] args){
OneParamNoResult something = (String str)-> System.out.println(str);
something.test("Hello World");
something = (str)->{System.out.println(str.toLowerCase());};
something.test("sAfwAEFE");
}
interface OneParamNoResult{
void test(String str);
}
}
3、有参数,有返回值
(形参名1,形参名2)->{return data}
public class Demo2 {
public static void main(String[] args) {
OneParamNoResult something = (String str, Integer i) -> {
String newStr = str;
for (; i > 0; i--) {
newStr += str;
}
return newStr;
};
String newStr = something.test("hello world", 3);
System.out.println(newStr);
}
interface OneParamNoResult{
String test(String str,Integer i);
}
}
二、四大内置函数式接口
Lambda的实现依赖于函数式接口
接口可以我们自己定义,也可以使用jdk已经提供好的一些函数式接口。
(1) 消费性接口 Comsumer : 只进不出
void accept(T t)
案例:Collection中的forEach方法需要一个consumer接口的实现类对象。
ArrayList<String> list = new ArrayList<>();
list.add("AAA");
list.add("BBB");
list.add("CCC");
list.forEach(t->System.out.println(t));
(2) 供给型接口 Supplier :白手起家,空手套白狼
T get()
List<Integer> numberList = getNumList(10,()->(int)(Math.random() * 100));
numberList.forEach(n->System.out.println(n));
public static List<Integer> getNumList(int num, Supplier<Integer> sup){
List<Integer> list = new ArrayList<>();
for(int i = 0; i < num; i++){
Integer n = sup.get();
list.add(n);
}
return list;
}
函数型接口 Function<T,R> :礼尚往来
R apply(T t)
String newStr = strHandler(" shsxte ",(str)->{
return str.trim();
});
System.out.println(newStr);
newStr = strHandler("shsxt",str-> {return str.substring(0,5);});
System.out.println(newStr);
public static String strHandler(String str, Function<String,String> fun){
return fun.apply(str);
}
断定型接口 Predicate :鉴定评审
boolean test(T t)
Predicate<Integer> pre = (i) -> i > 1;
System.out.println(pre.test(5));
List<String> strList = List.of("hello","orange","ok");
List<String> newStrList = filter(strList,s-> s.length() > 3);
newStrList.forEach(s->System.out.println(s));
public static List<String> filter(List<String> list,Predicate<String> pre){
List<String> strList = new ArrayList<>();
list.forEach(string->
{
if(pre.test(string)){
strList.add(string);
}
});
return strList;
}
三、方法引用
若lambda体重的内容有方法已经实现了,我们可以使用“方法引用”,主要有三种语法格式:
(1)对象::实例方法名
Consumer<String> con = (x)->System.out.println(x);
PrintStream ps = System.out;
Consumer<String> con1 = ps :: println;
Consumer<String> con2 = System.out::println;
con2.accept("shsxt");
List<String> list2 = List.of("ss","cc","dd");
Supplier<String> sup = ()-> list2.get(0);
String str = sup.get();
System.out.println(str);
Supplier<Integer> sup2 = list2::size;
int size = sup2.get();
System.out.println(size);
(2)类::静态方法名
Comparator<Integer> com = (x, y)->Integer.compare(x,y);
Comparator<Integer> com1 = Integer::compareTo;
(3)类::实例方法名
BiPredicate<String,String> bp = (x,y)->x.equals(y);
BiPredicate<String,String> bp1 = String::equals;
(4)构造器引用
Supplier<Employee> supplier = ()-> new Employee();
Employee emp = supplier.get();
Supplier<Employee> sup1 = Employee::new;
Employee emp1 = sup1.get();
System.out.println(emp1);
Function<Integer,Employee> func = (x)->new Employee(x);
func.apply(20);
Function<Integer,Employee> func2 = Employee::new;
Employee emp2 = func2.apply(18);
BiFunction<Integer,String,Employee> bf = Employee::new;
Employee emp3 = bf.apply(20,"张三");
System.out.println(emp3);