Java8于2014年发布,其最重要的新特性,便是支持了lambda表达式。那么,什么是lambda表达式呢?我的理解是,lambda表达式是一个匿名函数,可以赋值给一个变量。其他语言如JavaScript非强类型的可以直接赋值,但是,java中一切皆对象,赋给的值需要是“函数式接口”类型(Java8注解@FunctionalInterface
标记的接口,只有一个抽象方法的接口),当然,普通的接口类型也可以,lambda充当接口的实现类,如下图Runnable
接口。Java8还提供了很多函数式接口方便我们开发,在java.util.function
包中。
![](https://img.haomeiwen.com/i8746907/dd59ccf7e51fcf7b.png)
更多关于lambda表达是,可以参考本篇文章底部的“参考资料”,可以先看下Mingqi在知乎上的回答,Lambda 表达式有何用处?如何使用? - Mingqi的回答 - 知乎,以下是我的个人总结。总之,java中lambda表达式虽然使得代码相当精简,不过可读性不高,后期很难维护,个人不建议项目中使用lambda表达式。
lambda表达式最规范的形态是(parameters) ->{ statements; }
,其可以赋值给一个接口,如MyInterface i = (String s, Interger i) -> { Sysout.out.println(s + " " + i); }
。当然,参数类型可以省略。同时如果parameters只有一个参数,可以省略小括号,statements只有一条语句,可以省略花括号。如x -> System.out.println(x)
。
lambda常用模式
OK,接下来试试lambda的用法。首先,我们说lambda需要赋值给接口类型,那么这里,我们定义一个接口,只有一个方法printAString()
打印一个字符串。
public interface MyInterface {
void printAString (String s);
}
![](https://img.haomeiwen.com/i8746907/2f5fe93fdd867f82.png)
有了接口,一般我们需要新建一个实现类才能使用该接口,现在不用啦,用lambda搞定,如下,测试接口的实现。
import me.zebin.demo.lambdademo.service.MyInterface;
import org.junit.Test;
public class MyInterfaceTest {
@Test
public void testPrintAString(){
MyInterface i = x -> System.out.println(x);
i.printAString("hello lambda");
}
}
顺利执行。
![](https://img.haomeiwen.com/i8746907/ac01a771843b49fd.png)
![](https://img.haomeiwen.com/i8746907/8dd1c0feec606cab.png)
嗯,在这里可以看到lambda的方便之处了吧,不用新建实现类就能通过lambda定义实现来调用方法了。
如果我们在接口新增一个方法呢,是否可行,如下,lambda报错了,因为lambda的接口只能有一个方法。
![](https://img.haomeiwen.com/i8746907/abd47de2160819c5.png)
![](https://img.haomeiwen.com/i8746907/e5108b056c6a297a.png)
为了防止协同开发过程中,其他人在lambda接口中新增了方法导致别人的报错。可以在接口上加@FunctionalInterface,如下@FunctionalInterface只能有一个方法,否则编译器会报错。
![](https://img.haomeiwen.com/i8746907/64630baa555bbb8f.png)
有了lambda,我们以后先线程就不用匿名内部类了,因为Runnable接口也是一个FunctionalInterface。
forEach循环
java的集合类,都实现了Iterable
接口,该接口中定义了forEach
方法,故结合类基本都能使用该方法。如下,该方法接受一个Consumer
类型的接口,并执行他的accept
方法。Consumer
是一个java.util.function
中的@FunctionalInterface
接口。
![](https://img.haomeiwen.com/i8746907/64d16fc2695c3216.png)
假设我们定义了一个List中有一组Person,遍历输出这些Person的姓名,那么可以使用lambda表达式如下执行。
Person类如下:
public class Person {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
forEach打印测试如下:
public class PersonTest {
@Test
public void testPerson(){
// 构造一个list
List<Person> l = new ArrayList<>();
l.add(new Person("zhangsan", 20));
l.add(new Person("lisi", 21));
// foreach 循环打印
l.forEach(x -> System.out.println(x.getName()));
}
}
运行结果如下:
![](https://img.haomeiwen.com/i8746907/ecc96b3b82a40afa.png)
本篇就写到这里啦,早上起来写的,上班去。
参考资料
Lambda 表达式有何用处?如何使用? - Mingqi的回答 - 知乎
The Java™ Tutorials(官方文档)
猴子小皮球的简书
网友评论