Java基础(二十五):Lambda表达式、方法引用、构造器引用

news2025/1/13 13:45:54

Java基础系列文章

Java基础(一):语言概述

Java基础(二):原码、反码、补码及进制之间的运算

Java基础(三):数据类型与进制

Java基础(四):逻辑运算符和位运算符

Java基础(五):流程控制语句

Java基础(六):数组

Java基础(七):面向对象编程

Java基础(八):封装、继承、多态性

Java基础(九):Object 类的使用

Java基础(十):关键字static、代码块、关键字final

Java基础(十一):抽象类、接口、内部类

Java基础(十二):枚举类

Java基础(十三):注解(Annotation)

Java基础(十四):包装类

Java基础(十五):异常处理

Java基础(十六):String的常用API

Java基础(十七):日期时间API

Java基础(十八):java比较器、系统相关类、数学相关类

Java基础(十九):集合框架

Java基础(二十):泛型

Java基础(二十一):集合源码

Java基础(二十二):File类与IO流

Java基础(二十三):反射机制

Java基础(二十四):网络编程

Java基础(二十五):Lambda表达式、方法引用、构造器引用


目录

  • 一、Lambda表达式
    • 1、语法
    • 2、函数式(Functional)接口
      • 2.1、四大核心函数式接口
      • 2.2、消费型接口
      • 2.3、供给型接口
      • 2.4、函数型接口
      • 2.5、判断型接口
  • 二、方法引用
    • 1、方法引用格式
    • 2、举例
  • 三、构造器引用
  • 四、数组构造引用
  • 总结


一、Lambda表达式

1、语法

  • Lambda 表达式:在Java 8 语言中引入的一种新的语法元素和操作符
  • 这个操作符为 “->” , 该操作符被称为Lambda操作符箭头操作符
  • 它将 Lambda 分为两个部分:
    • 左侧:指定了 Lambda 表达式需要的参数列表
    • 右侧:指定了 Lambda 体,是抽象方法的实现逻辑,也即 Lambda 表达式要执行的功能

语法格式一:无参,无返回值

  • run方法名省略,保留无参()和具体实现类{内容}
@Test
public void test1(){
    //未使用Lambda表达式
    Runnable r1 = new Runnable() {
        @Override
        public void run() {
            System.out.println("我爱北京天安门");
        }
    };

    r1.run();

    System.out.println("***********************");

    //使用Lambda表达式
    Runnable r2 = () -> {
        System.out.println("我爱北京故宫");
    };

    r2.run();
}

语法格式二:一个参数,但是没有返回值

  • 只保留参数(类型 变量)和具体实现类{内容}
@Test
public void test2(){
    //未使用Lambda表达式
    Consumer<String> con = new Consumer<String>() {
        @Override
        public void accept(String s) {
            System.out.println(s);
        }
    };
    con.accept("谎言和誓言的区别是什么?");

    System.out.println("*******************");

    //使用Lambda表达式
    Consumer<String> con1 = (String s) -> {
        System.out.println(s);
    };
    con1.accept("一个是听得人当真了,一个是说的人当真了");
}

语法格式三:数据类型可以省略,因为可由编译器推断得出,称为“类型推断”

@Test
public void test3(){
    //语法格式三使用前
    Consumer<String> con1 = (String s) -> {
        System.out.println(s);
    };
    con1.accept("一个是听得人当真了,一个是说的人当真了");

    System.out.println("*******************");
    //语法格式三使用后
    Consumer<String> con2 = (s) -> {
        System.out.println(s);
    };
    con2.accept("一个是听得人当真了,一个是说的人当真了");
}

语法格式四:若只需要一个参数时,参数的小括号可以省略

@Test
public void test4(){
    //语法格式四使用前
    Consumer<String> con1 = (s) -> {
        System.out.println(s);
    };
    con1.accept("一个是听得人当真了,一个是说的人当真了");

    System.out.println("*******************");
    //语法格式四使用后
    Consumer<String> con2 = s -> {
        System.out.println(s);
    };
    con2.accept("一个是听得人当真了,一个是说的人当真了");
}

语法格式五:当Lambda体只有一条语句时,return与大括号若有,都可以省略

