Java:Lambda表达式、方法引用

news2025/2/28 5:06:45

文章目录

    • 1、Lambda表达式
      • 1.1 Lambda表达式体验
      • 1.2 Lambda表达式的省略形式
      • 1.3 Lambda表达式练习
    • 2、方法引用体验
    • 3、方法引用符
    • 4、引用静态方法
    • 5、引用对象的实例方法
    • 6、引用类的实例方法
    • 7、引用构造方法
    • 8、引用数组的构造方法
    • 9、方法引用练习
      • 9.1 练习1
      • 9.2 练习2
      • 9.3 练习3
    • 10、方法引用总结

学习方法引用之前先学匿名内部类和Lambda表达式。以下代码基于JDK11编写。

1、Lambda表达式

函数式编程:忽略面向对象的复杂语法,强调做什么,而不是谁去做。
函数式接口:有且只有一个抽象方法的接口叫做函数式接口,接口上方可加@Functioonalinterface

Lambda表达式的基本作用:用来简化匿名内部类的书写,Lambda表达式只能简化函数式接口的匿名内部类的写法。

Lambda表达式有什么使用前提:必须是接口的匿名内部类,接口中只能有一个抽象方法。

Lambda的好处:Lambda是一个匿名函数,可以把Lambda表达式理解为是一段可以传递的代码,它可以写出更简洁、更灵活的代码,作为一种更紧凑的代码风格,使Java语言表达能力得到了提升。

Lambda表达式语法:() -> {}

  • ():形参
  • ->:固定格式
  • {}:方法的方法体

1.1 Lambda表达式体验

public class LambdaDemo01 {
    public static void main(String[] args) {

        /**
         *  1.利用匿名内部类的形式去调用下面的方法(以前的调用方式)
         *  调用一个方法的时候,如果方法的形参是一个接口,那么我们要传递这个接口的实现类对象
         *  如果实现类对象只要用到一次,就可以用匿名内部类的形式进行书写
         */
        method(new Swiming() {
            @Override
            public void swim() {
                System.out.println("正在游泳-这是匿名内部类方式");
            }
        });

        /**
         *  2.利用Lambda表达式的形式去调用下面的方法
         */
        method(() ->{
            System.out.println("正在游泳-这是Lambda表达式格式");
        });
    }

    public static void method(Swiming s){
        s.swim();
    }
}

// 这里即使不写@Functioonalinterface也是函数式接口,因为接口中只有一个抽象方法
interface Swiming{
    void swim();
}

image-20231226143352488

1.2 Lambda表达式的省略形式

  • 参数类型可以省略不写。
  • 如果只有一个参数,参数类型可以省略,同时()也可以省略。
  • 如果Lambda表达式的方法体只有一行,大括号,分号,return可以省略不写,需要同时省略。
public class LambdaDemo02 {
    public static void main(String[] args) {
        // 需求:降序排序

        Integer[] arr = {10, 2, 5, 1, 4, 3, 6, 7, 8, 9};

        System.out.println("------------Lambda表达式完整格式----------");
        //Lambda表达式完整格式
        Arrays.sort(arr,(Integer o1, Integer o2) -> {
//            return o1 - o2; //升序排序
            return o2-o1;  //降序排序
        });
        System.out.println(Arrays.toString(arr));


        System.out.println("------------Lambda表达式省略格式----------");

        /**
         * Lambda表达式省略写法
         * 如果Lambda表达式的方法体只有一行,大括号,分号,return可以省略不写,需要同时省略
         */
        Arrays.sort(arr,((o1, o2) -> o2-o1));
        System.out.println(Arrays.toString(arr));
    }
}

image-20231226144524263

1.3 Lambda表达式练习

需求:定义数组并存储一些字符串,利用Arrays中的sort方法进行排序

思路:按照字符串长度排序,短的在前,长的在后,不比较里面的内容。

