【JDK 8 新特性】 推导Lambda简化过程

【JDK 8 新特性】 推导Lambda简化过程

前言

该文章记录了多线程用Lambda简化的过程(这里就不多赘述Lambda 的作用了)。

推荐将 二、示例 中的代码粘贴运行感受一下。

一、Lambda简化过程

1.外部类

多线程的创建有三种方式(继承Thread、实现Runnable接口、实现Callable接口)。这里我们实现Runnable接口。

/**
 * 推导 Lambda 表达式,简化多线程
 * @author ChangSheng
 * @date 2020-02-17
 */
public class Lambda简化过程 {
    public static void main(String[] args) {
        // 启动PrintThread线程
        new Thread(new PrintThread()).start();
    }
}
// 外部类实现
class PrintThread implements Runnable {
    @Override
    public void run() {
        System.out.println("PrintThread类打印字符。");
    }
}

2.静态内部类

内部类只有在外部类使用时,才会加载编译。

public class Lambda简化过程 {
    // 静态内部类
    static class PrintThread implements Runnable {
        @Override
        public void run() {
            System.out.println("PrintThread类打印字符。");
        }
    }
    public static void main(String[] args) {
        // 启动PrintThread多线程
        new Thread(new PrintThread()).start();
    }
}

3.局部内部类

将静态移入main方法,作为局部内部类。

public class Lambda简化过程 {
    public static void main(String[] args) {
        // 局部内部类
        class PrintThread implements Runnable {
            @Override
            public void run() {
                System.out.println("PrintThread类打印字符。");
            }
        }
        // 启动PrintThread多线程
        new Thread(new PrintThread()).start();
    }
}

4.匿名内部类

这里将PrintThread类名字去掉了,成为了匿名内部类。

匿名内部类,必须借助父类或接口。

public class Lambda简化过程 {
    public static void main(String[] args) {
        // 匿名内部类,必须借助父类或接口。
        new Thread(new Runnable(){
            @Override
            public void run() {
                System.out.println("PrintThread类打印字符。");
            }
        }).start();
    }
}

5.JDK 8 Lambda表达式

JDK 8 的Lambda表达式将上面匿名内部类接口名,和方法名简化了。

现在只需要关注run()方法中的语句。{}中写原本run()方法中的语句,加上花括号可以写多条语句(一条语句时可以不加花括号{})。

public class Lambda简化过程 {
    public static void main(String[] args) {
        // Lambda 表达式({}中可以写多条语句)
        new Thread(() -> {
            System.out.println("PrintThread类打印字符。");
        }).start();
        // 如果只有一句话,Lambda 表达式也可以写成这样
        new Thread(() -> System.out.println("PrintThread类打印字符。")).start();
    }
}

二、示例

1.接口方法无参数

以下代码可以直接复制到IDE中运行。

/**
 * Lambda示例,推导IPrint接口
 *
 * @author ChangSheng
 * @date 2020-02-17
 */
public class Lambda示例 {
    // 2.静态内部类
    static class PrintSome2 implements IPrint {
        @Override
        public void print() {
            System.out.println("PrintSome2.b.静态内部类");
        }
    }
    public static void main(String[] args) {
        // 3.局部内部类
        class PrintSome3 implements IPrint {
            @Override
            public void print() {
                System.out.println("PrintSome3.c.局部内部类");
            }
        }

        // a.外部类
        IPrint p1 = new PrintSome1();
        p1.print();
        // b.静态内部类
        IPrint p2 = new PrintSome2();
        p2.print();
        // c.局部内部类
        IPrint p3 = new PrintSome3();
        p3.print();
        // d.匿名内部类
        IPrint p4 = new IPrint() {
            @Override
            public void print() {
                System.out.println("PrintSome4.d.匿名内部类");
            }
        };
        p4.print();
        // e.Lambda表达式(注意,使用Lambda表达式时,需要有类型IPrint )
        IPrint p5 = () -> {
            System.out.println("PrintSome5.e.Lambda表达式");
        };
        p5.print();
        // e.Lambda表达式(只有一条语句时去掉{})
        IPrint p6 = () ->  System.out.println("PrintSome6.f.Lambda表达(一条语句省去花括号{})");
        p6.print();
    }
}

interface IPrint {
    // 该接口的无参方法。(注意,我们需要保证接口只有一个未实现方法,否则Lambda无法推导)
    // 无返回值(打印一句话)
    void print();
}

