java中的lambda表达式浅析

关于lambda,相信现在很多朋友都不陌生,包括工作中或多或少都有用到,或者见到,一些简单的使用见多不惯了,比如我们在写线程时可以这样写,new Thread(() -> {//...}),看上去代码精简了很多,简洁明了,所以lambda的使用可以帮助我们开发人员写出想对比较优雅的代码,没有那么冗余,如果还没有掌握lambda的童鞋可以侧重看下本篇博客,希望对你有所帮助,如有误处,欢迎大佬指点,不胜感激。

在说lambda使用之前,应该认识什么是lambda:

  1. lambda 函数是一个可以接收任意多个参数(包括可选参数)并且返回单个表达式值的匿名函数。 (注意:lambda 函数不能包含命令,它们所包含的表达式也不能超过一个)
  2. lambda函数比较轻便,即用即扔,很适合需要完成某一项简单功能,但是这个简单的功能只在此一处使用,连名字都很随意的情况下;
  3. lambda是匿名函数,一般用来给filter,map,reduce这样的函数式编程服务;
  4. 作为回调函数,可以传递给某些应用,比如消息处理等。

举一个lambda应用非常简单的栗子:

@Data
class Person {
    private int age;
    private String name;
    private String firstName;
    private String gen;
}


 public static List<Person> getPersons(int personNum) {
        String[] firstName = {"孙","上官","刘","李","赵","李","王","张"};
        String[] endName = {"宏强","三","四","壁咚","古来","八戒","恒达"};
        List<Person> personList = new ArrayList<>();
        for (int i = 0; i < personNum - 1; i++) {
            int findex = new Random().nextInt(firstName.length);
            int eindex = new Random().nextInt(endName.length);
            int age = (findex + 1) * (eindex +1);
            Person person = new Person();
            person.setAge(age);
            person.setName(endName[eindex] + firstName[findex]);
            person.setFirstName(firstName[findex]);
            person.setGen(age % 3 ==0?"男":"女");
            personList.add(person);
        }
        return personList;
    }

用上面person作为集合元素,求出集合中男的人数有多少,ok,想都不用想直接噼里啪啦搞起:

         List<Person> persons = getPersons(14);
         int count = 0;
    
        Iterator<Person> iterator = persons.iterator();
        while (iterator.hasNext()) {
            Person next = iterator.next();
            if (next.getGen().equals("男"))
                count++;
        }

或者使用for循环直接遍历等等,既然说lambda,我们看一下lambda结合stream的写法:

long count1 = persons.stream().filter(x -> x.getGen().equals("男")).count();

我们用lambda编码后,会发现整个代码看起来简洁了不少,而且相信聪明的你,一眼就能看懂是什么意思,没错,lambda就是结合函数式编程的一种应用思想,接触过函数式编程的朋友肯定非常容易上手,像我这种没有接触过的,趁机小补了一把,那问题来了,什么是函数式呢?我举个简单的例子,超级超级简单的那种:

@FunctionalInterface//函数式接口检查注解 只能存在一个抽象方法
public interface WorkerInterface<T> {

     boolean doSomeWork(T t);
     //取反
     default WorkerInterface<T> workTest() {
          return t -> !doSomeWork(t);
     }
}

首先要明白函数式接口只允许接口内有一个抽象方法,那么,static和default修饰的还是可以存在的。至于@FunctionalInterface注解,它的作用如下:

1、该注解只能标记在"有且仅有一个抽象方法"的接口上。

2、JDK8接口中的静态方法和默认方法,都不算是抽象方法。

3、接口默认继承java.lang.Object,所以如果接口显示声明覆盖了Object中方法,那么也不算抽象方法。

4、该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错。

扫描二维码关注公众号,回复: 5046406 查看本文章

关于@FunctionalInterface的具体解释,可以看我上篇博客有关于该注解的详细解释。

还没完,上我们最后的代码,还是关于lambda的简单应用:

public class WorkerInterfaceTest {

    public static void main(String[] args) {
        WorkerInterface<Integer> a = x -> x < 6;
        System.out.println(a.doSomeWork(5));
        System.out.println(a.workTest().doSomeWork(5));
    }

猜你喜欢

转载自blog.csdn.net/weixin_42140580/article/details/86576964