函数式编程基本语法

文章目录

    • 1.函数对象表现形式
        • 1.Lambda表达式(功能全面)
          • 1.基本语法
          • 2.只有一行逻辑,该逻辑结果是返回值
          • 3.复杂逻辑
          • 4.省略参数类型(可以通过上下文推导出类型时,比如实现了函数式接口)
          • 5.只有一个参数时,参数的圆括号可以省略,但是也不能加参数类型
        • 2.方法引用(写法简洁)
          • 1.类型调用静态方法
          • 2.类型调用成员方法(函数是以对象为基本单位的)
          • 3.对象调用非静态方法
          • 4.类型创建对象
        • 3.练习
          • 1.判断Lambda表达式正确性
          • 2.方法引用转换为Lambda表达式(要素:逻辑,参数,返回值)
          • 3.方法引用实例
        • 4.函数式编程的技巧(重要)
          • 1.定义函数式接口:定义参数 + 返回值
          • 2.Lambda表达式:根据参数和返回值写出逻辑
          • 3.方法引用:根据逻辑反推出参数和返回值
    • 2.函数对象的类型
        • 1.如何归类?
        • 2.归类练习
        • 3.自定义函数式接口
          • 1.函数式接口加上@FunctionalInterface 在编译时检查是否函数式接口有且只有一个抽象方法
          • 2.练习案例
    • 3.JDK提供的函数式接口
        • 1.IntPredicate 参数为int,返回值为boolean
        • 2.IntBinaryOperator 参数为两个int,返回值为int
        • 3.Supplier 参数为空,返回值为泛型
        • 4.Function 参数为泛型,返回值也为泛型
        • 5.实例
        • 6.常见函数接口
          • 1.概览
          • 2.命名规则
        • 7.练习
          • 1.将判断条件使用函数式接口替换 Predicate
            • 1.题目
            • 2.答案
          • 2.一个参数一个返回值 Function
            • 1.题目
            • 2.答案
          • 3.将具体逻辑使用函数式接口替换 Consumer
            • 1.题目
            • 2.结果
          • 4.没有参数,一个返回值 Supplier
            • 1.题目
            • 2.答案
    • 4.方法引用
        • 1.基本介绍
        • 2.六种方法引用的格式
          • 1.类名::静态方法
            • 1.介绍
            • 2.使用lambda表达式的方式,打印所有学生 forEach
            • 3.使用方法引用,打印所有学生 forEach
            • 4.使用lambda表达式的方式,打印所有男学生 filter
            • 5.使用方法引用的方式,打印所有男学生 filter
          • 2.类名:非静态方法
            • 1.介绍
            • 2.使用lambda表达式的方式,打印所有男学生 filter
            • 3.使用方法引用的方式,打印所有男学生 filter
          • 3.对象:非静态方法
            • 1.介绍
            • 2.输出
            • 3.过滤性别是男的
            • 4.将男生转化为女生
          • 4.类名::new
            • 1.介绍
            • 2.调用不同参数个数的构造
          • 5.this::非静态方法和super::非静态方法
            • 1.使用this过滤男性
            • 2.使用super过滤男性
          • 6.六种使用方式对比

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/718479.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

NAND闪存市场彻底复苏

在全球内存市场逐渐走出阴霾、迎来复苏曙光之际&#xff0c;日本存储巨头铠侠&#xff08;Kioxia&#xff09;凭借敏锐的市场洞察力和及时的战略调整&#xff0c;成功实现了从生产紧缩到全面复苏的华丽转身。这一转变不仅彰显了企业在逆境中的生存智慧&#xff0c;也为全球半导…

在 Stable Diffusion 中控制光线的三种方式

光线在摄影中扮演着至关重要的角色&#xff0c;并对图像的整体质量和意境产生重要影响。你可以利用光线来增强主题&#xff0c;创造深度和立体感&#xff0c;传达情感&#xff0c;并突出重要细节。 在本文中&#xff0c;你将了解通过以下方法来控制光线&#xff1a; 光线提示…

基于Java的度分秒坐标转纯经纬度坐标的漂亮国基地信息管理

目录 前言 一、空间表设计 1、物理表结构 二、后台数据管理 1、数据去重 2、去重的具体实现 3、度分秒数据格式转换 4、具体的转换方法 5、新增界面的实现 三、数据管理界面 总结 前言 众所周知&#xff0c;漂亮国在全球范围内部署了大量的基地&#xff0c;用以维持其…

阿里巴巴全球数学竞赛报名条件

#竞赛概览与历史# “阿里巴巴全球数学竞赛”&#xff08;Alibaba Global Mathematics Competition&#xff09;由阿里巴巴公益、阿里巴巴达摩院共同举办&#xff0c;面向全球的数学爱好者&#xff0c;集竞赛、培训、交流于一体&#xff0c;旨在全球范围内引领开启关注数学、理解…

monitor-zabbix

监控体系理论 学习本篇文章&#xff0c;了解运维监控系统的前世今生 zabbix官网仓库地址 zabbix官网 https://www.zabbix.com/cn/zabbix官网仓库地址 http://repo.zabbix.com/zabbix/ http://repo.zabbix.com/zabbix/4.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_…

数字孪生智慧机场:引领航空未来

图扑数字孪生技术赋能智慧机场&#xff0c;实现运营管理和乘客服务的全面优化。实时数据监控与智能决策助力高效安全的航空体验&#xff0c;推动行业创新与发展。

分布式理论与设计 三、分布式一致性协议

