【函数式编程方法引用

2023年 10月 14日 61.2k 0

方法引用

什么是方法引用

  • 方法引用是Lambda表达式的一种特殊形式。
  • 方法引用提供了一种更简洁的方式来为Lambda参数指定现有的方法或构造器。
  • 方法引用需要一个与现有方法声明兼容的函数式接口。
  • 方法引用语法为:Classname::methodName
  • 使用方法引用

    举个例子就懂了,使用已经存在的方法去替换我们的Lambda表达式。

    一般函数表达式写法:

    public class MyClass{
        public static void main(String[] args) {
            addMethod(5,6,(a,b) -> a+b);
        }
        public static int addMethod(int a, int b, MyFunction myFunction){
            return myFunction.add(a,b);
        }
    }
    @FunctionalInterface
    interface MyFunction {
        int add(int a, int b);
    }
    

    使用方法引用:

    public class MyClass{
        public static void main(String[] args) {
            addMethod(5,6, Integer::sum);
        }
        public static int addMethod(int a, int b, MyFunction myFunction){
            return myFunction.add(a,b);
        }
    }
    @FunctionalInterface
    interface MyFunction {
        int add(int a, int b);
    }
    

    可以看到: 我的函数式表达式(a,b) -> return a+b替换为Integer::sum, 把代码拷贝下来跑一跑。

    为什么可以这样替换呢?

    因为它们的逻辑与方法相同(Integer的sum函数是求和,而我的函数式接口也是求和,方法的逻辑相同,参数列表也相同),就可以直接替换。

    Integer类的sum方法:

    public static int sum(int a, int b) {
        return a + b;
    }
    

    是不是和我的add方法一模一样呢。

    方法引用的好处

    那替换有什么好处呢?

    • 更简洁 - 不需要具体参数列表
    • 更易读 - 方法名直接说明功能
    • 代码复用 - 使用已经存在的函数,不用自己再去构造,效率肯定比自己写更高

    方法引用的主要形式包括:

    • 对象::实例方法
    • 类::静态方法
    • 类::实例方法
    • 类构造器::new
    • 数组类型[]::new

    下面对四种形式进行举例子

    对象::实例方法

    创建类的实例,再去使用它的方法

    public class MyClass{
        public static void main(String[] args) {
            MyClass myClass = new MyClass();
            myClass.test();
        }
        public void test(){
            // 创建实例
            Cat cat = new Cat();
            // 定义消费者接口
            Consumer cs1 = (s) -> System.out.println("cat eat " + s);
            Consumer cs2 = cat::eat;
            // 调用方法
            cs1.accept("fish");
            cs2.accept("fish");
        }
    }
    class Cat{
        public void eat(String s){
            System.out.println("cat eat " + s);
        }
    }
    

    类::静态方法

    直接使用类的静态方法

    public class MyClass{
        public static void main(String[] args) {
            MyClass myClass = new MyClass();
            myClass.test();
        }
        public void test(){
            // 定义消费者接口
            Consumer cs1 = (s) -> System.out.println("cat eat " + s);
            Consumer cs2 = Cat::eat;
            // 调用方法
            cs1.accept("fish");
            cs2.accept("fish");
        }
    }
    class Cat{
        public static void eat(String s){
            System.out.println("cat eat " + s);
        }
    }
    

    类::实例方法

    // 方法引用-类名::实例方法名
    BiFunction fun1 = (str1, str2) -> str1.equals(str2);
    BiFunction fun2 = String::equals;
    Boolean result2 = fun2.apply("hello", "world");
    System.out.println(result2);
    

    这个只能使用JavaJDK已经编写好的类的函数,自己编写的函数需要设为static。

    类构造器::new

    public class Solution {
        public static void main(String[] args) {
            // 使用lambda表达式
            Function f1 = (s)-> new Cat(s);
            Cat c1 = f1.apply("小白");
            System.out.println(c1.getName());
            // 使用方法引用
            Function f2 = Cat::new;
            Cat c2 = f2.apply("小黑");
            System.out.println(c2.getName());
        }
    }
    class Cat{
        private String name;
        Cat(String name){
            this.name = name;
        }
        public String getName(){
            return this.name;
        }
    }
    

    注意: 使用的时候传入的参数列表需要和构造函数相匹配。比如我里面用的Fuction接口,刚刚好就是我们Cat类的对应形式,构造函数返回值为它的类对象。

    如果要匹配多个参数怎么办???

    答案是我们自己定义函数接口呗,比如定义一个接收三个参数的:

    @FunctionalInterface
    interface CatFactory{
        Cat getCat(T a1, V a2, R a3);
    }
    

    数组类型[]::new

    public class Solution {
        public static void main(String[] args) {
           ArrayFactory af = String[]::new;
            String[] strings = af.create(5);
        }
    }
    @FunctionalInterface
    interface ArrayFactory {
        T[] create(int size);
    }
    

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论