public class LambdaDemo03 {
    public static void main(String[] args) {
        //需求:定义数组并存储一些字符串,利用Arrays中的sort方法进行排序
        //思路:按照字符串长度排序,短的在前,长的在后,不比较里面的内容
        String[] strings = {"abc","a","ab","123abc","123","abab","aaaaaaaa","aaaaa"};

        System.out.println("------------Lambda表达式完整格式(升序)----------");
        Arrays.sort(strings,(String o1, String o2) ->{
            return o1.length() - o2.length();
        });
        System.out.println(Arrays.toString(strings));

        System.out.println("------------Lambda表达式省略格式(倒叙)----------");
        Arrays.sort(strings,((o1, o2) -> o2.length() - o1.length()));
        System.out.println(Arrays.toString(strings));
    }
}

image-20231226145347566

2、方法引用体验

(1)方法引用的出现原因

在使用Lambda表达式的时候,我们实际上传递进去的代码就是一种解决方案:拿参数做操作

那么考虑一种情况:如果我们在Lambda中所指定的操作方案,已经有地方存在相同方案,那是否还有必要再写重复逻辑呢?答案肯定是没有必要。

那我们又是如何使用已经存在的方案的呢?这就是我们要讲解的方法引用,我们是通过方法引用来使用已经存在的方案。

(2)方法引用的使用条件

  • 被引用的方法需要已经存在,可以是Java已经写好的,也可以是一些第三方的工具类
  • 被引用方法的形参和返回值需要跟抽象方法的形参和返回值保持一致
  • 被引用方法的功能需要满足当前的要求

(3)代码演示

public class MethodReferenceDemo01 {
    public static void main(String[] args) {
        // 需求:创建一个数组,进行降序排列
        Integer[] arr = {3, 5, 4, 1, 6, 2};

        System.out.println("------------匿名内部类方式-----------");
        /**
         * 匿名内部类方式
         */
        Arrays.sort(arr, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2-o1;
            }
        });
        System.out.println(Arrays.toString(arr));


        System.out.println("------------lambda表达式方式-----------");
        /**
         * lambda表达式方式
         * 因为第二个参数的类型Comparator是一个函数式接口,所以可以使用lambda表达式
         */
        Arrays.sort(arr,(Integer o1,Integer o2) -> {
            return o2-o1;
        });
        System.out.println(Arrays.toString(arr));


        System.out.println("------------方法引用方式-----------");
        /**
         * 1.引用处需要是函数式接口
         * 2.被引用的方法需要已经存在
         * 3.被引用方法的形参和返回值需要跟抽象方法的形参和返回值保持一致
         * 4.被引用方法的功能需要满足当前的要求
         */
        Arrays.sort(arr,MethodReferenceDemo01::subtraction);
        System.out.println(Arrays.toString(arr));
    }
    
    // 被引用的方法可以是Java已经写好的,也可以是一些第三方的工具类
    public static int subtraction(int num1, int num2) {
        return num2 - num1;
    }
}

image-20231226150950157

3、方法引用符

(1)方法引用符

:: 该符号为引用运算符,而它所在的表达式被称为方法引用

(2)推导与省略

  • 如果使用Lambda,那么根据“可推导就是可省略”的原则,无需指定参数类型,也无需指定的重载形式,它们都将被自动推导
  • 如果使用方法引用,也是同样可以根据上下文进行推导
  • 方法引用是Lambda的孪生兄弟

4、引用静态方法

引用类方法,其实就是引用类的静态方法

类方法(Class Method)是指使用 static 关键字修饰的方法。

(1)格式

类名::静态方法

(2)示例

Integer::parseInt

Integer类的方法:public static int parseInt(String s) 将此String转换为int类型数据

(3)练习描述

需求:集合中有以下数字,要求把他们都变成int类型
“1”,“2”,“3”,“4”,“5”

(4)代码演示

public class MethodReferenceDemo02 {
    public static void main(String[] args) {

        // 1.创建集合并添加元素
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"1","2","3","4","5");

