Lambda 语法糖《方法引用》

简介: Lambda 语法糖《方法引用》

一、什么是方法引用?

其实简单来讲,方法引用就是把已经存在的方法拿过来用,当做函数式接口中抽象方法的方法体。使用方法引用有这么四个必要条件:

  1. 引用处必须是函数式接口
  2. 被引用的方法必须已存在
  3. 被引用方法的形参和返回值需要根抽象方法保持一致
  4. 被引用方法的功能要满足当前需求

二、方法引用有什么用?

其实方法引用就是用来简化 Lambda 表达式的,虽然 Lambda 表达式在一些场景下也能起到简化的效果,但是还不够 “优雅”,方法引用便是一种简化 Lambda 表达式的跟优雅的写法。

三、方法引用使用

1、引用静态方法

  • 语法格式:类名 :: 静态方法
  • 演示范例:Integer :: parseInt
    public static void main(String[] args) {
        List<String> lists = new ArrayList<>();
        Collections.addAll(lists,"1","2","3","4","5");
        // 引用静态方法示例:
        List<Integer> collect = lists.stream().map(Integer::parseInt).collect(Collectors.toList());
        System.out.println(collect);
    }

2、引用成员方法

  • 语法格式:对象 :: 成员方法

具体来说,可分为三类:

  1. 其他类:其他类对象 :: 方法名
  2. 本类:this :: 方法名
  3. 父类:super :: 方法名

其他类:

class StringUtil {
    public boolean judge(String s) {
        return s.startsWith("蔡") && s.length() == 3;
    }
}

public class OtherClassDemo {
    public static void main(String[] args) {
        // 创建集合并填入数据
        ArrayList<String> manList = new ArrayList<>();
        Collections.addAll(manList, "蔡坤坤", "叶厚贤,", "刘不甜", "吴倩", "蔡加", "蔡亮亮");

        // 获取所有以 “蔡” 开头,并且长度为 3 的姓名
        manList.stream().filter(new StringUtil()::judge).forEach(System.out::println);
    }
}

本类:

public class ThisAndSuperDemo {
    private int thisDesc(Integer o1,Integer o2) {
        return  o2 - o1;
    }

    private void sortDesc(Integer[] nums) {
        Arrays.sort(nums,this::thisDesc);
    }

    public static void main(String[] args) {
        Integer[] nums = {1,2,3,4,5};

        new ThisAndSuperDemo().sortDesc(nums);
        System.out.println(Arrays.toString(nums));
    }
}

父类:

class Father {
    public int thisDesc(Integer o1,Integer o2) {
        return  o2 - o1;
    }
}
public class ThisAndSuperDemo extends Father {

    private void sortDesc(Integer[] nums) {
        Arrays.sort(nums,super::thisDesc);
    }

    public static void main(String[] args) {
        Integer[] nums = {1,2,3,4,5};

        new ThisAndSuperDemo().sortDesc(nums);
        System.out.println(Arrays.toString(nums));
    }
}

3、引用构造方法

  • 语法格式:类名 :: new
  • 演示范例:Student :: new

:引用构造方法就是为了创建一个对象。

// ...
// Actor 中的构造方法
    public Actor(String str) {
        String[] split = str.split(",");
        this.name = split[0];
        this.age = Integer.parseInt(split[1]);
    }
// ...
public class StructDemo {
    public static void main(String[] args) {
        //创建一个集合,存储多个字符串元素
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张无忌,15","周芷若,14","赵敏,13","张三丰,100","谢广坤,41");

        // 将上述字符串封装成 Actor 对象返回
        List<Actor> collect = list.stream().map(Actor::new).collect(Collectors.toList());
        System.out.println(collect);
    }
}    

4. 类名引用成员方法

独有规则:

  1. 对于抽象方法中的第一个参数,表示被引用方法的调用者,决定了可以引用哪些类中的方法。假设 Stream 流中的数据是字符串,那么使用这种方式,只能引用 String 类中的方法。
  2. 第二个参数到最后一个参数,跟被引用方法的形参保持一致,如果没有第二个参数,说明被引用的方法需要是无参的成员方法。
  • 语法格式:类名 :: 成员方法
  • 演示范例:String :: toUpperCase
