当前位置: 首页 > news >正文

JAVA后端开发——forEach 与方法引用(::)详解

1、案例代码

@Overridepublic  List<ModelDetailVo> selectModelList(ModelQuery query){List<ModelDetailVo> modelList = modelMapper.selectModelList(query);modelList.forEach(this::enrichModelDetailVo);return modelList;}private ModelDetailVo enrichModelDetailVo(ModelDetailVo vo) {if (vo == null) {return null;}if (vo.getSizeInBytes() != null) {vo.setSizeFormatted(formatBytes(vo.getSizeInBytes()));}if (vo.getModelTypeId() != null) {String typeName = DictUtils.getDictLabel("cloud_model_type", String.valueOf(vo.getModelTypeId()));vo.setModelTypeName(typeName);}return vo;}

这段代码的核心功能是:遍历 modelList 集合中的每一个 ModelDetailVo 对象,并对每个对象执行 enrichModelDetailVo 这个方法。这种写法是传统 for 循环的现代化替代方案,它利用了 Java 8 的函数式编程特性,使代码更简洁、更具表达力。

这个结构可以拆解为两个核心组件来理解:

  1. forEach() 方法。

  2. 方法引用 (::) 操作符。

2. 核心知识点一:List.forEach() 方法

forEach() 方法是在 Java 8 中被添加到 java.lang.Iterable 接口的,这意味着所有的集合(List、Set 等)都拥有这个方法。

  • 作用: 为集合中的每个元素执行一次给定的操作。

  • 方法签名: void forEach(Consumer<? super T> action)

  • 参数: 它接受一个 Consumer (消费者) 类型的参数。Consumer 是一个函数式接口,它代表了一个接受单个输入参数并且没有返回值的操作。通俗地讲,它就是“消费”一个元素,然后用这个元素去做一些事情。

3. 核心知识点二:方法引用 (::) 操作符

双冒号 :: 是 Java 8 中引入的方法引用操作符。它是一种用于直接引用已有方法的 Lambda 表达式的简化写法。当 Lambda 表达式的主体只是调用一个已存在的方法时,方法引用可以让代码更加清晰和易读。

让我们来分析 this::enrichModelDetailVo 这个部分:

  • this: 指代当前类的实例对象。

  • ::: 分隔符,用于连接对象/类与方法名。

  • enrichModelDetailVo: 需要被引用的实例方法名。

工作原理:
方法引用 this::enrichModelDetailVo 会被 Java 编译器自动转换成一个实现了 Consumer 接口的实例,而这正好是 forEach 方法所需要的参数类型。

4. 融会贯通:三种等价的代码写法

modelList.forEach(this::enrichModelDetailVo);

代码解读: “对于 modelList 中的每一个元素,都调用当前对象的 enrichModelDetailVo 方法,并将该元素作为参数传进去。”

方法引用本质上是 Lambda 表达式的一种语法。下面的代码在功能上与写法一完全相同。

modelList.forEach(vo -> this.enrichModelDetailVo(vo));

代码解读: “对于 modelList 中的每一个元素(我们临时称之为 vo),执行以下操作:调用 this.enrichModelDetailVo() 方法,并把 vo 作为参数传入。”

for (ModelDetailVo vo : modelList) {this.enrichModelDetailVo(vo);
}

代码解读: “创建一个循环来遍历 modelList。在每一次循环中,将当前元素赋值给变量 vo,然后用 vo 作为参数调用 this.enrichModelDetailVo() 方法。”

5. 使用 forEach 与方法引用的优势

对比维度forEach 与方法引用传统 for 循环
编程风格声明式 (Declarative) - “做什么”命令式 (Imperative) - “怎么做”
代码可读性。意图非常清晰:将一个操作应用于所有元素。。循环的样板代码可能会掩盖其核心操作。
代码简洁性非常高。一行富有表现力的代码即可完成。较低。需要多行代码和循环语法(for, (), {})。
代码表达力。清晰地将数据(modelList)和操作(enrichModelDetailVo)分离开。较低。迭代逻辑和业务操作逻辑耦合在一起。

6. 总结

  • 它是什么: modelList.forEach(this::enrichModelDetailVo); 是一种简洁的函数式循环,它将当前对象的 enrichModelDetailVo 方法应用到了 modelList 的每一个元素上。

  • 何时使用: 当你需要对一个集合的每个元素调用一个已经存在的、单一的方法时,这是最理想的选择。被引用的方法签名必须与所需的函数式接口兼容(forEach 需要的是 Consumer,即接受一个参数,返回 void)。这里的例子中 enrichModelDetailVo 方法虽然有返回值,但 forEach 会忽略它,因此是兼容的。

  • 何时避免: 如果你的循环体逻辑比单个方法调用更复杂(例如,包含多个 if/else 分支、调用多个方法或需要处理异常),那么使用多行 Lambda 表达式 forEach(vo -> { ... }); 或者传统的 for 循环可能会让代码的逻辑更清晰。

http://www.dtcms.com/a/362052.html

相关文章:

  • 剧想智读项目展示
  • 针对redis中的热数据该怎么处理
  • Qt 项目文件(.pro)中添加 UI 文件相关命令
  • 【系规伴学】云资源规划核心知识点解析
  • vcruntime140.dll丢失解决办法
  • pandas自学笔记16 pandas可视化
  • 继承体系中的隐藏机制解析(继承中的作用域)
  • Unity图集 SpriteAltas 打包探究
  • [界面通过zmq请求调用指定动态库函数(三)]将zmq请求集成二次开发接口
  • Android 文件下载 FileDownloader
  • TypeScript交叉类型、重复属性、类型断言和as const详解
  • 光颉科技)Viking)的CS25FTFR009 1225 0.009R/9mR 3W电阻介绍-华年商城
  • 【笔记】float类型的精度有限,无法精确表示123456.6789
  • 【Audio】静音或振动模式下重复来电响铃
  • Java Web项目后台管理系统之内容管理仿写(三):图片上传
  • 使用 BayesFlow 通过神经网络简化贝叶斯推断(一)
  • C扩展4:X宏(X-MACRO)
  • JS循环机制
  • IS-IS的原理
  • Java超卖问题
  • MySQL安装与使用指南
  • 【读论文】量子关联增强双梳光谱技术
  • 力扣404 代码随想录Day15 第三题
  • 故障排查指南:理解与解决 “No route to host“ 错误
  • NOSQL——Redis
  • MySQL基础知识保姆级教程(四)视图与约束
  • 浅谈中断控制器:从 IRQ 到 IRR、IMR、In-Service Register
  • 软考-操作系统-错题收集(3)文件系统的索引节点结构
  • 【前端】《手把手带你入门前端》前端的一整套从开发到打包流程, 这篇文章都会教会你;什么是vue,Ajax,Nginx,前端三大件?
  • ComPE for win 纯净的PE系统