        // 2.把他们都变成int类型,使用map进行类型的转换(String->Integer)
        System.out.println("-----------匿名内部类方式------------");
        list.stream().map(new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                int i = Integer.parseInt(s);
                return i;
            }
        }).forEach(s-> System.out.println(s));

        System.out.println("-----------方法引用方式------------");
        list.stream()
                .map(Integer::parseInt)
                .forEach(s-> System.out.println(s));
    }
}

image-20231226152228386

使用说明:Lambda表达式被类方法替代的时候,它的形式参数全部传递给静态方法作为参数

5、引用对象的实例方法

引用对象的实例方法,其实就是引用类中的成员方法

成员方法包括实例方法和静态方法。

public class MyClass {
// 实例变量
private int myVariable;

// 实例方法
public void instanceMethod() {
  // 这是一个实例方法,可以访问实例变量
  System.out.println("This is an instance method.");
}

// 静态方法
public static void staticMethod() {
  // 这是一个静态方法,不能访问实例变量
  System.out.println("This is a static method.");
}
}

(1)格式
其他类:其他类对象::方法名
本类:this::方法名(引用处不能是静态方法)
父类:super::方法名(引用处不能是静态方法)

(2)示例

“HelloWorld”::toUpperCase

String类中的方法:public String toUpperCase() 将此String所有字符转换为大写

(3)练习描述

    需求:
        集合中有一些名字,按照要求过滤数据
        数据:"张无忌","周芷若","赵敏","张强","张三丰"
        要求:只要以张开头,而且名字是3个字的

(4)代码演示

其他类的成员方法

public class StringOperation {
    public boolean stringJudge(String s){
        return s.startsWith("张") && s.length() == 3;
    }
}

测试

public class MethodReferenceDemo03 {
    public static void main(String[] args) {
        
        //1.创建集合
        ArrayList<String> list = new ArrayList<>();
        //2.添加数据
        Collections.addAll(list,"张无忌","周芷若","赵敏","张强","张三丰");

        //3.过滤数据(只要以张开头,而且名字是3个字的)


        System.out.println("------------匿名内部类方式--------------");
        list.stream().filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.startsWith("张")&&s.length() == 3;
            }
        }).forEach(s-> System.out.println(s));


        System.out.println("------------Lambda表达式方式--------------");
        list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(s -> System.out.println(s));

        System.out.println("------------方法引用方式:引用其他类的成员方法--------------");
        StringOperation so = new StringOperation();
        list.stream().filter(so::stringJudge)
                .forEach(s -> System.out.println(s));

        System.out.println("------------方法引用方式:引用本类的成员方法-----------------");
        // 下面的这个代码在main中,main方法是静态的,而静态方法中是没有this的,
        // 所以会报错cannot be referenced from a static context
/*        list.stream().filter(this.stringJudge)
                .forEach(s -> System.out.println(s));*/
        list.stream().filter(new MethodReferenceDemo03()::stringJudge)
                .forEach(s -> System.out.println(s));
    }
    
    public boolean stringJudge(String s){
        return s.startsWith("张") && s.length() == 3;
    }
}

image-20231226155629278

使用说明:Lambda表达式被对象的实例方法替代的时候,它的形式参数全部传递给该方法作为参数

6、引用类的实例方法

引用类的实例方法,其实就是引用类中的成员方法

(1)格式

类名::成员方法

(2)示例

String::substring

public String substring(int beginIndex,int endIndex)

从beginIndex开始到endIndex结束,截取字符串。返回一个子串,子串的长度为endIndex-beginIndex

(3)练习描述

需求:合里面一些字符串,要求变成大写后进行输出

(4)代码演示

