Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。
Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
使用 Lambda 表达式可以使代码变的更加简洁紧凑。
允许将函数作为一个方法的参数(将一个方法传递到另外的方法中执行),本质上可以理解为是一种语法糖。
语法格式:
(参数列表)->表达式,例如(k1,k2)-> k1+k2
(参数列表)->{代码块;},例如(k1,k2)->{return k1+k2;}
可选的类型声明;不需要声明参数类型,编译器可以统一识别参数类型
可选的参数圆括号,一个参数无需使用(),但是如果多个参数则需要使用()
可选的大括号,如果主体中包含一个语句,则不需要使用{}
可选的return关键字,如果主体中只有一个表达式返回值则编译器自动返回,不需要使用return
使用样例:
不需要参数,返回值为5 ()->5
接收一个参数,返回值为乘以3: x->3*x
接收2个参数,返回差值: (x,y)->x-y
接收2个int类型参数,返回和: (int x, int y)->x+y ,也可以 (x,y)->x+y
接收一个string类型参数,在控制台打印输出,不返回任何值(void):(String s)->System.out.println(s)
实例:
1、首先需要一个函数式接口,接口中只能有一个抽象方法
public interface MathOperation{
int operate(int a, int b);
}
2、在Test类中具体使用接口
public int operator(int a, int b, MathOperation operation){
int res=operation.operate(a,b);
System.out.println("计算结果为:"+res);
}
3、调用处通过lambda表达式提供接口的实现
MathOperation addition=(int a,int b)->a+b;//也可以写成(a,b)->a+b,还可以(int b,int b)->{return a+b;}
Test test=new Test();
System.out.println("10+5="+test.operator(10,5,addition));
内置4大函数式接口
Consumer消费性接口 void accept(T t)
Supplier供给性接口 T get()
Function函数式接口 R apply(T t)
Predicate断言式接口 boolean test(T t)
Consumer:
方法定义:
public void bb(double num, Consumer<Double> consumer){
consumer.accept(num);
}
调用:
Test1 test=new Test1();
test.bb(1000,num->System.out.println(num));
Supplier:
需求:产生指定个数num的整数,并放入集合中
public List<Integer> getNumList(int num,Supplier<Integer> supplier){
List<Integer> res=new ArrayList<>();
for(int i=0;i<num;i++){
Integer tmp=supplier.get();
res.add(tmp);
}
return res;
}
调用:
List<Integer> res=getNumList(10,()->(int)(Math.random()*200));
System.out.println(res);
Function:
进行字符串的转换处理:
public String handleString(String str,Function<String,String> function){
return str.apply(str);
}
调用:
String str1=handleString("abc",str->str.toUpperCase());
String str2=handleString(" abbc ",(String str)->{
return str.trim();
});
Predicate:
调用断言对传入的数据进行判断:
public static List<String> filterString(List<String> list, Predicate<String> predicate) {
List<String> res = new ArrayList<>();
for (String tmp : list) {
if (predicate.test(tmp))
res.add(tmp);
}
return res;
}
调用:
List<String> list=Arrays.asList("Hello","yan1","lambda","ok","xxx");
List<String> res=filterString(list,(str)->str.length()>2);
特殊方法:
对象名::实例方法名
//普通写法
PrintStream ps=System.out;
Consumer<String> consumer= (x)->ps.println(x);
consumer.accept("ddh!");
//简写
Consumer<String> consumer2=ps::println; //等价于3
consumer2.accept("ddh2!");
//更简单的写法
Consumer<String> consumer3=System.out::println;
consumer3.accpet("ddh3");
类名::静态方法
//Comparable和Comparator接口
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj); //特殊方法
default Comparator<T> reversed() {
return Collections.reverseOrder(this);
}
public static <T> Comparator<T> comparingDouble(ToDoubleFunction<? super T> keyExtractor) {
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable)
(c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2));
}
}
调用:
//普通写法
Comparator<Integer> comparator=(x,y)->Integer.compare(x,y);
//简化写法
Comparator<Integer> comparator2=Integer::compare;
类名::实例方法名
如果lambda表达式中第一个参数式实例方法的调用者,而第二个参数是实例方法的参数时可以使用【类名::实例方法名】的形式
//普通写法
BiPredicate<String,String> bp=(x,y)->x.equals(y);
//简化写法
BiPredicate<String,String> bp2=String::equals;
调用构造器:
//普通写法
Supplier<User> supplier= ()->new User();
//简化写法
Supplier<User> supplier2=User::new; //调用默认的无参构造