Lambda理解

58 阅读2分钟

Lambda理解

java中最简单的语法,莫过于将一个值赋给某个变量,例如

int a=1;

而java8中的lambda,就是将一段代码赋给某个变量,例如

ablock=public void dosomethings(String s){
 System.out.println(s);
 }

但是这样的写法略显笨拙,我们可以一步一步精简代码。

2023-11-16-20-49-28-image.png

lambda表达式,即(可省略类型,也可省略参数的参数列表)->{ 代码块 }

我们来看更多的lambda例子

(1)强就强在lambda能替换匿名内部类

    Runnable r = new Runnable() {
        @Override
        public void run() {
            System.out.println("thread run");
        }
    }

    Runnable r = () -> {
        System.out.println("thread run");
    };

从这里可以看出,lambda是有类型的,它的类型为等号左边接口的类型。

当lambda表达式内部的语句只有一行时,可以省略{},但不建议这样做。

编译器之所以能大胆推断出这条语句System.out.println("thread run")实际上是run方法的内部语句,是因为Runnable接口只有run这一个抽象方法。我们注意到,Runnable接口被@FunctionalInterface注解修饰,该注解限制该接口只能有一个抽象方法,该接口就会被赋予新的名词,函数接口。

在工作中,我们可以(建议,非必须)给某一个接口添加@FunctionalInterface注解,代表该接口为函数接口,是为lambda所服务的。如果再添加一个抽象方法,就会和此注解冲突,从而编译失败。

(2)哪里有list,哪里就有lambda

    //遍历输出集合
    List<Integer> list=Arrays.asList(1,2,3,4,5);
    list.forEach(x->System.out.print(x));
    //当然也可使用方法引用
    list.forEach(System.out::print);

    //取出所有大于1的元素,并形成新的集合
    List<Integer> collect = list.stream().filter(x -> x > 1).collect(Collectors.toList());

    //获取学生的所有年龄集合
    List<Integer> ageList=Arrays.asList(new Student("tom",20),new Student("jack",22))
            .stream().map(Student::getAge).collect(Collectors.toList());

forEach:对集合的迭代。但在大多数情况下,遍历效率:迭代器与for-each循环>带有索引的for循环>lambda中的forEach。但是lambda可以在多个CPU核上同时处理集合,在大数据量并行计算下,lambda的效率就体现出来了。

stream():将集合转化为流,这里的流不是io流。只有转化为流后,才可以进行接下来的map、filter、collect操作等,但流只能被消费一次。

map():将一种形式的流转化为另一种形式的流,这里常常配合方法引用,例如将List形式的流转化为List形式的流。

collect():按照某种方法将流形成具体的集合。