public class MethodReferenceDemo05 {
    public static void main(String[] args) {
        /*
        匿名内部类中的抽象方法形参的详解:
        第一个参数:表示被引用方法的调用者,决定了可以引用哪些类中的方法
                    在Stream流当中,第一个参数一般都表示流里面的每一个数据。
                    假设流里面的数据是字符串,那么使用这种方式进行方法引用,只能引用String这个类中的方法

        第二个参数到最后一个参数:跟被引用方法的形参保持一致,如果没有第二个参数,说明被引用的方法需要是无参的成员方法

        局限性:
            不能引用所有类中的成员方法。
            是跟抽象方法的第一个参数有关,这个参数是什么类型的,那么就只能引用这个类中的方法。

       */

        //1.创建集合对象
        ArrayList<String> list = new ArrayList<>();
        //2.添加数据
        Collections.addAll(list, "aaa", "bbb", "ccc", "ddd");
        //3.变成大写后进行输出,使用map进行转换

        System.out.println("------------匿名内部类方式--------------");
        list.stream().map(new Function<String, String>() {
            @Override
            public String apply(String s) {
                return s.toUpperCase();
            }
        }).forEach(s -> System.out.println(s));


        System.out.println("------------方法引用方式-----------------");
        //拿着流里面的每一个数据,去调用String类中的toUpperCase方法,方法的返回值就是转换之后的结果。
        list.stream().map(String::toUpperCase).forEach(s -> System.out.println(s));
    }
}

image-20231226162724972

image-20231226162943730

image-20231226162650970

使用说明:Lambda表达式被类的实例方法替代的时候,第一个参数作为调用者,后面的参数全部传递给该方法作为参数。

7、引用构造方法

引用构造器,其实就是引用构造方法

(1)格式

类名::new

(2)示例

Student::new

(3)练习描述

需求:集合里面存储姓名和年龄,要求封装成Student对象并收集到List集合中

(4)代码演示

public class MethodReferenceDemo04 {
    public static void main(String[] args) {

        //1.创建集合对象
        ArrayList<String> list = new ArrayList<>();
        //2.添加数据
        Collections.addAll(list, "张无忌,15", "周芷若,14", "赵敏,13", "张强,20", "张三丰,100", "张翠山,40", "张良,35", "王二麻子,37", "谢广坤,41");
        //3.封装成Student对象并收集到List集合中,使用map进行类型转换(String --> Student)

        System.out.println("------------匿名内部类方式--------------");
        List<Student> newList = list.stream().map(new Function<String, Student>() {
            @Override
            public Student apply(String s) {
                String[] arr = s.split(",");
                String name = arr[0];
                int age = Integer.parseInt(arr[1]);
                return new Student(name, age);
            }
        }).collect(Collectors.toList());
        System.out.println(newList);

        System.out.println("------------方法引用方式-----------------");
        List<Student> newList2 = list.stream().map(Student::new).collect(Collectors.toList());
        System.out.println(newList2);
    }
}

image-20231226160905777

使用说明:Lambda表达式被构造器替代的时候,它的形式参数全部传递给构造器作为参数。

8、引用数组的构造方法

(1)格式

数据类型[]::new

(2)示例

int[]::new

(3)目的

创建一个指定类型的数组

(4)练习描述

需求:集合中存储一些整数,收集到数组当中
细节:数组的类型,需要跟流中数据的类型保持一致。

(5)代码演示

public class MethodReferenceDemo06 {
    public static void main(String[] args) {

        //1.创建集合并添加元素
        ArrayList<Integer> list = new ArrayList<>();
        Collections.addAll(list, 1, 2, 3, 4, 5);
        //2.收集到数组当中
        System.out.println("------------匿名内部类方式--------------");
        Integer[] arr = list.stream().toArray(new IntFunction<Integer[]>() {
            @Override
            public Integer[] apply(int value) {
                return new Integer[value];
            }
        });
        System.out.println(Arrays.toString(arr));

        System.out.println("------------方法引用方式-----------------");
        Integer[] arr2 = list.stream().toArray(Integer[]::new);
        System.out.println(Arrays.toString(arr2));
    }
}

image-20231226165916374

9、方法引用练习

9.1 练习1

需求:
     集合中存储一些字符串的数据,比如:张三,23。
     收集到Student类型的数组当中

代码实现

