Lambda在解决什么问题

lambda的本质是java的语法糖,目的是为了简化开发成本,降低代码阅读难度.基于这个前提来理解lambda的语法会方便很多,下面主要是对::使用的理解.


先看代码:

package com.joshua.test;

import org.junit.Test;

/**
 * 这个案例主要用来探索双冒号::的使用
 */
public class DcolonTest {
    @Test
    public void colonTest() {
        Colon colon = new Colon();
        // 方式1
        colon.hello(Handler::helloS, "joshua");
        // 方式2
        colon.hello((String name) -> {
            System.out.println("hello " + name);
        }, "joshua");
        // 方式3
        HelloHandler helloHandler = name -> System.out.println("hello " + name);
        colon.hello(helloHandler, "joshua");
        // bye 
        colon.bye(Handler::byeS, "joshua");
        // colon.bye((String name) -> {
        //     System.out.println("bye " + name);
        //     return name;
        // }, "joshua");
        
        colon.speak(Handler::helloS, "momoker", new Handler()::speakS, Handler::byeS);
    }
}

class Colon {
    Colon() {
        System.out.println("no param construction");
    }

    Colon(String str) {
        System.out.println("with param construction :" + str);
    }

    void hello(HelloHandler helloHandler, String str) {
        System.out.println("打招呼:");
        helloHandler.hello(str);
    }

    String bye(ByeHandler byeHandler, String str) {
        System.out.println("说再见:");
        return byeHandler.bye(str);
    }

    void speak(HelloHandler helloHandler, String name, SpeakHandler speakHandler, ByeHandler byeHandler) {
        helloHandler.hello(name);
        System.out.println("说句话:");
        speakHandler.speak();
        String byeString = byeHandler.bye(name);
        System.out.println(byeString);
    }

}

interface HelloHandler {
    void hello(String str);
}

interface ByeHandler {
    String bye(String str);
}

interface SpeakHandler {
    void speak();
}

class Handler {
    static void helloS(String str) {
        System.out.println("hello-s " + str);
    }

    static String byeS(String str) {
        System.out.println("bye-s " + str);
        return "走了";
    }

    void speakS() {
        System.out.println("speak " + "今天天气不错!");
    }
}

从上面的代码中可以得出以下结论:

  1. 使用::的场景也可以使用()->{}语法,详见代码方式1,方式2,方式3,他们都是等价的
  2. 当一个方法使用了interface作为入参的时候
    1. 接口下只有一个方法(此时可以使用lambda)
    2. 有另一个类下的某一个方法,与这个接口下的函数形式完全相同
    3. 满足上面两个条件时,可以使用::语法
  3. 本质上是代码编译的时候::可以找到唯一的实现方法,这也是为什么说lambda是语法糖的原因.