• 为什么Java需要lambda 表达式? 上帝爱吃苹果


    Java 为什么会引入lambda ?

    在Java8出现之前,如果你想传递一段代码到另一个方法里是很不方便的。你几乎不可能将代码块到处传递,因为Java是一个面向对象的语言,因此你要构建一个属于某个类的对象,由它的某个方法来放置你想传递的代码块。

    下面看两个非常典型的例子,构造线程与比较器:

    构造线程:

    我们要想在另一个线程中执行一些代码逻辑时,通常会将代码放在一个实现Runnable接口的run方法当中,如下图:

    public static void main(String[] args) {
        myThread t = new myThread();
    
    }
    
    class myThread implements Runnable {
        @Override
        public void run() {
            System.out.println("放入你想执行的代码");
        }
    }
    

    你写这段代码的目的就是想开启新的线程来执行你定制的代码,为此你创建了myThread

    接着我们看下构造比较器:

    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(2);
        list.add(5);
        list.add(1);
        list.add(4);
        list.add(3);
    
        Comparator<Integer> comparator = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        };
        Collections.sort(list, comparator);
    }
    

    sort 方法会不断调用compare 方法,对顺序不对的元素进行重新排序,直到有序为止。你写比较器的目的就是给Collections的sort方法传递一段比较逻辑的代码片段,这段代码会被整合到排序排序逻辑中,为此你写了一个类和一个方法

    上述两个例子你会看到它们的相似点,将一段代码传递给其他调用者(一个线程池或者一个排序方法),这段代码会在新的方法中被调用。

    但是,在Java8出现之前,如果你想传递一段代码到另一个方法里是很不方便的,因为Java是一个面向对象的语言,因此你要构建一个属于某个类的对象,由它的某个方法来放置你想传递的代码块。而在一些其他语言中可以直接传递代码块,比如JS。为此,Java决定加入了lambda表达式的语法糖。

    lambda改造

    对于传入比较器代码块,我们的目的是想传入一段比较逻辑,利用lambda表达式可以:

    lambda表达式的语法格式是:参数->一个表达式,如果想传入的代码无法用一个表达式表示,则可以用 参数->{多个表达式}。如果没有参数需要传递,则可以用()->表达式的形式。

    public static void main(String[] args) {
    
            List<Integer> list = new ArrayList<>();
            list.add(2);
            list.add(5);
            list.add(1);
            list.add(4);
            list.add(3);
    
            Collections.sort(list, (one,two)->{
                System.out.println("one="+one);
                System.out.println("two="+two);
                return two - one;
            });
        }
    

    编译器会解析出来 one 与 two 是原先接口compare方法的入参,并自动赋予Integer类型。

    对于构造线程,我们的目的就是想传入一段线程执行的代码,利用lambda表达式可以这样做:

    public static void main(String[] args) {
    
        new Thread(() -> {
            for (int i = 0; i < 100; i++) {
    
                System.out.println("这是一个线程" + i);
            }
        }).start();
    
        for (int i = 100; i < 200; i++) {
            System.out.println("这是主线程" + i);
        }
    }
    

    从上述的例子可以看出,有了lambda表达式,传递代码块变得更为简单,对于一些特定的使用场景,例如Steam API,lambda会大大提高你的代码效率,并且比传统的方式要更为易读(当然,前提是你知道lambda表达式的语法)。

    总的来说,所有的lambda表达式都是延迟执行的,如果你希望立即执行一段代码,那就没必要使用lambda表达式了,延迟执行代码的原因有很多种:

    1. 在另一个线程中运行代码
    2. 多次运行代码
    3. 在某个算法的正确时间点上运行代码(如排序中的比较逻辑)
    4. 某些条件触发时运行代码(数据到达,接口回调等)

    在实际工作中还是比较推荐大家使用的,有人可能会拿性能说事,但你想一想lambda表达的性能损耗可比查询一次MySQL代价小的太多了。

  • 相关阅读:
    【k8s】Volume-persistentVolumeReclaimPolicy
    【k8s】Volume-pv
    【k8s】Secret-生成环境变量
    【k8s】Volume-nfs
    【k8s】Volume-hostPath
    【k8s】Volume-emptyDir
    【k8s】Volume-downwardAPI
    【k8s】Volume-Secret
    【k8s】Volume-ConfigMap-file
    SQL SERVER 列转行
  • 原文地址:https://www.cnblogs.com/keeya/p/11404631.html
Copyright © 2020-2023  润新知