函数式编程基本语法

文章目录

1.函数对象表现形式

1.Lambda表达式(功能全面)
1.基本语法
  • 参数 + “->” + {逻辑}
2.只有一行逻辑,该逻辑结果是返回值

image-20240607234452645

3.复杂逻辑

image-20240607234632700

4.省略参数类型(可以通过上下文推导出类型时,比如实现了函数式接口)

image-20240607234756094

5.只有一个参数时,参数的圆括号可以省略,但是也不能加参数类型

image-20240607235117271

2.方法引用(写法简洁)
1.类型调用静态方法

image-20240607235538574

2.类型调用成员方法(函数是以对象为基本单位的)

image-20240607235615587

3.对象调用非静态方法

4.类型创建对象

image-20240608000047017

3.练习
1.判断Lambda表达式正确性

image-20240608000706259

2.方法引用转换为Lambda表达式(要素:逻辑,参数,返回值)

image-20240608001236212

3.方法引用实例

image-20240608001643179

4.函数式编程的技巧(重要)
1.定义函数式接口:定义参数 + 返回值
2.Lambda表达式:根据参数和返回值写出逻辑
3.方法引用:根据逻辑反推出参数和返回值

2.函数对象的类型

1.如何归类?

image-20240608001755717

2.归类练习

image-20240608001939742

3.自定义函数式接口
1.函数式接口加上@FunctionalInterface 在编译时检查是否函数式接口有且只有一个抽象方法
package com.sun.first;

/**
 * @Author sun
 * @Create 2024/6/7 22:51
 * @Version 1.0
 */
public class Sample2 {

    public static void main(String[] args) {
        // 参数和返回值需要与函数对象一致
        Fun fun = (a) -> {
            return a + 1;
        };
        System.out.println(fun.test(2));
    }
}

// 在编译时检查是否函数式接口有且只有一个抽象方法
@FunctionalInterface
interface Fun {
    int test(int a);
}
2.练习案例
package com.sun.first;

import java.util.ArrayList;

/**
 * @Author sun
 * @Create 2024/6/7 22:51
 * @Version 1.0
 */
public class Sample2 {

    public static void main(String[] args) {
        // 参数和返回值需要与函数对象一致
        Fun fun = (a) -> {
            return a + 1;
        };
        System.out.println(fun.test(2));

        Fun1 fun1 = (int a, int b, int c) -> a + b + c;

        Fun2 fun2 = (int a, int b) -> a - b;

        Fun3 fun3 = () -> new String();

        Fun4 fun4 = () -> new ArrayList<String>();

        Fun5<String, Integer> fun5 = (str) -> {
            return Integer.valueOf(str);
        };

        System.out.println(fun5.test("34"));
    }
}

// 在编译时检查是否函数式接口有且只有一个抽象方法
@FunctionalInterface
interface Fun {
    int test(int a);
}

@FunctionalInterface
interface Fun1 {
    int test(int a, int b, int c);
}

@FunctionalInterface
interface Fun2 {
    int test(int a, int b);
}

@FunctionalInterface
interface Fun3 {
    String test();
}

@FunctionalInterface
interface Fun4 {
    ArrayList<String> test();
}

// 参数和返回值都是泛型
@FunctionalInterface
interface Fun5<I, O> {
    O test(I input);
}



3.JDK提供的函数式接口

1.IntPredicate 参数为int,返回值为boolean

image-20240608211325083

2.IntBinaryOperator 参数为两个int,返回值为int

image-20240608211706550

3.Supplier 参数为空,返回值为泛型

image-20240608212044668

4.Function 参数为泛型,返回值也为泛型

image-20240608211951855

5.实例

image-20240608212058797

6.常见函数接口
1.概览

image-20240608212149243

2.命名规则

image-20240608212831086

7.练习
1.将判断条件使用函数式接口替换 Predicate
1.题目

image-20240608213428171

2.答案
package com.sun.first;

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

/**
 * Description: 将判断条件使用函数式接口替换
 * @Author sun
 * @Create 2024/6/8 21:35
 * @Version 1.0
 */
public class Sample4 {
    public static void main(String[] args) {
        List<Integer> filter = filter(Arrays.asList(1, 2, 3), i -> {
            // 这里的参数是Integer类型的,返回值是boolean类型,逻辑是判断i是否是偶数,当然也可以更换
            return (i & 1) == 0;
        });
        System.out.println("filter = " + filter);
    }

