lambda表达式 —— 过滤再排序未生效问题排查

背景

项目中有个场景,需要将一个列表先按要求过滤,再根据某字段排序。图方便使用lambda表达式修改原列表将过滤和排序逻辑写到一行,打印输出列表发现过滤未生效。
代码示例:

        List<Long> productIdList = Arrays.asList(1L);List<ProductDTO> productDTOList = new ArrayList<>();ProductDTO r1 = new ProductDTO();r1.setProductId(4L);r1.setPrice(100);productDTOList.add(r1);ProductDTO r2 = new ProductDTO();r2.setProductId(1L);r2.setPrice(20);productDTOList.add(r2);ProductDTO r3 = new ProductDTO();r3.setProductId(1L);r3.setPrice(100);productDTOList.add(r3);ProductDTO r4 = new ProductDTO();r4.setProductId(2L);r4.setPrice(150);productDTOList.add(r4);Map<Long, List<ProductDTO>> map = new HashMap<>();map.put(111L, productDTOList);

第一种 过滤+排序

      map.forEach((infoId, productList) -> {productList.stream().filter(e -> productIdList.contains(e.getProductId())).collect(Collectors.toList()).sort(Comparator.comparing(ProductDTO::getPrice).reversed());System.out.println("=================" + productList);});

输出结果:

=================[ProductDTO(productId=4, price=100, name=null), ProductDTO(productId=1, price=20, name=null), ProductDTO(productId=1, price=100, name=null), ProductDTO(productId=2, price=150, name=null)]

第二种 过滤排序拆两行

      map.forEach((infoId, productList) -> {productList = productList.stream().filter(e -> productIdList.contains(e.getProductId())).collect(Collectors.toList());productList.sort(Comparator.comparing(ProductDTO::getPrice).reversed());System.out.println("=================" + productList);});

输出结果:

=================[ProductDTO(productId=1, price=100, name=null), ProductDTO(productId=1, price=20, name=null)]

从上面示例可以看出第二种是我们需要的,第一种过滤没生效。

分析

针对下面这行代码,分析其运行过程。

productList.stream().filter(e -> productIdList.contains(e.getProductId())).collect(Collectors.toList()).sort(Comparator.comparing(ProductDTO::getPrice).reversed());
  • stream()
    productList被转换成一个Stream,以声明性方式处理数据集合;
  • filter(e -> productIdList.contains(e.getProductId()))
    Stream上的filter方法被调用,该方法接受一个返回boolean值的函数作为参数。它检查productList中的每一个元素e的productId是否包含在productIdList中,只有满足条件的元素会被保留在Stream中。
  • collect(Collectors.toList())
    经过filter操作后,Stream中的元素被收集到一个新的List中。
  • sort(Comparator.comparing(ProductDTO::getPrice).reversed()):
    新生成的List被排序。sort方法接受一个Comparator作为参数,用于定义排序规则。在这里,Comparator.comparing(ProductDTO::getPrice)创建了一个Comparator,它根据ProductDTO对象的getPrice方法返回的价格值进行排序。.reversed()表示降序排列。

综上,List 接口的 sort 方法使用了自然排序或者通过提供的 Comparator 进行排序,是对原始表进行排序,不会创建一个新的已排序的列表。在上述示例中,对collect(Collectors.toList())后生成的新列表进行排序,但新列表并未输出,对原列表productList无影响,既未过滤也未排序。

所以,上面第二种方案是先过滤再排序最后生成新列表返回,只不过原列表productList变量不再使用,指向新列表。也可以使用下面的写法。

List<ProductDTO> list = productList.stream().filter(e -> productIdList.contains(e.getProductId())).sorted((Comparator.comparing(ProductDTO::getPrice).reversed())).collect(Collectors.toList());

此时list和原有productList为两个不同的列表,输出结果也是我们需要的。