@Test
public void test5(){
    //语法格式五使用前
    Comparator<Integer> com1 = (o1,o2) -> {
        return o1.compareTo(o2);
    };

    System.out.println(com1.compare(12,6));

    System.out.println("*****************************");
    //语法格式五使用后
    Comparator<Integer> com2 = (o1,o2) -> o1.compareTo(o2);

    System.out.println(com2.compare(12,21));
}

语法格式六:需要两个或以上的参数,多条执行语句,并且可以有返回值

@Test
public void test6(){
    //语法格式六使用前
    Comparator<Integer> com1 = new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            System.out.println(o1);
            System.out.println(o2);
            return o1.compareTo(o2);
        }
    };

    System.out.println(com1.compare(12,21));
    System.out.println("*****************************");
    //语法格式六使用后
    Comparator<Integer> com2 = (o1,o2) -> {
        System.out.println(o1);
        System.out.println(o2);
        return o1.compareTo(o2);
    };
    System.out.println(com2.compare(12,6));
}

Lambda表达式的语法规则总结

  • -> 的左边:lambda形参列表,参数的类型都可以省略。如果形参只有一个,则一对()也可以省略
  • -> 的右边:lambda体,对应着重写的方法的方法体。如果方法体中只有一行执行语句,则一对{}可以省略。如果有return关键字,则必须一并省略

2、函数式(Functional)接口

  • 只包含一个抽象方法的接口,称为函数式接口。当然该接口可以包含其他非抽象方法
  • 可以在一个接口上使用 @FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口
  • java.util.function包下定义了Java 8 的丰富的函数式接口

2.1、四大核心函数式接口

函数式接口称谓参数类型用途
Consumer<T> 消费型接口T对类型为T的对象应用操作
包含方法: void accept(T t)
Supplier<T> 供给型接口返回类型为T的对象
包含方法:T get()
Function<T, R> 函数型接口T对类型为T的对象应用操作,并返回结果。结果是R类型的对象
包含方法:R apply(T t)
Predicate<T> 判断型接口T确定类型为T的对象是否满足某约束,并返回boolean值
包含方法:boolean test(T t)

消费型接口

在这里插入图片描述

@Test
public void test1() {
    List<String> list = Arrays.asList("hello", "java", "lambda");
    list.forEach(s -> System.out.println(s));
}

供给型接口

在这里插入图片描述

@Test
public void test2() {
    // 返回一个无限连续的无序流,其中每个元素都由提供的 Supplier 生成
    // 这适用于生成恒定流、随机元素流等
    Stream.generate(() -> Math.random()).forEach(System.out::println);
}

功能型接口

在这里插入图片描述

@Test
public void test3() {
    HashMap<Integer, String> map = new HashMap<>();
    map.put(1, "100");
    map.put(2, "200");
    map.put(3, "300");
    map.put(4, "400");
    map.put(5, "500");
    // 如果k为偶数,则返回v + "00",否则返回v
    map.replaceAll((k, v) -> {
        if (k % 2 == 0){
            return v + "00";
        }
        return v;
    });
    map.forEach((k, v) -> System.out.println(k + "=" + v));
}

功能型接口

在这里插入图片描述

@Test
public void test4() {
    ArrayList<String> list = new ArrayList<>();
    list.add("hello");
    list.add("java8");
    list.add("ok");
    list.add("yes");
    // 移除所有长度小于5的元素
    list.removeIf(str -> str.length() < 5);
    list.forEach(str -> System.out.println(str)); // hello java8
}

2.2、消费型接口

  • 消费型接口的抽象方法特点:有形参,但是返回值类型是void
接口名抽象方法描述
BiConsumer<T,U>void accept(T t, U u)接收两个对象用于完成功能
DoubleConsumervoid accept(double value)接收一个double值
IntConsumervoid accept(int value)接收一个int值
LongConsumervoid accept(long value)接收一个long值
ObjDoubleConsumervoid accept(T t, double value)接收一个对象和一个double值
ObjIntConsumervoid accept(T t, int value)接收一个对象和一个int值
ObjLongConsumervoid accept(T t, long value)接收一个对象和一个long值

2.3、供给型接口

  • 供给型接口的抽象方法特点:无参,但是有返回值