    // 过滤一下list,得到list中的偶数
    static List<Integer> filter(List<Integer> list, Predicate<Integer> predicate) {
        // 使用一个List来存储结果
        List<Integer> res = new ArrayList<>();
        // 过滤出偶数
        for (Integer i : list) {
            // 其中当i的最后一位是1的时候&1才是1,否则为0,也就是偶数
            // 这里的函数式接口的意思就是,参数为i,返回值为boolean,也就是如果结果是true,才进行添加
            if (predicate.test(i)) {
                res.add(i);
            }
        }
        return res;
    }
}
2.一个参数一个返回值 Function
1.题目

image-20240608215636309

2.答案
package com.sun.first;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;

/**
 * Description:
 * @Author sun
 * @Create 2024/6/8 21:57
 * @Version 1.0
 */
public class Sample5 {
    public static void main(String[] args) {
        List<String> map = map(Arrays.asList(1, 2, 3), a -> {
            return String.valueOf(a);
        } );
        System.out.println(map);
    }

    static List<String> map(List<Integer> list, Function<Integer, String> function) {
        List<String> res = new ArrayList<>();
        for (Integer i : list) {
            // 将结果转换为String类型
            // 将具体逻辑使用函数式接口替换,参数为Integer类型的i,返回值为String类型,使用Function
            res.add(function.apply(i));
        }
        return res;
    }
}
3.将具体逻辑使用函数式接口替换 Consumer
1.题目

image-20240608221111329

2.结果
package com.sun.first;

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

/**
 * Description:
 * @Author sun
 * @Create 2024/6/8 22:14
 * @Version 1.0
 */
public class Sample6 {
    public static void main(String[] args) {
        consume(Arrays.asList(1, 3, 3), num -> {
            System.out.println("num = " + num);
        });

    }

    static void consume(List<Integer> list, Consumer<Integer> consumer) {
        for(Integer num : list) {
            // 打印,但是以后逻辑可能改变
            // 一个参数,为Integer类型的num,没有返回值,使用Consumer
            consumer.accept(num);
        }
    }
}
4.没有参数,一个返回值 Supplier
1.题目

image-20240608222201277

2.答案
package com.sun.first;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.Supplier;

/**
 * Description:
 * @Author sun
 * @Create 2024/6/8 22:22
 * @Version 1.0
 */
public class Sample7 {
    public static void main(String[] args) {
        List<Integer> supply = supply(3, () -> {
            // 逻辑为生成一个随机数
            int res = ThreadLocalRandom.current().nextInt();
            System.out.println(res);
            return res;
        });
    }

    static List<Integer> supply(int count, Supplier<Integer> supplier) {
        List<Integer> result = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            // 生成随机数,但是逻辑可能改变
            // 参数为空,返回值为一个,使用Supplier
            result.add(supplier.get());
        }
        return result;
    }
}

4.方法引用

1.基本介绍

2.六种方法引用的格式
1.类名::静态方法
1.介绍

image-20240610211507579

2.使用lambda表达式的方式,打印所有学生 forEach
package com.sun.methodref;

import java.util.stream.Stream;

/**
 * Description:
 * @Author sun
 * @Create 2024/6/10 21:19
 * @Version 1.0
 */
public class MethodRef01 {
    public static void main(String[] args) {
        Stream.of(
                new Student("libai", "男"),
                new Student("dufu", "男"),
                new Student("lishimin", "女")
        ).forEach(student -> {
            // 挑选出所有的男的
                System.out.println(student);
        });
    }
}

class Student {
    private String name;
    private String sex;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Student(String name, String sex) {
        this.name = name;
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                '}';
    }
}
3.使用方法引用,打印所有学生 forEach
public class MethodRef01 {
    public static void main(String[] args) {
        Stream.of(
                new Student("libai", "男"),
                new Student("dufu", "男"),
                new Student("lishimin", "女")
        ).forEach(MethodRef01::abc);
        // 对于forEach来说,参数为每个元素,返回值为空
        // 所以无论是lambda表达式还是方法引用,他们都遵循这个条件:(Student stu) -> void
    }

    public static void abc(Student student) {
        System.out.println(student);
    }
}
4.使用lambda表达式的方式,打印所有男学生 filter
    public static void main(String[] args) {
        Stream.of(
                        new Student("libai", "男"),
                        new Student("dufu", "男"),
                        new Student("lishimin", "女")
                ).filter(student -> {
                    // (Student student) -> boolean
                    if (student.getSex().equals("男")) {
                        return true;
                    }
                    return false;
                })
                .forEach(MethodRef01::abc);
    }

    public static void abc(Student student) {
        System.out.println(student);
    }
}
5.使用方法引用的方式,打印所有男学生 filter
public static void main(String[] args) {
    Stream.of(
                    new Student("libai", "男"),
                    new Student("dufu", "男"),
                    new Student("lishimin", "女")
            ).filter(MethodRef01::filter).
            forEach(MethodRef01::abc);
}

