Java8中Lambda表达式详解

Posted mrnx2004

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java8中Lambda表达式详解相关的知识,希望对你有一定的参考价值。

对于任何场景而言,代码量永远都是越少越好,而Java8中提供的Lambda表达式正式简化代码的利器。
参考博客:Java 8 Lambda 表达式详解
参考博客:完美的lambda表达式只有一行

在 Java 8 以前,若我们想要把某些功能传递给某些方法,总要去写匿名类

manager.addScheduleListener(new ScheduleListener() {
    @Override
    public void onSchedule(ScheduleEvent e) {        
        // Event listener implementation goes here...
    }
});

Java 是面向对象语言,除了原始数据类型之处,Java 中的所有内容都是一个对象。而在函数式语言中,我们只需要给函数分配变量,并将这个函数作为参数传递给其它函数就可实现特定的功能。javascript 就是功能编程语言的典范(闭包)。也就是说Java中方法参数只有两种:一是基础数据类型,一是对象。为了兼容函数式编程,而出现了Lambda表达式。

什么是Lambda表达式

Java 中的 Lambda 表达式通常使用语法是 (argument) -> (body),比如:

(arg1, arg2...) -> { body }
(type1 arg1, type2 arg2...) -> { body }

如果Lambda表达式只有一行,则不需要{}return、或者;,比如:

(Integer e)  -> e*2

再比如Lambda要创建一个比较器:

Comparator c = (p1, p2) -> p1.getAge().compareTo(p2.getAge());

甚至于:

Comparator c = Comparator.comparing(Person::getAge);

在这里的::就是Java中的方法引用。

功能接口

在 Java 中,功能接口(Functional interface)指只有一个抽象方法的接口。
每个 Lambda 表达式都可以隐式地分配给功能接口。例如,我们可以从 Lambda 表达式创建 Runnable 接口的引用,如下所示:

Runnable r = () -> System.out.println("hello world");

编译器会自动将上面的代码编译为:

new Thread(
    () -> System.out.println("hello world")
).start();

Lambda 表达式的例子

线程初始化

// Old way
new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello world");
    }
}).start();

// New way
new Thread(
    () -> System.out.println("Hello world")
).start();

事件处理

// Old way
button.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("Hello world");
    }
});

// New way
button.addActionListener( (e) -> {
        System.out.println("Hello world");
});

遍例输出(方法引用)

// old way
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
for (Integer n : list) {
    System.out.println(n);
}

// 使用 -> 的 Lambda 表达式
list.forEach(n -> System.out.println(n));

// 使用 :: 的 Lambda 表达式
list.forEach(System.out::println);

逻辑操作

package com.wuxianjiezh.demo.lambda;

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

public class Main {

    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);

        System.out.print("输出所有数字:");
        evaluate(list, (n) -> true);

        System.out.print("不输出:");
        evaluate(list, (n) -> false);

        System.out.print("输出偶数:");
        evaluate(list, (n) -> n % 2 == 0);

        System.out.print("输出奇数:");
        evaluate(list, (n) -> n % 2 == 1);

        System.out.print("输出大于 5 的数字:");
        evaluate(list, (n) -> n > 5);
    }

    public static void evaluate(List<Integer> list, Predicate<Integer> predicate) {
        for (Integer n : list) {
            if (predicate.test(n)) {
                System.out.print(n + " ");
            }
        }
        System.out.println();
    }
}

Stream API 示例

// old way
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
for(Integer n : list) {
    int x = n * n;
    System.out.println(x);
}

// new way
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
list.stream().map((x) -> x*x).forEach(System.out::println);

以上是关于Java8中Lambda表达式详解的主要内容,如果未能解决你的问题,请参考以下文章

Java8特性详解 lambda表达式:原理篇

Java8特性详解 lambda表达式 Stream

Java学习笔记之三十一详解Java8 lambda表达式

Java8 Lambda表达式详解手册及实例

Java8特性详解 lambda表达式:流式处理中的lambda

JAVA8之lambda表达式详解