Lambda 表达式

Lambda 表达式

Java 8新特性简介

  • 速度更快
  • 代码更少(增加了新的语法 Lambda 表达式)
  • 强大的 Stream API
  • 便于并行
  • 最大化减少空指针异常 Optional

为什么使用Lambda 表达式

Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码 像数据一样进行传递)。可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使 Java的语言表达能力得到了提升。

从匿名类到 Lambda 的转换
 // jdk 1.7 前 ,必须是 final
        int num = 0;
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println(" Hello Lambda !!!"/* +num++*/);
            }
        };
        runnable.run();
        System.out.println("__________________________________");
        Runnable runnable1 = () -> System.out.println(" Hello Lambda !!!"/*,num++*/);
        runnable1.run();
    /**
     * 匿名内部类
     */
    @Test
    public void test() {
        Comparator<Integer> comparator = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1, o2);
            }
        };
        TreeSet<Integer> treeSet = new TreeSet<>(comparator);
    }

    /**
     * Lambda
     */
    @Test
    public void test2() {
        Comparator<Integer> comparator = (x, y) -> Integer.compare(x, y);
        Comparator<Integer> comparator2 = Integer::compare;
        TreeSet<Integer> treeSet = new TreeSet<>(comparator);
    }
Lambda 表达式语法

Lambda 表达式在Java 语言中引入了一个新的语法元 素和操作符。这个操作符为 “->” , 该操作符被称 为 Lambda 操作符或剪头操作符。它将 Lambda 分为 两个部分:

左侧:指定了 Lambda 表达式需要的所有参数

右侧:指定了 Lambda 体,即 Lambda 表达式要执行 的功能

代码演示
package com.www.java8.test;

import com.www.java8.inter.MyFun;
import com.www.java8.inter.MyFunction2;
import org.testng.annotations.Test;

import java.util.*;
import java.util.function.Consumer;


/**
 * 一 、Lambda 表达式的基础语法 :Java8 中引入图了一个新的操作符 ” -> “ 该操作符称为箭头操作符 或 Lambda 操作符
 * <p>
 * 箭头操作符将 Lambda分成了两部分
 * <p>
 * 右侧 : Lambda 表达式的参数列表
 * <p>
 * 左侧 : Lambda 表达式中所需执行的功能, 即 Lambda 体
 * <p>
 * <p>
 * 语法格式一 : 无参数 , 无返回值
 * <p>
 * () -> System.out.println("Hello Lambda !!")
 * <p>
 * <p>
 * 语法格式二 : 有一个参数 ,无返回值
 * <p>
 * (x)->System.out.println(x)
 * <p>
 * <p>
 * 语法格式三 : 若只有一个参数,小括号可以省略不写
 * <p>
 * x -> System.out.println(x)
 * <p>
 * <p>
 * 语法格式四 :有两个以上的参数, 有返回值 ,并且 Lambda 体中 有多条语句
 * <p>
 * <pre>
 *     Comparator<Integer> comparator = (x, y) -> {
 *             System.out.println("函数式接口!!!");
 *             return Integer.compare(x, y);
 *         };
 * </pre>
 * <p>
 * <p>
 * 语法格式五 : 若 Lambda 体中只有一条语句, return 和 大括号 都可以省略不写
 * <p>
 * <pre>
 *      Comparator<Integer> comparator = (x, y) -> Integer.compare(x, y);
 *         Comparator<Integer> comparator1 = Integer::compare;
 * </pre>
 * <p>
 * <p>
 * 语法格式六: Lambda 表达式的参数列表的数据类型可以省略不写, 因为 JVM 编译器 可以通过上下文推断出 数据类型, 即 ”类型推断“
 * <p>
 * Comparator<Integer> comparator = (Integer x, Integer y) -> Integer.compare(x, y);
 * <p>
 * <p>
 * <p>
 * 上联 : 左右遇一括号省
 * 下联 : 左侧推断类型省
 * 横批 : 能省则省
 * <p>
 * <p>
 * <p>
 * 二: Lambda 表达式需要 ”函数式接口“ 的支持
 * <p>
 * 函数式接口: 接口中只有一个抽象方法的接口,称为函数式接口, 可以使用 注解 @FunctionalInterface 修饰
 * 可以检查是否为函数式接口
 *
 * @author Www
 * <p>
 * 邮箱: 483223455@qq.com
 * <p>
 * 创建时间: 2022/8/11  17:03  星期四
 * <p>
 */