public class MethodReferenceDemo07 {
    public static void main(String[] args) {
        //1.创建集合并添加元素
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张无忌,15", "周芷若,14", "赵敏,13", "张强,20", "张三丰,100", "张翠山,40", "张良,35", "王二麻子,37", "谢广坤,41");
        //2.先把字符串变成Student对象,然后再把Student对象收集起来
        // map之后,流里的数据已经变为Student了,所以toArray要转为Student类型的数组
        Student[] arr = list.stream().map(Student::new).toArray(Student[]::new);
        // 打印数组
        System.out.println(Arrays.toString(arr));
    }
}

image-20231226171004234

9.2 练习2

需求:
    创建集合添加学生对象
    学生对象属性:name,age
要求:
    获取姓名并放到数组当中
    使用方法引用完成
技巧:
    1.现在有没有一个方法符合我当前的需求
    2.如果有这样的方法,这个方法是否满足引用的规则
    静态   类名::方法名
    成员方法
    构造方法  类名::new

代码实现

public class MethodReferenceDemo08 {
    public static void main(String[] args) {
        // 1.创建集合
        ArrayList<Student> list = new ArrayList<>();
        // 2.添加元素
        list.add(new Student("zhangsan",23));
        list.add(new Student("lisi",24));
        list.add(new Student("wangwu",25));
        // 3.获取姓名放到数组当中
        System.out.println("------------匿名内部类方式--------------");
        String[] arr = list.stream().map(new Function<Student, String>() {
            @Override
            public String apply(Student student) {
                return student.getName();
            }
        }).toArray(String[]::new);
        System.out.println(Arrays.toString(arr));

        System.out.println("------------方法引用方式-----------------");
        String[] arr2 = list.stream().map(Student::getName).toArray(String[]::new);
        System.out.println(Arrays.toString(arr2));
    }
}

image-20231226172306598

9.3 练习3

需求:
    创建集合添加学生对象
    学生对象属性:name,age
要求:
    把姓名和年龄拼接成:张三-23的字符串,并放到数组当中
    使用方法引用完成

代码实现

public class MethodReferenceDemo09 {
    public static void main(String[] args) {
        ArrayList<Student> studentList = new ArrayList<>();
        studentList.add(new Student("zhangsan",23));
        studentList.add(new Student("lisi",24));
        studentList.add(new Student("wangwu",25));

        // 使用方法引用将姓名和年龄拼接成字符串并放到数组中
        String[] nameAgeArray = studentList.stream()
                .map(student -> student.getName() + "-" + student.getAge())
                .toArray(String[]::new);

        // 打印结果
        for (String nameAge : nameAgeArray) {
            System.out.println(nameAge);
        }
    }
}

image-20231226173917992

10、方法引用总结

1.什么是方法引用?
把已经存在的方法拿过来用,当做函数式接口中抽象方法的方法体
2.::是什么符号?
方法引用符
3.方法引用时要注意什么?
- 要使用方法引用的,需要是函数式接口
- 被引用方法必须已经存在
- 被引用方法的形参和返回值需要跟抽象方法保持一致
- 被引用方法的功能要满足当前的需求

3.引用静态方法
类名::静态方法

4.引用对象的实例方法	(可以引用所有类中的成员方法,与【5.】不同)
对象名::成员方法	(引用任意一个类的成员方法,要求形参和返回值要一样)
ths::成员方法	(引用本类的成员方法,只能写在非静态方法中,静态方法可以使用类名::成员方法)
super::成员方法		(引用父类的成员方法,只能写在非静态方法中,静态方法可以使用类名::成员方法)

5.引用类的实例方法
类名::成员方法  (被引用的方法形参是跟抽象方法第二个参数后面的保持一致)
注:不能引用所有类中的成员方法,如果抽象方法的第一个参数是A类型的,只能引用A类中的方法。

6.引用构造方法
类名::new


7.引用数组的构造方法
数据类型[]::new

使用类名引用实例方法的参数对应解释:

image-20231226113258838

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CAN通信的基本原理与实现方法

一. CAN协议概念 1.1 CAN 协议简介 CAN 是控制器局域网络 (Controller Area Network) 的简称&#xff0c;它是由研发和生产汽车电子产品著称的德国 BOSCH 公司开发的&#xff0c;并最终成为国际标准(ISO11519以及ISO11898),是国际上应用最广泛的现场总线之一。差异点如下&…

