java8|Java8 Lambda 新人必知(一)

目录 前言:
Lambda表达式初体验:
Lambda表达式的转变过程:
Lambda表达式的优势:
Lambda表达式的使用:
未完待续:
前言: 本人大学读的是电子信息工程,和大部分人一样毕业后没有从事本专业的工作,2014年毕业后先后干过:

  • QT编程(C++)
  • Linux嵌入式编程(C)
  • Java后台开发(Java)
打算学习一下大数据(python)不要问我为什么做的这么杂,因为世界唯一不变的就是变。
半路出家做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); } }


java8|Java8 Lambda 新人必知(一)
文章图片

What?你这是凭什么给我报啊(程序员一般都对自己比较自信!),怀着疑惑的心情Alt+Enter查看到底是什么问题?
看到了这样的一个提示:
java8|Java8 Lambda 新人必知(一)
文章图片

Replace with lambda?lambda是什么鬼,无知的我,处于好奇,点击了它,我去!
神奇的事情发生了,眼前代码脱胎换骨:
java8|Java8 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表达式的优势: 到这里有人可能会说这个匿名函数没什么大的区别嘛,干嘛要整个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 新人必知(一)】

    推荐阅读