Lambda介绍<二>:底层运行原理及Stream的Api简介

一、Lambda的底层运行原理

  首先,创建一个LambdaDemo.java文件编写如下的代码(代码示例1),通过javac命令编译LambdaDemo.java,则得到LambdaDemo.class和FunctionalDemo.class字节码文件, 通过java -Djdk.internal.lambda.dumpProxyClasses LambdaDemo命令运行代码,又会多出一个LambdaDemo$$Lambda$1.class文件,再通过javaP - p命令分别反编译 LambdaDemo.class和LambdaDemo$$Lambda$1.class字节码文件得到示例2的代码。
代码示例1:

public class LambdaDemo {
    public static void main(String[] args) {
            FunctionalDemo functionalDemo = s -> System.out.println(s);
            functionalDemo.test("λ表达式");
    }
}
@FunctionalInterface
interface FunctionalDemo { void test(String s); }

代码示例2:

PS D:\setup\samples> javap -p '.\LambdaDemo.class'
    Compiled from "LambdaDemo.java"
    public class LambdaDemo {
      public LambdaDemo();
      public static void main(java.lang.String[]);
      private static void lambda$main$0(java.lang.String);
    }
PS D:\setup\samples> javap -p '.\LambdaDemo$$Lambda$1.class'
    final class LambdaDemo$$Lambda$1 implements FunctionalDemo {
      private LambdaDemo$$Lambda$1();
      public void test(java.lang.String);
    }
PS D:\setup\samples>

可以发现Lambda表达式在编译过程中,首先对FunctionalDemo接口进行实现生成了实现类LambdaDemo$$Lambda$1,之后,在LambdaDemo类中会生成一个私有静态方法lambda$main$0,然后lambda$main$0方法调用实现类LambdaDemo$$Lambda$1中的test方法完成Lambda表达式中的内容。

所以综上:
  1.Lambda在JVM底层被解释成私有静态方法和匿名内部类型。
  2.通过静态实现方法调用实现接口的匿名内部类中接口方法,完成Lambda表达式的执行。

二、Stream的Api简介

  stream的Api是JDK8提供的数据存储类操作API,配合Lambda表达式可以极大的简化集合操作,提高代码质量,且支持串行、并行操作,一个Stream实例只能被使用一次。特点:stream不会影响原有的数据存储对象,会生成一个新的数据存储对象,所以对于stream有中间操作和结束操作,中间操作指对数据进行比较过滤等,结束操作指将最终的结果输出。常见的中间操作有map/filter等,结束操作有foreach/collect/max/min等,中间操作是lazy操作,并不会立即执行,只会在结束操作确认后执行。
  1. 数组集合获取Stream实例的方式
   (1)数组:Arrays.stream(T[] Arrays)
   (2)List和Set:List.stream()、Set.stream()
   (3)Map: Map.entrySet.stream()
  2. filter操作:根据条件过滤
  3. map操作:遍历并返回
  4. max/min操作: 根据条件比较出最大最小
代码示例3:

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class LambdaDemo {
    public static void main(String[] args) {
        List<User> users = new ArrayList<>();
        users.add(new User("李白", 26));
        users.add(new User("李商隐", 23));
        users.add(new User("杜甫", 18));
        users.add(new User("杜牧", 9));
        /*foreach遍历*/
        users.stream().forEach(user -> System.out.println(user.getName()));

        /*map操作*/
        users.stream().map(user -> user.getAge()).collect(Collectors.toList()).forEach(name-> {
            System.out.println(name);
        });

        /*filter操作*/
        users.stream().filter(user -> user.getAge() < 20).forEach(user -> System.out.println(user.getName()));

        /*max操作,min操作相似*/
        String name = users.stream().max((user1, user2) -> user1.getAge() - user2.getAge()).get().getName();
        System.out.println(name);
        //lambda对于内部方法的引用可简化为以下
        // Optional<User> max = users.stream().max(Comparator.comparingInt(User::getAge));
    }
}
class User {
    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
    private String name;
    private Integer age;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
}

 

posted @ 2021-02-26 15:04  哲雪君!  阅读(274)  评论(0编辑  收藏  举报