​三子棋(c语言)

前言&#xff1a; 三子棋是一种民间传统游戏&#xff0c;又叫九宫棋、圈圈叉叉棋、一条龙、井字棋等。游戏规则是双方对战&#xff0c;双方依次在9宫格棋盘上摆放棋子&#xff0c;率先将自己的三个棋子走成一条线就视为胜利。但因棋盘太小&#xff0c;三子棋在很多时候会出现和…

【CentOS 7.9】安装搜狗输入法教程

总览 1.如何在 centos7.x 中使用 搜狗输入法 一、安装依赖 1.切换至 root 用户 su root2.更新 yum yum update3.卸载 ibus rpm -e --nodeps ibus4.安装 epel 源 yum -y install epel-release5.安装 fcitx 环境、qtwebkit包 和 alien 转换工具等&#xff08;可以将 .deb …

静态网页设计——旅游景点介绍(HTML+CSS+JavaScript)

前言 声明&#xff1a;该文章只是做技术分享&#xff0c;若侵权请联系我删除。&#xff01;&#xff01; 感谢大佬的视频&#xff1a; https://www.bilibili.com/video/BV1f64y1N7uH/?vd_source5f425e0074a7f92921f53ab87712357b 使用技术&#xff1a;HTMLCSSJS&#xff08;…

系列十一、(三)Sentinel控制台

一、Sentinel控制台 二、实时监控 2.1、概述 实时监控&#xff0c;顾名思义是用来实时监控的&#xff0c;具体监控的是接口请求通过的QPS和拒绝的QPS&#xff0c;默认情况下没有访问记录&#xff0c;所以看不到任何记录&#xff0c;需要访问接口才会有记录。另外需要注意&…

[4K80 AI ISP IPC芯片]

4K80 AI ISP IPC芯片 Hi3403V100是一颗面向监控市场推出的专业 Ultra-HD Smart IP Camera SOC&#xff0c;该芯片最高支持四路sensor输入&#xff0c;支持最高4K60的ISP图像处理能力&#xff0c;支持3F WDR加粗样式、多级降噪、六轴防抖、硬件拼接等多种图像增强和处理算法&am…

easyrecovery16 (硬盘数据恢复软件)免费版

EasyRecovery是由球著名数据厂商Kroll Ontrack出品的一款便捷实用&#xff0c;功能强大的硬盘数据恢复软件。它能够全面恢复删除丢失数据&#xff0c;支持包括文档、表格、图片、音视频等各种文件类型。支持恢复不同存储介质数据&#xff1a;硬盘、光盘、U盘/移动硬盘、数码相机…

Vue3-35-路由-路由守卫的简单认识

什么是路由守卫 路由守卫&#xff0c;就是在 路由跳转 的过程中&#xff0c; 可以进行一些拦截&#xff0c;做一些逻辑判断&#xff0c; 控制该路由是否可以正常跳转的函数。常用的路由守卫有三个 &#xff1a; beforeEach() : 前置守卫&#xff0c;在路由 跳转前 就会被拦截&…

C++学习笔记——类作用域和抽象数据类型

目录 一、C类作用域 类内作用域 类外作用域 二、类作用域案列详细的解释说明 三、抽象数据类型 四、总结 类作用域 抽象数据类型&#xff08;ADT&#xff09; 五、图书馆管理系统 一、C类作用域 在C中&#xff0c;类作用域是指类定义中声明的标识符&#xff08;成员变…

【SpringCloud】之远程消费(进阶使用)

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是君易--鑨&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的博客专栏《SpringCloud开发之远程消费》。&#x1f3af;&a…

Linux第12步_磁盘重新分区

解决“挂载后的U盘出现中文乱码”后&#xff0c;我们接着学习“磁盘重新分区”&#xff0c;熟悉fdisk命令。 1、删除磁盘的分区 输入“cd /回车”&#xff0c;进入根目录 输入“ls /dev/sd*回车”&#xff0c;显示dev以sd所有文件。 输入“sudo fdisk /dev/sdb1回车” 输入…