另外productList = productList.stream()...collect(Collectors.toList()); 这种写法将新生成的列表赋值给了productList变量,productList指向了一个新的列表,但不会改变productList内容。如果原始的productList列表没有其他引用指向它,被其他使用,之后会被垃圾回收器回收。
原变量不再使用可以这么写,但会使代码不够清晰甚至引用出现失误,可以创建一个新的变量来存储新列表。

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

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

相关文章

向爬虫而生---Redis 探究篇4<Redis主从复制(1)>

前言: 当涉及到Redis的高可用性和数据冗余时&#xff0c;主从复制是一个非常重要的概念。 在现代应用程序的开发中&#xff0c;数据的可靠性和高可用性是至关重要的。当涉及到数据冗余和故障恢复时&#xff0c;Redis主从复制成为一个必不可少的工具和技术。Redis主从复制是一…

蓝桥杯-单片机组基础5——外部中断与LED的控制(附小蜜蜂课程代码)

蓝桥杯单片机组备赛指南请查看这篇文章&#xff1a;戳此跳转蓝桥杯备赛指南文章 本文章针对蓝桥杯-单片机组比赛开发板所写&#xff0c;代码可直接在比赛开发板上使用。 型号&#xff1a;国信天长4T开发板&#xff08;绿板&#xff09;&#xff0c;芯片&#xff1a;IAP15F2K6…

自学软件测试怎么学?

软件测试是一个变得越来越受欢迎的行业&#xff0c;在IT行业里面&#xff0c;也是初学比较容易的。但对小白而言&#xff0c;怎样学习才能做到快速入门&#xff0c;少走弯路呢&#xff1f; 步骤一&#xff1a;初学学软件测试&#xff0c;要先搞懂这种问题 要想进入到软件测试…

Android Duplicate class 排除重复类

一、起因&#xff1a; 在迭代开发的时候&#xff0c;发现2个ijk很多类重复。但又2个库实现的功能是不一样&#xff0c;目前不能合并。但又想保留2个功能。需要排除其中一个库。 二、报错如何下图&#xff1a; 三、解决方法&#xff1a; 3.1 在terminal 也就是命令行处输入 …

Golang 并发机制 CSP模型

Golang 并发机制 CSP模型 1 前言 go语言的最大两个亮点&#xff0c;一个是 goroutine &#xff0c;一个就是 chan 了。二者合体的典型应用CSP&#xff0c;基本就是大家认可的并行开发神器&#xff0c;简化了并行程序的开发难度&#xff0c;我们来看一下CSP。 2 CSP是什么 C…

在Windows 11中运行磁盘清理工具的9种方法,总有一种适合你

自Windows98以来,微软在操作系统中包含了一个内置的清理工具。当用户转向第三方清理应用程序时,这个值得信赖的实用程序站稳了脚跟。微软甚至宣布,第三方应用程序几乎毫无用处,删除注册表项不是一个好主意。 磁盘清理工具可以帮助删除临时文件、旧的更新日志、缩略图缓存和…

git安装与使用4.3

一、git的安装 1、下载git包 下载git包url&#xff1a;https://git-scm.com/download/win 下载包分为&#xff1a;64位和32位 2、点击安装包 2、选择安装路径 3、 点击下一步 4、点击next 5、点击next 6、点击next 7、 8、 9、 10、 11、 12、在桌面空白处&#xff0c;右键…

【SpringBoot】测试单元使用多线程

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;SpringBoot ⛺️稳重求进&#xff0c;晒太阳 问题产生 今天学习了乐观锁&#xff0c;但在测试单元执行多线程的时候出现了问题&#xff0c;多线程并没有直接结果 在控制台没有任何输出…

KubeSphere平台安装系列之二【Linux单节点部署KubeSphere】(2/3)

**《KubeSphere平台安装系列》** 【Kubernetes上安装KubeSphere&#xff08;亲测–实操完整版&#xff09;】&#xff08;1/3&#xff09; 【Linux单节点部署KubeSphere】&#xff08;2/3&#xff09; 【Linux多节点部署KubeSphere】&#xff08;3/3&#xff09; **《KubeS…

RocketMQ学习笔记一