接口名抽象方法描述
BooleanSupplierboolean getAsBoolean()返回一个boolean值
DoubleSupplierdouble getAsDouble()返回一个double值
IntSupplierint getAsInt()返回一个int值
LongSupplierlong getAsLong()返回一个long值

2.4、函数型接口

  • 函数型接口的抽象方法特点:既有参数又有返回值
接口名抽象方法描述
UnaryOperatorT apply(T t)接收一个T类型对象,返回一个T类型对象结果
DoubleFunctionR apply(double value)接收一个double值,返回一个R类型对象
IntFunctionR apply(int value)接收一个int值,返回一个R类型对象
LongFunctionR apply(long value)接收一个long值,返回一个R类型对象
ToDoubleFunctiondouble applyAsDouble(T value)接收一个T类型对象,返回一个double
ToIntFunctionint applyAsInt(T value)接收一个T类型对象,返回一个int
ToLongFunctionlong applyAsLong(T value)接收一个T类型对象,返回一个long
DoubleToIntFunctionint applyAsInt(double value)接收一个double值,返回一个int结果
DoubleToLongFunctionlong applyAsLong(double value)接收一个double值,返回一个long结果
IntToDoubleFunctiondouble applyAsDouble(int value)接收一个int值,返回一个double结果
IntToLongFunctionlong applyAsLong(int value)接收一个int值,返回一个long结果
LongToDoubleFunctiondouble applyAsDouble(long value)接收一个long值,返回一个double结果
LongToIntFunctionint applyAsInt(long value)接收一个long值,返回一个int结果
DoubleUnaryOperatordouble applyAsDouble(double operand)接收一个double值,返回一个double
IntUnaryOperatorint applyAsInt(int operand)接收一个int值,返回一个int结果
LongUnaryOperatorlong applyAsLong(long operand)接收一个long值,返回一个long结果
BiFunction<T,U,R>R apply(T t, U u)接收一个T类型和一个U类型对象,返回一个R类型对象结果
BinaryOperatorT apply(T t, T u)接收两个T类型对象,返回一个T类型对象结果
ToDoubleBiFunction<T,U>double applyAsDouble(T t, U u)接收一个T类型和一个U类型对象,返回一个double
ToIntBiFunction<T,U>int applyAsInt(T t, U u)接收一个T类型和一个U类型对象,返回一个int
ToLongBiFunction<T,U>long applyAsLong(T t, U u)接收一个T类型和一个U类型对象,返回一个long
DoubleBinaryOperatordouble applyAsDouble(double left, double right)接收两个double值,返回一个double结果
IntBinaryOperatorint applyAsInt(int left, int right)接收两个int值,返回一个int结果
LongBinaryOperatorlong applyAsLong(long left, long right)接收两个long值,返回一个long结果

2.5、判断型接口

  • 判断型接口的抽象方法特点:有参,但是返回值类型是boolean结果
接口名抽象方法描述
BiPredicate<T,U>boolean test(T t, U u)接收两个对象
DoublePredicateboolean test(double value)接收一个double值
IntPredicateboolean test(int value)接收一个int值
LongPredicateboolean test(long value)接收一个long值

二、方法引用

  • 方法引用,可以看做是基于lambda表达式的进一步简化

1、方法引用格式

  • 情况1:对象 :: 实例方法名
    • 函数式接口中的抽象方法a在被重写时使用了某一个对象的方法b
    • 如果方法a的形参列表、返回值类型与方法b的形参列表、返回值类型都相同
    • 则我们可以使用方法b实现对方法a的重写、替换
  • 情况2:类 :: 静态方法名
    • 函数式接口中的抽象方法a在被重写时使用了某一个类的静态方法b
    • 如果方法a的形参列表、返回值类型与方法b的形参列表、返回值类型都相同
    • 则我们可以使用方法b实现对方法a的重写、替换
  • 情况3:类 :: 实例方法名
    • 函数式接口中的抽象方法a在被重写时使用了某一个对象的方法b
    • 如果方法a的返回值类型与方法b的返回值类型相同
    • 同时方法a的形参列表中有n个参数,方法b的形参列表有n-1个参数
    • 且方法a的第1个参数作为方法b的调用者,且方法a的后n-1参数与方法b的n-1参数匹配

2、举例