瑜亮之争有结果了,6GHz(6425-7125MHz)全部或部分频段划分用于IMT系统

文章目录 6GHz&#xff08;6425-7125MHz&#xff09;全部或部分频段划分用于IMT系统Wi-Fi 7 使用的频段Wi-Fi 7 与IMT使用的频段存在重叠频谱分配有讲究6GHz频段未来如何利用如何看待6GHz频段划入IMT关于Wi-Fi 7 与IMT关于Wi-Fi 7(IEEE 802.11be EHT)关于IMT(International Mob…

从零开始的OpenGL光栅化渲染器构建1

前言 参照Learnopengl&#xff0c;我开始回顾OpenGL中的内容&#xff0c;最终目标是构建一个玩具级的光栅化渲染器&#xff0c;最好还能和之前做的光线追踪渲染器相结合&#xff0c;希望能够有所收获吧~ 包管理 之前我用CMake配置过OpenGL的环境&#xff0c;这样做出来的项目…

Vue3 + Vite + TypeScript + Element-Plus:从零到一构建企业级后台管理系统(前后端开源)

vue3-element-admin 是基于 vue-element-admin 升级的 Vue3 Element Plus 版本的后台管理前端解决方案&#xff0c;技术栈为 Vue3 Vite4 TypeScript Element Plus Pinia Vue Router 等当前主流框架。 相较于其他管理前端框架&#xff0c;vue3-element-admin 的优势在于一…

Python 面向对象之多态和鸭子类型

Python 面向对象之多态和鸭子类型 【一】多态 【1】概念 多态是面向对象的三大特征之一多态&#xff1a;允许不同的对象对同一操作做出不同的反应多态可以提高代码的灵活性&#xff0c;可扩展性&#xff0c;简化代码逻辑 【2】代码解释 在植物大战僵尸中&#xff0c;有寒冰…

vite4项目中,vant兼容750适配

一般非vite项目&#xff0c;使用postcss-px-to-viewport。在设计稿为750时候&#xff0c;可使用以下配置兼容vant。 在vite4项目中&#xff0c;以上配置不行。需要调整下&#xff0c;使用postcss-px-to-viewport-8-plugin&#xff0c;并修改viewportWidth&#xff0c;具体如下…

2 @RequestMapping 注解

1. RequestMapping 概念 SpringMVC 使用RequestMapping 注解为控制器指定可以处理哪些 URL 请求在控制器的类定义及方法定义处都可标注 RequestMapping 标记在类上&#xff1a;提供初步的请求映射信息。相对于 WEB 应用的根目录标记在方法上&#xff1a;提供进一步的细分映射信…

大创项目推荐 深度学习图像风格迁移 - opencv python

文章目录 0 前言1 VGG网络2 风格迁移3 内容损失4 风格损失5 主代码实现6 迁移模型实现7 效果展示8 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习图像风格迁移 - opencv python 该项目较为新颖&#xff0c;适合作为竞赛课题…

遇见狂神说 Spring学习笔记(完整笔记+代码)

简介 Spring是一个开源的免费的框架&#xff08;容器&#xff09;Spring是一个轻量级的、非入侵式的框架控制反转(IOC&#xff09;&#xff0c;面向切面编程 (AOP)支持事务的处理&#xff0c;支持对框架进行整合 Spring就是一个轻量级的控制反转&#xff08;IOC&#xff09;和…

视频智能分析支持摄像头异常位移检测,监测摄像机异常位移变化,保障监控状态

我们经常在生产场景中会遇到摄像头经过风吹日晒&#xff0c;或者异常的触碰&#xff0c;导致了角度或者位置的变化&#xff0c;这种情况下&#xff0c;如果不及时做出调整&#xff0c;会导致原本的监控条件被破坏&#xff0c;发生事件需要追溯的时候&#xff0c;查不到对应位置…