课程来源&#xff1a;002-MQ简介_哔哩哔哩_bilibili &#xff08;尚硅谷老雷&#xff0c;时长19h&#xff09; 第1章 RocketMQ概述 1. MQ是什么&#xff1f; 2. MQ用途有哪些&#xff1f; 限流削峰&#xff1b;异步解耦&#xff1b;数据收集。 3. 常见MQ产品有哪些&对比…

Kaggle竞赛之Titanic存活预测2

提高代码规范性&#xff0c;基于上一个 baseline 的提高 import pandas as pd from sklearn.preprocessing import LabelBinarizer from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split#数据划分方法 from sklearn.ensem…

哪个超声波清洗机品牌值得入手?销量榜品牌值得选购!

在科技日益发展的今天&#xff0c;超声波清洗技术以其高效、便捷和深度清洁的特点&#xff0c;已经深入到生活的诸多领域&#xff0c;从精密仪器到珠宝首饰&#xff0c;从眼镜框到假牙&#xff0c;甚至是厨房用品的日常护理&#xff0c;都能见到超声波清洗机的身影。面对市场上…

无人机两次飞行的图像数据配准与几何校正方法研究

标题: 无人机两次飞行的图像数据配准与几何校正方法研究 摘要: 本文研究了利用无人机获取的两次飞行的图像数据进行配准与几何校正的方法。无人机航拍技术在地理信息获取和空间数据应用中具有重要意义,但由于飞行条件、摄影设备和环境等因素的影响,同一区域的不同飞行任务…

【基频提取算法-YIN】

本文对基频提取算法 YIN 做以介绍。如有表述不当之处欢迎批评指正。欢迎任何形式的转载&#xff0c;但请务必注明出处。 文章目录 1. 引言2. YIN 各模块代码讲解2.1. 差分函数的实现2.2. 累积均值归一化差分函数的实现2.3. 绝对阈值2.4. 抛物线插值2.5. 最优局部估计 3. 总结 1…

免杀实战-EDR对抗

文章目录 杀软分析BOF.NET 杀软分析 x64dgb简单调试发现该edr在r3环对ntdll.dll和kernel32.dll关键函数均存在hook&#xff0c;这里硬盘读取原来的dll进行重新加载&#xff0c;原理如图 loader // dllmain.cpp : 定义 DLL 应用程序的入口点。 #include "pch.h" #in…

DSI2协议之BTA行为理解

概念: DSI协议spec支持总线控制权在master和slave之间发生交换,即通过bus turn around来实现; BUS TURN AROUND: BTA 的实现是通过controller—>cdphy的turnrequest信号来实现; 关于控制器发出turnrequest给phy,phy通过lvds/trio线输出turnaround sequence如下图中…

LeetCode刷题笔记之二叉树(四)

一、二叉搜索树的应用 1. 700【二叉搜索树中的搜索】 题目&#xff1a; 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和一个整数值 val。你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在&#xff0c;则返回 null 。代码&a…

BUGKU 本地管理员

打开环境&#xff0c;先F12查看看到一串代码。Base64解码一下&#xff0c;得到的应该是密码&#xff0c;然后输入admin | test123试一下 使用BP抓包&#xff0c;修改XFF&#xff0c;得到flag

将镜像上传到私有镜像仓库Harbor

首先你需要安装Harbor服务&#xff1a; https://blog.csdn.net/qq_50247813/article/details/136388229 客户端已经安装docker&#xff1a; https://docs.docker.com/engine/install/centos/ 在docker客户端登录 Harbor 我的Harbor 服务器地址&#xff1a; 192.168.44.161 账号…

关于编写测试用例的一些思考

测试用例是QA同学的基本功&#xff0c;每个人都有一套编写测试用例的体系&#xff0c;本文是作者结合自身的工作经验以及阅读一些测试相关的书籍后的一些看法&#xff0c;欢迎大家一起讨论学习。 测试设计 测试用例格式 面试中一些常见的问题 1.APP测试与服务端测试的区别&am…