zoukankan      html  css  js  c++  java
  • 为什么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代价小的太多了。

  • 相关阅读:
    176. Second Highest Salary
    175. Combine Two Tables
    172. Factorial Trailing Zeroes
    171. Excel Sheet Column Number
    169. Majority Element
    168. Excel Sheet Column Title
    167. Two Sum II
    160. Intersection of Two Linked Lists
    个人博客记录
    <meta>标签
  • 原文地址:https://www.cnblogs.com/keeya/p/11404631.html
Copyright © 2011-2022 走看看