情况一:对象 :: 实例方法

  • Consumer中的void accept(T t)与PrintStream中的void println(T t)参数返回值相同
  • 后者直接替换掉前者
@Test
public void test1() {
	Consumer<String> con1 = str -> System.out.println(str);
	con1.accept("北京");

	System.out.println("*******************");
	PrintStream ps = System.out;
	Consumer<String> con2 = ps::println;
	con2.accept("beijing");
}
  • Supplier<String>中的T get()与Employee中的String getName()参数返回值相同
@Test
public void test2() {
	Employee emp = new Employee(1001,"Tom",23,5600);

	Supplier<String> sup1 = () -> emp.getName();
	System.out.println(sup1.get());

	System.out.println("*******************");
	Supplier<String> sup2 = emp::getName;
	System.out.println(sup2.get());
}

情况二:类 :: 静态方法

  • Comparator中的int compare(T t1,T t2)与Integer中的静态方法int compare(T t1,T t2)参数返回值相同
@Test
public void test3() {
	Comparator<Integer> com1 = (t1,t2) -> Integer.compare(t1,t2);
	System.out.println(com1.compare(12,21));

	System.out.println("*******************");

	Comparator<Integer> com2 = Integer::compare;
	System.out.println(com2.compare(12,3));
}
  • Function中的R apply(T t)与Math中的静态方法Long round(Double d)参数返回值相同
@Test
public void test4() {
	Function<Double,Long> func = new Function<Double, Long>() {
		@Override
		public Long apply(Double d) {
			return Math.round(d);
		}
	};

	System.out.println("*******************");

	Function<Double,Long> func1 = d -> Math.round(d);
	System.out.println(func1.apply(12.3));

	System.out.println("*******************");

	Function<Double,Long> func2 = Math::round;
	System.out.println(func2.apply(12.6));
}

情况三:类 :: 实例方法

  • a抽象方法第一个参数s1为b方法调用者,a抽象方法其他参数为b方法参数
@Test
public void test5() {
	Comparator<String> com1 = (s1,s2) -> s1.compareTo(s2);
	System.out.println(com1.compare("abc","abd"));

	System.out.println("*******************");

	Comparator<String> com2 = String :: compareTo;
	System.out.println(com2.compare("abd","abm"));
}
  • Function中的R apply(T t)与Employee中的String getName()返回值一样
  • e -> e.getName():第一参数e为后者的调用者
@Test
public void test6() {
	Employee employee = new Employee(1001, "Jerry", 23, 6000);

	Function<Employee,String> func1 = e -> e.getName();
	System.out.println(func1.apply(employee));

	System.out.println("*******************");
	Function<Employee,String> func2 = Employee::getName;
	System.out.println(func2.apply(employee));
}

三、构造器引用

  • 当Lambda表达式是创建一个对象,并且满足Lambda表达式形参正好是给创建这个对象的构造器的实参列表,就可以使用构造器引用
  • 格式:类名::new

空参构造器

@Test
public void test1(){
    Supplier<Employee> sup = new Supplier<Employee>() {
        @Override
        public Employee get() {
            return new Employee();
        }
    };
    System.out.println("*******************");

    Supplier<Employee>  sup1 = () -> new Employee();
    System.out.println(sup1.get());

    System.out.println("*******************");

    Supplier<Employee>  sup2 = Employee :: new;
    System.out.println(sup2.get());
}

多参构造器

  • 相当于BiFunction中的R apply(T t,U u)中的参数赋值给new Employee(id,name)
@Test
public void test2(){
    BiFunction<Integer,String,Employee> func1 = (id,name) -> new Employee(id,name);
    System.out.println(func1.apply(1001,"Tom"));

    System.out.println("*******************");

    BiFunction<Integer,String,Employee> func2 = Employee :: new;
    System.out.println(func2.apply(1002,"Tom"));
}

四、数组构造引用

  • 当Lambda表达式是创建一个数组对象,并且满足Lambda表达式形参正好是给创建这个数组对象的长度,就可以数组构造引用
  • 格式:数组类型名::new
@Test
public void test3(){
    Function<Integer,String[]> func1 = length -> new String[length];
    String[] arr1 = func1.apply(5);
    System.out.println(Arrays.toString(arr1));

    System.out.println("*******************");

    Function<Integer,String[]> func2 = String[] :: new;
    String[] arr2 = func2.apply(10);
    System.out.println(Arrays.toString(arr2));
}