public class Lambda1Test {
    /**
     * 语法格式一 : 无参数 , 无返回值
     * <p>
     * () -> System.out.println("Hello Lambda !!")
     */
    @Test
    public void test1() {
        // jdk 1.7 前 ,必须是 final
        int num = 0;
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println(" Hello Lambda !!!"/* +num++*/);
            }
        };
        runnable.run();
        System.out.println("__________________________________");
        Runnable runnable1 = () -> System.out.println(" Hello Lambda !!!"/*,num++*/);
        runnable1.run();
    }
    
    /**
     * 语法格式二 : 有一个参数 ,无返回值
     * <p>
     * (x)->System.out.println(x)
     */
    @Test
    public void test2() {
        Consumer<String> consumer = (x) -> System.out.println(x);
        Consumer<String> consumer1 = System.out::print;
        consumer1.accept("www");
    }
    
    /**
     * 语法格式四 :有两个以上的参数, 有返回值 ,并且 Lambda 体中 有多条语句
     * <p>
     * <pre>
     *     Comparator<Integer> comparator = (x, y) -> {
     *             System.out.println("函数式接口!!!");
     *             return Integer.compare(x, y);
     *         };
     * </pre>
     */
    @Test
    public void test3() {
        Comparator<Integer> comparator = (x, y) -> {
            System.out.println("函数式接口!!!");
            return Integer.compare(x, y);
        };
        int compare = comparator.compare(1, 2);
        System.out.println(compare);
    }
    
    /**
     * 语法格式五 : 若 Lambda 体中只有一条语句, return 和 大括号 都可以省略不写
     * <p>
     * <pre>
     *      Comparator<Integer> comparator = (x, y) -> Integer.compare(x, y);
     *         Comparator<Integer> comparator1 = Integer::compare;
     * </pre>
     */
    @Test
    public void test4() {
        Comparator<Integer> comparator = (Integer x, Integer y) -> Integer.compare(x, y);
        Comparator<Integer> comparator1 = Integer::compare;
        int compare = comparator1.compare(1, 333);
        System.out.println(compare);
    }
    
    
    /**
     * 类型推断 ---> jdk 1.8 出现; 1.7 之前不存在
     */
    @Test
    public void test5() {
        String str[] = {"w", "ww", "www"};
        String str1;
        //       str1={"www","ww","w"};
        List<String> list = new ArrayList<>();
        show(new HashMap<>());
    }
    
    public void show(Map<String, Integer> map) {
        System.out.println(map.toString());
    }
    
    /**
     * 对一个数进行运行算
     */
    @Test
    public void test6() {
        Integer operation = operation(46, x -> x * x);
        System.out.println(operation);
        System.out.println(operation(919, x -> x * x));
    }
    
    /**
     * 运算方法
     *
     * @param num
     * @param fun
     * @return
     */
    public Integer operation(Integer num, MyFun<Integer> fun) {
        return fun.getValue(num);
    }
    
    /**
     *
     */
    @Test
    public void test7() {
        oop(46L, 919L, Long::sum);
        oop(46L, 919L, (x, y) -> x * y);
    }
    
    /**
     * 对两个 Long 类型进行处理
     *
     * @param l1
     * @param l2
     * @param fun
     */
    public void oop(Long l1, Long l2, MyFunction2<Long, Long> fun) {
        System.out.println(fun.getValue(l1, l2));
    }
}

image.png
image.png

类型推断

上述 Lambda 表达式中的参数类型都是由编译器推断 得出的。Lambda 表达式中无需指定类型,程序依然可 以编译,这是因为 javac 根据程序的上下文,在后台 推断出了参数的类型。Lambda 表达式的类型依赖于上下文环境,是由编译器推断出来的。这就是所谓的 “ 类型推断"

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容