开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第6天,点击查看活动详情
0.背景
话说啊,咱们快餐店老板因为瞎搞濒临破产,危难之际,虾搞一通餐饮有限公司收购了它。我们的程序员小孙开始了新的生活。
1.面向接口编程
小孙因为得到老安的指点,学了两招以后,便喜欢上了学习。这一天,老安自由了。小孙也没注意到他,全身心在学习。
因为老安到这一天,正好满135岁了,HR 给他过了个生日,说老安年龄大了,应该转到保安处看大门。老安拒绝了,他笑了笑,摆摆手:“算了吧,真遇到坏人,我这把老骨头,谁保护谁啊?”说完,他潇洒地离去了。
花开两朵,各表一枝。小孙苦练起了面向接口编程,写出了一个这样的接口:
public interface YoungPersonService {
boolean isYoung(int age);
}
小黄笑话他:“就这么个东西还写个接口啊?真是画蛇添足,哈哈!”
小孙生气了:“这是面向接口编程,你不懂!”
小黄说:“什么面向接口编程,咱们还不是面向领导编程?领导就爱拍脑袋决策,咱们是面向拍脑袋编程,哈哈……”
老罗听到了他们在吵闹,就问他们发生了什么。小孙和小黄一五一十地说了经过。老罗一边擦护手霜,一边说:“如果说一个接口,只有一个函数,确切来说只定义了一个抽象方法,那么,这就是函数式接口。小朋友们,函数式接口非常有用,它是 Lambda 表达式思想的前身”
2.函数式接口与 Lambda 表达式
Lambda表达式允许你直接以内联的形式为函数式接口的抽象方法提供实现,并把整个表达式作为函数式接口的实例(具体说来,是函数式接口一个具体实现的实例)。你用匿名内部类也可以完成同样的事情,只不过比较笨拙:需要提供一个实现,然后再直接内联将它实例化。——《Java实战》
仔细想想,我们在书写 Lambda 表达式的时候,是不是只写了一个函数,就开始了处理?我们在写filter的条件时是不是也是直接就上手写了?好了,我们稍微改一下刚才的代码,然后做一个测试。为了减少学习恐惧感,我们还是 Predicate 。
我们还是判断一个员工是否为年轻人:
public interface YoungPersonService extends Predicate<UserTests.User> {
}
我们制作一个年轻员工的服务:
public class YoungEmployeeServiceImpl implements YoungPersonService {
@Override
public boolean test(UserTests.User user) {
if (user == null) {
return false;
}
if (user.getAge() < 35) {
return true;
}
return false;
}
}
最后我们使用它:
public class UserTests {
public static class User {
private int age;
public User(int age) {
this.age = age;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return "User{" +
"age=" + age +
'}';
}
}
public static void main(String[] args) {
List<User> userList = new ArrayList<>();
for (int i = 18; i <= 50; i++) {
User user = new User(i);
userList.add(user);
}
List<User> elders = userList.stream()
.filter(new YoungEmployeeServiceImpl())
.collect(Collectors.toList());
System.out.println(elders);
}
}
小孙说:“这有点复杂,我看懵了。”老罗笑了笑:“别急,临时需求,我们用Lambda”
public class UserTests {
public static class User {
private int age;
public User(int age) {
this.age = age;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return "User{" +
"age=" + age +
'}';
}
}
public static void main(String[] args) {
List<User> userList = new ArrayList<>();
for (int i = 18; i <= 50; i++) {
User user = new User(i);
userList.add(user);
}
List<User> elders = userList.stream()
.filter((user -> user.getAge() < 35))
.collect(Collectors.toList());
System.out.println(elders);
}
}
小孙和小黄都拍手叫好,感受到了简洁。
小黄问老罗:“老罗,不说这个业务,你觉得什么算是年轻人?”老罗说:“年岁有加,并非垂老,理想丢弃,方堕暮年。”小孙和小黄又都拍手叫好,竖起大拇指,老罗不好意思地低下了头。
结语
本例中,我们介绍了函数式接口以及Lambda表达式。这两种编程思维对于现代编程语言都非常重要,良好的设计可以为我们减少因需求变动而带来重构的次数。你还想到哪些应用呢?欢迎你在评论区和我讨论!