总结

  • 只要看起来没有歧义,只能仅有调用某个方法,传入某些参数,就可以简化为Lambda表达式或方法构造器引用

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

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

相关文章

华为---RSTP(二)---RSTP基本配置示例

目录 1. 示例要求 2. 网络拓扑图 3. 配置命令 4. 测试终端连通性 5. RSTP基本配置 5.1 启用STP 5.2 修改生成树协议模式为RSTP 5.3 配置根交换机和次根交换机 5.4 设置边缘端口 6. 指定端口切换为备份端口 7. 测试验证网络 1. 示例要求 为防止网络出现环路&#xf…

芋道-------如何实现工作流退回后重新提交到之前退回的节点

一、概述 上一节&#xff0c;我们讲过了工作流如何退回到申请人&#xff0c;接下来我们来讲一讲&#xff0c;如何重新提交。这里重新提交可以是再走一遍正常流程&#xff0c;同时也可以是直接跳过中间的步骤&#xff0c;直接继续给上一步退回的人审批。文章中会提及这两种情况。…

2、windows环境下vscode开发c/c++环境配置(一)

前言&#xff1a;VSCode是微软出的一款轻量级编辑器&#xff0c;它本身只是一款文本编辑器而已&#xff0c;并不是一个集成开发环境(IDE)&#xff0c;几乎所有功能都是以插件扩展的形式所存在的。因此&#xff0c;我们想用它编程&#xff0c;不只是把vscode下载下来就行&#x…

MQ最终一致性理论与实践

MQ最终一致性理论与实践 原理 分布式事务无论是2PC&3PC还是TCC&#xff0c;基本都遵守XA协议的思想&#xff0c;但全局事务方案并发性较差&#xff1b; 最终一致性方案指的是将最有可能出错的业务以本地事务的方式完成后&#xff0c;采用不断重试的方式&#xff08;不限…

Sora内测申请详细教程

Sora内测申请详细教程 Sora 的创作能力&#xff0c;已经让很多人震惊了&#xff0c;自己制作电影的时代来了&#xff0c;以前做个短视频觉得已经够满足了&#xff0c;现在人人都能成为导演。 这几天大家都在等什么时候能用上&#xff0c;我给他分享一个可能提前用上Sora的方法…

Panalog大数据日志审计系统libres_syn_delete.php存在命令执行漏洞

文章目录 前言声明一、Panalog大数据日志审计系统简介二、漏洞描述三、影响版本四、漏洞复现五、整改意见 前言 Panalog大数据日志审计系统定位于将大数据产品应用于高校、 公安、 政企、 医疗、 金融、 能源等行业之中&#xff0c;针对网络流量的信息进行日志留存&#xff0c…

MyBatis学习总结

MyBatis分页如何实现 分页分为 逻辑分页&#xff1a;查询出所有的数据缓存到内存里面&#xff0c;在从内存中筛选出需要的数据进行分页 物理分页&#xff1a;直接用数据库语法进行分页limit mybatis提供四种方法分页&#xff1a; 直接在sql语句中分页&#xff0c;传递分页参数…

多进程(1)

1> 使用多个进程实现文件拷贝 #include<myhead.h> int main(int argc, const char *argv[]) {pid_t pid;pidfork();int fdr;char buf;if((fdropen(argv[1],O_RDONLY))-1){perror("open error");return -1;}int lenlseek(fdr,0,SEEK_END)-lseek(fdr,0,SEEK_…

openGauss学习笔记-224 openGauss性能调优-系统调优-数据库系统参数调优-数据库并发队列参数调优

文章目录 openGauss学习笔记-224 openGauss性能调优-系统调优-数据库系统参数调优-数据库并发队列参数调优224.1 全局并发队列224.2 局部并发队列 openGauss学习笔记-224 openGauss性能调优-系统调优-数据库系统参数调优-数据库并发队列参数调优 数据库提供两种手段进行并发队…

掌握社区店选址技巧,提升商业成功率

