今天小编学习了Lambda表达式,瞬间感觉到了Java的魅力,就让我来为大家介绍这个朴素却功能强大的表达式吧!
Lambda表达式是什么?
Java8(JDK1.8)才能使用
Lambda表达式是一个匿名函数, 我们可以把Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使得Java语言表达能力得到了提升。
Java8中引入了一个新的操作符” -> ”该操作符称为箭头操作符或Lambda操作符, 箭头操作符将Lambda表达式拆分为两部分:
左侧:Lambda表达式的参数列表。对应接口中抽象方法的参数列表。
右侧:Lambda表达式中所需要执行的功能,即Lambda体。对应接口中抽象方法的实现。
接下来让小编直接通过代码告诉大家如何使用Lambda表达式:
先要声明一个接口,但只能有一个抽象函数。
interface Sky{
void flyer();
default void swim(){
System.out.println("我会游泳");
}
}
在主方法中添加调用,运行结果就出来了。
Sky a=()-> System.out.println("我会飞");
a.flyer();
该种形式即为Lambda的写法,其中 Sky a 规定了此时使用的接口类型, ( ) 为参数列表, {System.out.println("我会飞");} 为方法体, 非常重要的 -> 即为参数列表和方法体的分割符。是不是感觉逼格满满,代码就几行,却能实现一个功能!(可能会有人说不就是个打印吗?我一句System.out.println就能解决,)我们表面实现的是一个打印功能,如果把这个功能换成其他的复杂的功能,那么绝对会让你大开眼界!
Lambda语法
现在我们可以使用Lambda代替创建匿名函数的部分,Lambda的语法如下。
函数式接口
接口中有且仅有一个抽象方法的接口,称为函数式接口。 default 修饰方法只能在接口中使用(只能被实现了这个接口的对象调用),在接口种被default标记的方法为普通方法,可以直接写方法体。
可以使用注解 @FunctionalInterface 修饰, 可以检查是否是函数式接口。 Lambda表达式需要函数式接口的支持 。
以前我们整个java的继承关系已经使用了很多年,如果在java新版本中为了迎合函数式接口一个接口中只有一个抽象方法,会导致以前很多接口失效,那么别人也没法进行jdk的升级所以提供了默认方 法,在jdk1.8之后,可以在接口中定义默认方 法。
无参数,无返回值
只要有接口就有可以使用Lambda,根据接口中提供的抽象方法,可以有不同的 Lambda。
要求存在一个接口,接口中存在一个方法,方法无参无返回值即可。直接上代码:
Sky a=()-> System.out.println("我会飞");
a.flyer();
a.swim();
Test1(()-> System.out.println("我也会飞"));
//无参无返回值
public static void Test1(){
a.flyer();
}
无参: () 不能给形式参数无返回值:代码块中不能存在 return+ 数据的形式。
带一个参数,无返回值
要求存在一个接口,接口中存在一个方法,方法带一个参数无返回值即可。 一个参数时小括号可以省略。
1、存在一个接口,接口中只有一个带一个参数并且无返回值的抽象方法
2、在需要 使用到无参无返回值的场景下使用该方法完成特定功能,即给定Lambda表达式,直接上代码:
Sky1 a1=(asd)-> System.out.println("我想飞"+asd);
a1.flyer1("我能飞");
//接口
@FunctionalInterface
interface Sky1{
void flyer1(String a);
default void swim(){
System.out.println("我会游泳");
}
}
当然,在接口中也可以使用泛型。
有参有返回值
要求存在一个接口,接口中存在一个方法,方法带若干个参数并且有返回值返回值即可。
此时代码块中必须出现 return + 对应数据
1、存在一个接口,接口中只有一个带若干参数并且带返回值的抽象方法
2、在需要使用到无参无返回值的场景下使用该方法完成特定功能,即给定Lambda表达式,代码如下:
//有参有返回值
Sky2 a2=(sad)-> {
String b2=sad+"我飞起来很快";
return b2;
};
System.out.println(a2.flyer2("我是飞机"));
//接口
@FunctionalInterface
interface Sky2{
String flyer2(String a);
default void swim(){
System.out.println("我会游泳");
}
}
四大内置函数式接口
Lambda的实现依赖于函数式接口,接口可以我们自己定义,当然也可以使用JDK已 经提供好的一些函数式接口,这些接口基本已经能够满足我们的常用操作,并且在集合等框架中已经广泛地使用了,所以我们可以直接使用这些接口。
消费型、供给型、函数型、断定型
消费型接口 Comsumer void accept(T t) 消费型:只进不出
供给型接口 Supplier T get() 供给型:白手起家,空手套白狼
函数型接口 Function R apply(T t) 函数型:礼尚往来
断定型接口 Predicate boolean test(T t) 断定型:鉴定评审
注意:关注的只有接口中方法的参数和返回值即可
Consumer 消费型接口
带一个参数,在方法体中使用完了就完了,例如在Collection中的 forEach 方法则 需要一个Consumer接口的实现类对象。
List<String> list=new ArrayList<>();
list.add("saddsa");
list.add("sdsa");
list.add("safdfds");
list.add("ttrterdsa");
list.forEach(t-> System.out.print(t+" "));
典型的消费型
Supplier 供给型接口
A(5,()->{
return (int)(Math.random()*11);
}).forEach(t-> System.out.print(t+" "));
//方法函数
public static List<Integer> A(int a, Supplier<Integer> b)
{
List<Integer> list2=new ArrayList<>();
for (int i=0;i<a;i++)
{
list2.add(b.get());
}
return list2;
}
Function 函数型接口
System.out.println(stringMaker("我要飞", (s) -> {
String b = " " + s + " ";
return b;
}));
//方法
//函数型
public static String stringMaker(String a, Function<String,String> b)
{
return b.apply(a);
}
Predicate 断定型接口
System.out.println(A2(list, s -> {
return s.length() > 6;
}));
//接口
//判断型
public static List<String> A2 (List<String> list, Predicate<String> p)
{
List<String> list1=new ArrayList<>();
list.forEach(t->{
if (p.test(t))
{
list1.add(t);
}
});
return list1;
}
所有代码都已经上传,想要学习请自行下载(开源1积分,因为这个真的很装逼)。
总结:lambda表达式很朴素,但功能强大,学会使用绝对使一般Java开发者逼格提升一大截。
学而不思则罔,思而不学则殆。