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 Lambda 新人必知(一)_第1张图片

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表达式的优势:

到这里有人可能会说这个匿名函数没什么大的区别嘛,干嘛要整个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,lambda,java8)