// 1.外部类
class PrintSome1 implements IPrint {
    @Override
    public void print() {
        System.out.println("PrintSome1.a.外部类");
    }
}

2.接口方法有参数

/**
 * Lambda示例,推导IPrint接口
 *
 * @author ChangSheng
 * @date 2020-02-17
 */
public class Lambda示例 {
    // 2.静态内部类
    static class PrintSome2 implements IPrint {
        @Override
        public void print(String v) {
            System.out.println("PrintSome2."+v);
        }
    }

    public static void main(String[] args) {
        // 3.局部内部类
        class PrintSome3 implements IPrint {
            @Override
            public void print(String v) {
                System.out.println("PrintSome3."+v);
            }
        }

        // a.外部类
        IPrint p1 = new PrintSome1();
        p1.print("a.外部类");
        // b.静态内部类
        IPrint p2 = new PrintSome2();
        p2.print("b.静态内部类");
        // c.局部内部类
        IPrint p3 = new PrintSome3();
        p3.print("c.局部内部类");
        // d.匿名内部类
        IPrint p4 = new IPrint() {
            @Override
            public void print(String v) {
                System.out.println("PrintSome4."+v);
            }
        };
        p4.print("d.匿名内部类");
        // e.Lambda表达式
        IPrint p5 = (String v) -> System.out.println("PrintSome5."+v);
        p5.print("e.Lambda表达式");
        // f.Lambda表达式(可以省略类型)
        IPrint p6 = (v) -> System.out.println("PrintSome6."+v);
        p6.print("f.Lambda表达式(省略类型)");
        // g.Lambda表达式(只有一个参数时,可以省略括号)
        IPrint p7 = v -> System.out.println("PrintSome7."+v);
        p7.print("g.Lambda表达式(省略括号)");
    }
}

interface IPrint {
    // 该接口的有参方法。(注意,我们需要保证接口只有一个未实现方法,否则Lambda无法推导,v代表value)
    // 无返回值(打印一句话 + 传入的值v)
    void print(String v);
}

// 1.外部类
class PrintSome1 implements IPrint {
    @Override
    public void print(String v) {
        System.out.println("PrintSome1." + v);
    }
}

3.接口方法有参数有返回值


/**
 * Lambda示例,推导IPrint接口
 *
 * @author ChangSheng
 * @date 2020-02-17
 */
public class Lambda示例 {
    // 2.静态内部类
    static class PrintSome2 implements IPrint {
        @Override
        public String print(String v1, String v2) {
            return v1+v2;
        }
    }

    public static void main(String[] args) {
        // 3.局部内部类
        class PrintSome3 implements IPrint {
            @Override
            public String print(String v1, String v2) {
                return v1+v2;
            }
        }

        // a.外部类
        IPrint p1 = new PrintSome1();
        String print1 = p1.print("PrintSome1.", "a.外部类");
        System.out.println(print1);
        // b.静态内部类
        IPrint p2 = new PrintSome2();
        String print2 = p2.print("PrintSome2.", "b.静态内部类");
        System.out.println(print2);
        // c.局部内部类
        IPrint p3 = new PrintSome3();
        String print3 = p3.print("PrintSome3.", "c.局部内部类");
        System.out.println(print3);
        // d.匿名内部类
        IPrint p4 = new IPrint() {
            @Override
            public String print(String v1, String v2) {
                return v1+v2;
            }
        };
        String print4 = p4.print("PrintSome4.", "d.匿名内部类");
        System.out.println(print4);
        // e.Lambda表达式(省略return)
        IPrint p5 = (String v1, String v2) -> v1+v2;
        String print5 = p5.print("PrintSome5.", "e.Lambda表达式");
        System.out.println(print5);
        // f.Lambda表达式(省略return,也可以省略类型)
        IPrint p6 = (v1, v2) -> v1+v2;
        String print6 = p6.print("PrintSome6.", "f.Lambda表达式(省略类型)");
        System.out.println(print6);
    }
}

interface IPrint {
    // 该接口的有参方法。(注意,我们需要保证接口只有一个未实现方法,否则Lambda无法推导,v代表value)
    // 有返回值(返回v1+v2)
    String print(String v1, String v2);
}

// 1.外部类
class PrintSome1 implements IPrint {
    @Override
    public String print(String v1, String v2) {
        return v1+v2;
    }
}