public class SpecialDemo {
    public static void main(String[] args) {
        // 准备数据
        List<String> list = new ArrayList<>();
        Collections.addAll(list,"aaa","bbb","ccc");

        // 转换成大写并输出
        list.stream().map(String::toUpperCase).forEach(System.out::println);
    }
}

5、引用数组的构造方法

  • 语法格式:数据类型[] :: new
  • 演示范例:int[] :: new

:引用数组的构造方法就是为了创建一个数组。

:数组的类型需要和流中数据的类型保持一致。

public class ArrayDemo {

    public static void main(String[] args) {
        // 1.创建集合并添加元素
        List<Integer> list = new ArrayList<>();
        Collections.addAll(list,1,2,3,4,5);
        // 2.收集到数组当中
        Integer[] integers = list.stream().toArray(Integer[]::new);
        System.out.println(Arrays.toString(integers));
    }
}

小结

Lambda 怎么简化?

  1. 首先,数据类型可以省略
  2. 如果形参只有一个,小括号可以省略
  3. 如果形参有多个,小括号就不能省略了
  4. 如果方法体只有一行,那么大括号可以省略,return 可以省略分号可以省略

什么是方法引用?

  • 把已经存在的方法拿过来用,当做函数式接口中抽象方法的方法体

:: 是什么符号?

  • 方法引用符

方法引用时需要注意什么?

  • 需要有函数式接口
  • 被引用方法必须已经存在
  • 被引用方法的形参和返回值需要跟抽象方法保持一致
  • 被引用方法的功能要满足当前的需求

方法引用的类型?

  1. 引用静态方法
  • 类名::静态方法
  1. 引用成员方法
  • 对象::成员方法
  • this::成员方法
  • super::成员方法
  1. 引用构造方法
  • 类名::new
  1. 使用类名引用成员方法
  • 类名::成员方法
  • 注:不能引用所有类中的成员方法,如果抽象方法中的第一个参数是A类型的,只能引用A类中的方法。
  1. 引用数组的构造方法
  • 数据类型[]::new


相关文章
|
1月前
|
存储 Python 数据处理
Python 05 之函数【参数,返回值,嵌套调用,作用域,匿名函数】
Python 05 之函数【参数,返回值,嵌套调用,作用域,匿名函数】
61 0
|
1月前
|
Java 编译器 Linux
【C++11(二)】lambda表达式以及function包装器
【C++11(二)】lambda表达式以及function包装器
|
1月前
|
存储
07-python函数的进阶-函数的多返回值/函数的多种传参方式/匿名函数/lambda函数
07-python函数的进阶-函数的多返回值/函数的多种传参方式/匿名函数/lambda函数
|
1月前
|
JavaScript 前端开发 Java
23、匿名类的排序、Lambda 表达式、方法引用
23、匿名类的排序、Lambda 表达式、方法引用
20 0
|
7月前
|
Go
详细介绍 Go 语言中函数的特点、定义、参数传递、返回值、匿名函数
详细介绍 Go 语言中函数的特点、定义、参数传递、返回值、匿名函数
125 39
详细介绍 Go 语言中函数的特点、定义、参数传递、返回值、匿名函数
|
10月前
|
安全 Java 编译器
Kotlin 学习笔记(一)—— 基本类型、函数、lambda、类与对象的写法
Kotlin 作为 Android 开发的首选语言,其基础语法和特性需要重点学习。本文概括总结了 Kotlin 的基本类型、关键字、函数、闭包、高阶函数、类与对象等核心知识点,并给出示例代码进行讲解。
159 0
Kotlin 学习笔记(一)—— 基本类型、函数、lambda、类与对象的写法
|
10月前
|
算法
函数包装器和lambda表达式
函数包装器和lambda表达式
|
存储 程序员 API
python中lambda表达式与函数,函数传参、引用、作用范围、函数文档
python中lambda表达式与函数,函数传参、引用、作用范围、函数文档
120 0
|
存储 算法 编译器
【C++】lambda 表达式 | 包装器
【C++】lambda 表达式 | 包装器
【C++】lambda 表达式 | 包装器
|
安全 Java
Lambda、方法引用、函数式接口
Lambda、方法引用、函数式接口