// (Student student) -> boolean
public static boolean filter(Student student) {
    return student.getSex().equals("男");
}


public static void abc(Student student) {
    System.out.println(student);
}
2.类名:非静态方法
1.介绍

image-20240610214942622

2.使用lambda表达式的方式,打印所有男学生 filter
public static void main(String[] args) {
    Stream.of(
                    new Student("libai", "男"),
                    new Student("dufu", "男"),
                    new Student("lishimin", "女")
            ).filter(student -> {
                // 使用lambda表达式
                return student.isMale(student);
            })
            .forEach(MethodRef01::abc);
}

image-20240610215931898

3.使用方法引用的方式,打印所有男学生 filter
public void main(String[] args) {
    Stream.of(
                    new Student("libai", "男"),
                    new Student("dufu", "男"),
                    new Student("lishimin", "女")
            ).filter(Student::isMale)
            .forEach(MethodRef01::abc);
}

image-20240610215931898

3.对象:非静态方法
1.介绍

image-20240616211647151

2.输出

image-20240616212406632

3.过滤性别是男的

image-20240616213001113

4.将男生转化为女生

image-20240616213655158

4.类名::new
1.介绍

image-20240616214029702

2.调用不同参数个数的构造
package com.sun.first;

import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * Description:
 * @Author sun
 * @Create 2024/6/16 21:42
 * @Version 1.0
 */
public class Sample9 {

    public static void main(String[] args) {
        // 调用无参构造
        Supplier<Student> m1 = Student::new;
        Student student = m1.get();
        System.out.println("student = " + student);
        // 调用一个参数的构造
        Function<String, Student> m2 = Student::new;
        Student sun = m2.apply("sun");
        System.out.println("sun = " + sun);
        // 调用两个参数的构造
        BiFunction<String, String, Student> m3 = Student::new;
        Student apply = m3.apply("sun", "男");
        System.out.println("apply = " + apply);
    }
}
5.this::非静态方法和super::非静态方法
1.使用this过滤男性
package com.sun.first;

import java.util.stream.Stream;

/**
 * Description:
 * @Author sun
 * @Create 2024/6/17 21:18
 * @Version 1.0
 */
public class Sample10 {

    /**
     * 判断学生是否是男的
     * @param student
     * @return
     */
    Boolean isMan(Student student) {
        return student.getSex().equals("男");
    }

    public void main(String[] args) {
        Stream.of(
                // 三个Student对象
                new Student("libai", "男"),
                new Student("dufu", "男"),
                new Student("lishimin", "女")
        ).filter(this::isMan);
    }

}
2.使用super过滤男性

image-20240617212527690

6.六种使用方式对比

image-20240617213827064

相关推荐

  1. 函数编程

    2024-06-18 06:04:04       56 阅读
  2. 函数编程

    2024-06-18 06:04:04       49 阅读
  3. 函数编程

    2024-06-18 06:04:04       55 阅读
  4. 函数编程要点

    2024-06-18 06:04:04       57 阅读
  5. 函数编程

    2024-06-18 06:04:04       34 阅读
  6. 7 - 函数编程

    2024-06-18 06:04:04       29 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-18 06:04:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-18 06:04:04       100 阅读
  3. 在Django里面运行非项目文件

    2024-06-18 06:04:04       82 阅读
  4. Python语言-面向对象

    2024-06-18 06:04:04       91 阅读

热门阅读

  1. vue 修改页面 刷新页面 增删改 provide / inject

    2024-06-18 06:04:04       39 阅读
  2. Elasticsearch在日志分析中的神奇之旅

    2024-06-18 06:04:04       34 阅读
  3. super().__init__()的解析和作用

    2024-06-18 06:04:04       32 阅读
  4. awtk界面实现下拉屏功能

    2024-06-18 06:04:04       39 阅读
  5. linux 压缩命令之tar工具的基本使用

    2024-06-18 06:04:04       36 阅读
  6. 【Linux】I/O多路复用

    2024-06-18 06:04:04       37 阅读
  7. 微调大模型 - 面向学术论文的AI大模型

    2024-06-18 06:04:04       29 阅读
  8. MySql修改最大连接数

    2024-06-18 06:04:04       40 阅读
  9. 系统安全!

    2024-06-18 06:04:04       32 阅读