1.两阶段提交协议&#xff08;2PC&#xff09; 1&#xff09;两阶段提交协议 两阶段提交协议&#xff0c;简称2PC(2 Prepare Commit)&#xff0c;是比较常用的解决分布式事务问题的方式&#xff0c;要么所有参与进程都提交事务&#xff0c;要么都取消事务&#xff0c;即实现A…

EasyRecovery电脑数据恢复软件2024数据守护神#误删文件神器#硬盘恢复利器#数据丢失救星

&#x1f310; 你是否曾经因为误删文件、硬盘损坏等原因&#xff0c;失去了重要的数据&#xff1f;别担心&#xff0c;EasyRecovery电脑数据恢复软件是你的救星&#xff01;它能够帮你找回丢失的文件&#xff0c;让你的数据重新焕发生机。 &#x1f50d; EasyRecovery软件的核…

Enhancing CLIP with GPT-4: Harnessing Visual Descriptions as Prompts

标题&#xff1a;用GPT-4增强CLIP:利用视觉描述作为提示 源文链接&#xff1a;Maniparambil_Enhancing_CLIP_with_GPT-4_Harnessing_Visual_Descriptions_as_Prompts_ICCVW_2023_paper.pdf (thecvf.com)https://openaccess.thecvf.com/content/ICCV2023W/MMFM/papers/Manipara…

【Android面试八股文】你能说一说什么是代理模式?静态代理和动态代理分别是什么?如何实现?

文章目录 一、代理模式1.1 代理模式概念1.2 代理模式的目的1.3 代理模式的三个角色1.4 代理模式的两种实现方式1.5 代理模式的优点1.6 代理模式的缺点1.7 适用场景 二、静态代理2.1 静态代理2.2 动态代理2.2.1 JDK动态代理2.2.2 CGLIB动态代理2.2.3 JDK 动态代理和 CGLIB 动态代…

【机器学习300问】122、RNN面临哪些问题?

循环神经网络&#xff08;RNN&#xff09;主要面临梯度消失和梯度爆炸两个核心问题&#xff0c;这严重影响了其处理长期依赖的能力。此外&#xff0c;还存在一些其他的技术挑战。 一、两个主要问题 &#xff08;1&#xff09;梯度消失和梯度爆炸问题 这是RNN中最显著的问题之…

JMU 数科 数据库与数据仓库期末总结(4)实验设计题

E-R图 实体-关系图 E-R图的组成要素主要包括&#xff1a; 实体&#xff08;Entity&#xff09;&#xff1a;实体代表现实世界中可相互区别的对象或事物&#xff0c;如顾客、订单、产品等。在图中&#xff0c;实体通常用矩形表示&#xff0c;并在矩形内标注实体的名称。 属性…

大话设计模式解读03-装饰模式

本篇文章&#xff0c;来解读《大话设计模式》的第6章——装饰模式。并通过C代码实现实例代码的功能。 注&#xff1a;第3~6章讲的是设计模式中的一些原则&#xff08;第3章&#xff1a;单一职责原则&#xff1b;第4章&#xff1a;开放-封闭原则&#xff1b;第5章&#xff1a;依…

C#知识|模块化分层学习笔记

哈喽&#xff0c;你好&#xff0c;我是雷工&#xff01; 01 基本分层 典型的两层结构&#xff1a;由UI层 数据访问层 实体类构成。 其中实体类不算一层&#xff0c;本质是一个数据载体。 02 模块化分层 模块概念&#xff1a;在.NET平台中&#xff0c;模块主要是指类库项目。…

2024.6.17 作业 xyt

今日作业&#xff1a; 升级优化自己应用程序的登录界面。 要求&#xff1a; 1. qss实现 2. 需要有图层的叠加 &#xff08;QFrame&#xff09; 3. 设置纯净窗口后&#xff0c;有关闭等窗口功能。 4. 如果账号密码正确…

Modbus协议转Profibus协议模块接热传感器配置攻略

一、前言 在工业自动化控制领域&#xff0c;Modbus协议和Profibus协议是两种常见的通讯协议&#xff0c;它们在设备之间传输数据起着至关重要的作用。而Modbus协议转Profibus协议模块&#xff08;XD-MDPB100&#xff09;设备&#xff0c;则扮演着连接不同通讯协议的桥梁角色。…

新质生产力水平测算与中国经济增长新动能(dta数据及do代码)

时间跨度&#xff1a;2012-2022年 数据范围&#xff1a;全国30个省份&#xff08;不含港澳台、西藏&#xff09; 数据指标&#xff1a; 参考韩文龙等的做法&#xff0c;收集了全部控制变量与稳定性检验所需变量。 类型 符号 变量 变量定义 被解释变量 GDP 各省人均GDP…

Linux 并发与竞争基础知识学习

Linux 并发与竞争 并发与竞争 Linux 系统是个多任务操作系统&#xff0c;会存在多个任务同时访问同一片内存区域&#xff0c;这些任务可能会相互覆盖这段内存中的数据&#xff0c;造成内存数据混乱。针对这个问题必须要做处理&#xff0c;严重的话可能会导致系统崩溃。现在的…

Swift开发——存储属性与计算属性

Swift语言开发者建议程序设计者多用结构体开发应用程序。在Swift语言中,结构体具有了很多类的特性(除类的与继承相关的特性外),具有属性和方法,且为值类型。所谓的属性是指结构体中的变量或常量,所谓的方法是指结构体中的函数。在结构体中使用属性和方法是因为:①匹别于结…