目录 前言:
Lambda表达式初体验:
Lambda表达式的转变过程:
Lambda表达式的优势:
Lambda表达式的使用:
未完待续:
前言: 本人大学读的是电子信息工程,和大部分人一样毕业后没有从事本专业的工作,2014年毕业后先后干过:
- QT编程(C++)
- Linux嵌入式编程(C)
- Java后台开发(Java)
半路出家做java开发已经两年了,之前一段日子一直是浑浑噩噩,最近看了一些书,《人性的弱点》,《软技能》,《自控力》对我启发颇多,决定每个星期更新一篇技术博客,来总结一下学到的知识,也分享给大家,希望对大家有所帮助,好了,废话已经说了一堆了正式开始进入正题。
Lambda表达式初体验: 第一次在代码中体验lambda表达式是在使用策略模式中使用匿名类的时候,idea编译器竟然对我的其中一个函数调用的代码灰色字体提示,但我自认为写的非常的规范:
//真是代码是用策略模式 对不同的锁动态密码使用不同的算法
//由于真实的代码比较复杂,用《java8实战》中的代码代替一下,见谅
//这个例子是用策略模式 对不同类型的苹果进行筛选/**
* 苹果类
*/
public class Apple {
private String color;
private int weight;
public Apple(String color, int weight) {
this.color = color;
this.weight = weight;
}public String getColor() {
return color;
}public void setColor(String color) {
this.color = color;
}public int getWeight() {
return weight;
}public void setWeight(int weight) {
this.weight = weight;
}
} /********************************************************//**
* 苹果筛选接口
*/
public interface ApplePredicate {
boolean test (Apple apple);
}/********************************************************/import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* 苹果过滤器类
*/
public class AppleFilter {
//苹果过滤器
public List filterApples(List apples, ApplePredicate predicate) {
List result = new ArrayList<>(apples.size());
for (Apple apple : apples) {
if (predicate.test(apple)) {
result.add(apple);
}
}
return result;
}//摘苹果
public static List pickApples(int num) {
List apples = new ArrayList<>(num);
Random random = new Random(2);
for (int i = 0;
i < num;
i++) {
String randomColor = random.nextBoolean() ? "red" : "green";
int randomWeight = random.nextInt(100) + 200;
Apple apple = new Apple(randomColor, randomWeight);
apples.add(apple);
}
return apples;
}//打印苹果信息
public static void printApples(List apples) {
System.out.println("Apples nums:" + apples.size());
for (int i = 0;
i < apples.size();
i++) {
if (i % 5 == 0) {
System.out.println();
}
System.out.print(apples.get(i) + ",");
}
System.out.println();
System.out.println("-----------------------------------------------------------");
}//测试
public static void main(String[] args) {
int num = 100;
//农民伯伯采摘了100个苹果
List apples = pickApples(num);
printApples(apples);
AppleFilter filter = new AppleFilter();
//收购商说要红苹果,让农民伯伯把苹果放入机器筛选红苹果出来
List applesResult1 = filter.filterApples(apples, new ApplePredicate() {
@Override
public boolean test(Apple apple) {
return "red".equals(apple.getColor());
}
});
printApples(applesResult1);
}
}
文章图片
What?你这是凭什么给我报啊(程序员一般都对自己比较自信!),怀着疑惑的心情Alt+Enter查看到底是什么问题?
看到了这样的一个提示:
文章图片
Replace with lambda?lambda是什么鬼,无知的我,处于好奇,点击了它,我去!
神奇的事情发生了,眼前代码脱胎换骨:
文章图片
我的代码摇身一变,这是减肥了?!
从匿名类 new ApplePredicate() { @Override public boolean test(Apple apple) { return "red".equals(apple.getColor()); } }到lambda apple -> "red".equals(apple.getColor())
我的代码你到底经历了什么?
带着这样的疑问,让我们一起来一探究竟把。
Lambda表达式的转变过程: 正如你所见,你仔细观察一下这个苗条的姑娘(lambda表达式),你就会发现她还是原来的她,
apple 对应匿名函数中 test(Apple apple)方法的参数,
"red".equals(apple.getColor()) 对应test(Apple apple)的方法内容
姑娘就是系了根腰带 (->),而且变瘦了(省略了其他部分)
好了让我们来看看lambda的真面目吧!
lambda由三部分组成:
- 参数列表——一个参数可以省略(),没有参数或多个参数要加上(), 参数之间要加上逗号隔开。
- 箭头——箭头->把参数列表与Lambda主体分隔开。
- Lambda主体——主题单句时不需要{},此时因为是表达式所以句尾不用加; , 当加上{}时,便成为了语句,此时语句可以有多句,每句都要有;最后有返回类型的时候要加上 return。表达式的返回值就是Lambda的返回值了。
Lambda表达式的优势: 到这里有人可能会说这个匿名函数没什么大的区别嘛,干嘛要整个lambda出来啊,这不是找麻烦啊。
兄dei!不要急,这就来讲讲lambda的优势。
还是先看个例子,筛选好了以后,收购商发现这里面混杂这小苹果,他觉得小苹果不能以一样的价格收,于是他又提出来要把240克一下的苹果全部剔除出来,以更便宜的价格收购。农名伯伯和无奈啊,只能照做了,按照匿名的方式这回应该这么做:
//农民伯伯心不甘情不愿的筛选出了小苹果
List applesResult2 = filter.filterApples(apples,new ApplePredicate() {
@Override
public boolean test(Apple apple) {
return apple.getWeight() > 240;
}
});
这时,农民伯伯气不过啊,凭什么你要大就大啊,于是他偷偷摸摸的又把大的苹果自己拿出来,打算自己去卖。
//农民伯伯挑出了绿苹果和大苹果,打算自己卖
List applesResult3 = filter.filterApples(apples,new ApplePredicate() {
@Override
public boolean test(Apple apple) {
return apple.getWeight() > 280 || "green".equals(apple.getColor());
}
});
到这个时候,相信大家已经发现,这么做,里面有很多的代码是重复的,多余的,那如果使用lambda呢?会是神马效果?
//农民伯伯心不甘情不愿的筛选出了小苹果
List applesResult2 = filter.filterApples(apples, apple -> apple.getWeight() > 240);
//农民伯伯挑出了绿苹果和大苹果,打算自己卖
List applesResult3 = filter.filterApples(apples, apple -> apple.getWeight() > 280 || "green".equals(apple.getColor()));
一下子就变成了最精简的代码了,程序员估计都喜欢苗条的把,哈哈,没错lambda表达式去除了匿名函数啰嗦的部分变得更加的精简和直观。
Lambda表达式的使用: 可能看到这里,大家对lambda的优点有所了解,但是可能对到底怎么了使用lambda表达式还是一头雾水。来来来,别急,上干货了,
首先我们先要明确 Lambda表达式是使用在函数式接口上的, 什么是函数式接口?函数式接口就是只定义一个抽象方法的接口(没有,或多个都不行)。Lambda表达式允许你直接以内联的形式为函数式接口的抽象方法提供实现, 并把整个表达式作为函数式接口的实例(具体说来,是函数式接口一个具体实现的实例),
在实际代码中的使用来给个例子:
常常会遇到读取文本的代码,比如这样:
//读取文本的第一行
public static String processFile() throws IOException {
try (BufferedReader br =
new BufferedReader(new FileReader("data.txt"))) {
return br.readLine();
}
}
直接这样写有点low,如果需要读两行,三行,n行呢?我们先来参数化
@FunctionalInterface
public interface BufferedReaderProcessor {
String process(BufferedReader b) throws IOException;
}public static String processFile(BufferedReaderProcessor p) throws
IOException {
…
}
使用lambda表达式有个模式:环绕执行模式
第 1 步:行为参数化
第 2 步:使用函数式接口来传递行为
第 3 步:执行一个行为
第 4 步:传递 Lambda
这样是不是给力多了呢?
未完待续: 发现写个博客还出挺耗时间的?不知不觉夜已深了,洗洗睡了,但是精彩的lambda知识内容只是个开头啊,大家可以关注我,继续我们的lambda旅程。
【java8|Java8 Lambda 新人必知(一)】
推荐阅读
- Java16都快上线了,你该不会连Java8的特性都不会用吧()
- Python 之 map函数 及lambda函数
- Java ASM系列((067)Java 8 Lambda原理探究)
- JDK新语法|一文让你掌握Stream流,还是那么自信
- 确定我们是否在AWS Lambda + Zappa下运行()
- java8实战学习
- 使用AWS Lambda@Edge进行灵活的A/B测试
- 基于Dapper的开源Lambda扩展,且支持分库分表自动生成实体基础
- Python|Python函数式编程学习(lambda, map, reduce, filter)