对于想开实体店或创业的人来说&#xff0c;选址是决定商业成功的关键因素之一。本人在社区店开鲜奶吧5年时间&#xff0c;我将分享一些实用的社区店选址技巧&#xff0c;帮助你提升商业成功率。 1、人口密度和流量&#xff1a; 选择人口密集、流量大的社区&#xff0c;这样可以…

redis scan命令导致cpu飙升

一.背景 今天下午Redis的cpu占用突然异常升高&#xff0c;一度占用达到了90%&#xff0c;触发了钉钉告警&#xff0c;之后又回到正常水平&#xff0c;跟DBA沟通&#xff0c;他说主要是下面这个语句的问题 SCAN 0 MATCH fastUser:6136* COUNT 10000这个语句的执行时长很短&…

苍穹外卖学习-----2024/02/19

1.开发环境搭建 我的git截图我使用的datagrip 运行sql学习到jwt令牌一种新的配置方式&#xff0c;写配置文件学习到了build属性nginx解决跨域的问题2.导入接口的文档 结果如图所示 3.Swagger /*** 通过knife4j生成接口文档* return*/Beanpublic Docket docket() {ApiInfo api…

论文阅读——ONE-PEACE

ONE-PEACE: EXPLORING ONE GENERAL REPRESENTATION MODEL TOWARD UNLIMITED MODALITIES 适应不同模态并且支持多模态交互。 预训练任务不仅能提取单模态信息&#xff0c;还能模态间对齐。 预训练任务通用且直接&#xff0c;使得他们可以应用到不同模态。 各个模态独立编码&am…

阿里云服务器多少钱一台?61元一年您看行吗?

2024年阿里云服务器租用价格表更新&#xff0c;云服务器ECS经济型e实例2核2G、3M固定带宽99元一年、ECS u1实例2核4G、5M固定带宽、80G ESSD Entry盘优惠价格199元一年&#xff0c;轻量应用服务器2核2G3M带宽轻量服务器一年61元、2核4G4M带宽轻量服务器一年165元12个月、2核4G服…

Python简单小案例之 筷手美女下载保存本地

嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 知识点: 动态数据抓包 requests发送请求 开发环境: python 3.8 运行代码 解释器 pycharm 2022.3 辅助敲代码 编辑器 requests pip install requests &#x1f447; &#x1f447; &#x1f447; 更多精彩机密、教程&…

【C++】类与对象(构造函数、析构函数、拷贝构造函数、常引用)

&#x1f308;个人主页&#xff1a;秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343&#x1f525; 系列专栏&#xff1a;http://t.csdnimg.cn/eCa5z 目录 类的6个默认成员函数 构造函数 特性 析构函数 特性 析构的顺序 拷贝构造函数 特性 常引用 前言 &…

频谱仿真平台HTZ Communications为私有5G建设铺平道路

韩国的国家监管机构韩国通信委员会&#xff08;KCA&#xff09;计划在德思特频谱仿真平台HTZ Communications的支持下加快扩大无线电接入范围&#xff0c;提升全国电信服务的质量和效率。 韩国通信委员会&#xff08;KCA&#xff09;在韩国的监管环境中扮演着至关重要的角色&am…

Spring6学习技术|IoC+基于xml管理bean

学习材料 尚硅谷Spring零基础入门到进阶&#xff0c;一套搞定spring6全套视频教程&#xff08;源码级讲解&#xff09; IoC 控制反转。是一种设计思想。 1.获取bean对象的方法 通过id&#xff0c;通过class&#xff0c;和双重方式。 ApplicationContext context new Cla…

云呐智能运维硬件包括哪些?智能运维体系包括哪些?

智能运维体系时&#xff0c;能够详细了解该体系包含的各个组成部分。具体来说&#xff0c;我们应该知道智能运维体系中涉及的软件组件有哪些&#xff0c;以及这些组件是如何相互协作以实现高效运维的。此外&#xff0c;智能运维体系中使用的硬件设备感兴趣。列举了智能运维硬件…

测试工具之压测工具JMeter(一)

有时候我们接到的需求是秒杀或者抽奖类的功能开发&#xff0c;这时候可能会在某一时间点大量请求并发&#xff0c;我们手工自测很难发现一些高并发场景下的问题&#xff0c;这时候可以借助一些压测工具帮我们模拟出大量请求来测试我们的接口是否能满足业务要求。JMeter是Apache…