Java封装一个根据指定的字段来获取子集的工具类
工具类
ZhLambdaUtils
@SuppressWarnings("all")
public class ZhLambdaUtils {/*** METHOD_NAME*/private static final String METHOD_NAME = "writeReplace";/*** 获取到lambda参数的方法名称** @param <T> parameter* @param function function* @return the name* @since 2023.1.1*/public static <T> String getLambdaMethodName(FilterUtils.ZhFunction<T, ?> function) {try {return ((SerializedLambda) MethodUtils.invokeMethod(function, true, METHOD_NAME)).getImplMethodName();} catch (Exception e) {throw new RuntimeException(e);}}/*** Method to property** @param name name* @return the string* @since 2023.1.1*/public static String methodToProperty(String name) {if (name.startsWith("is")) {name = name.substring(2);} else {if (!name.startsWith("get") && !name.startsWith("set")) {throw new IllegalArgumentException("Error parsing property name '" + name + "'. Didn't start with 'is', 'get' or 'set'.");}name = name.substring(3);}if (name.length() == 1 || name.length() > 1 && !Character.isUpperCase(name.charAt(1))) {name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1);}return name;}/*** Is property** @param name name* @return the boolean* @since 2023.1.1*/public static boolean isProperty(String name) {return isGetter(name) || isSetter(name);}/*** Is getter** @param name name* @return the boolean* @since 2023.1.1*/public static boolean isGetter(String name) {return name.startsWith("get") && name.length() > 3 || name.startsWith("is") && name.length() > 2;}/*** Is setter** @param name name* @return the boolean* @since 2023.1.1*/public static boolean isSetter(String name) {return name.startsWith("set") && name.length() > 3;}}
SelectSubsetUtils
该工具类可以实现通过对象的指定字段实现双向遍历
/*** 通过本级唯一key值,以及本级字段、父级字段迭查询所有本级的子集*/
@UtilityClass
public class SelectSubsetUtils {/*** Filter** @param <D> parameter* @param origin 需要被过滤的数据集* @param left 本级唯一key -例如code* @param right 本级与父级关联key值 -例如parentCode* @param adjust 本级唯一key值过滤条件* @return the list* @since 2023.1.1*/public static <D> List<D> filterSon(List<D> origin, ZhFunction<D, ?> left, ZhFunction<D, ?> right, Adjust adjust) {return filter(origin, left, right, adjust, false);}/*** Filter parent** @param <D> parameter* @param origin 需要被过滤的数据集* @param left 本级唯一key -例如code* @param right 本级与父级关联key值 -例如parentCode* @param adjust 本级唯一key值过滤条件* @return the list* @since 2023.1.1*/public static <D> List<D> filterParent(List<D> origin, ZhFunction<D, ?> left, ZhFunction<D, ?> right, Adjust adjust) {return filter(origin, left, right, adjust, true);}/*** Filter** @param <D> parameter* @param origin origin* @param left left* @param right right* @param adjust adjust* @param reverset reverset* @return the list* @since 2023.1.1*/private static <D> List<D> filter(List<D> origin, ZhFunction<D, ?> left, ZhFunction<D, ?> right,Adjust adjust, Boolean reverset) {//过滤全量数据按照本级唯一key进行过滤List<D> ds = origin.stream().filter(o -> {//通过反射获取到传递进来的本级唯一key值Object value = getObject(left, o);return adjust.test(value);}).collect(Collectors.toList());//调用与父级关联的key值进行递归过滤if (reverset) {// 如果是反转,那么就是父级过滤return filter(origin, ds, left, right);} else {// 如果是正常,那么就是子级过滤return filter(origin, ds, right, left);}}/*** Filter** @param <D> parameter* @param origin 需要被过滤的数据源* @param filter 被过滤后的数据集* @param left 本级唯一key -例如code* @param right 本级与父级关联key值 -例如parentCode* @return the list* @since 2023.1.1*/private static <D> List<D> filter(List<D> origin, List<D> filter, ZhFunction<D, ?> left, ZhFunction<D, ?> right) {//构建本级过滤的数据,然后拿出来跟全量数据再次进行比对List<D> list = new LinkedList<>(filter);if (CollectionUtils.isEmpty(filter)) {return list;}//遍历过滤后的数据集filter.forEach(f -> {//跟全量的数据进行比较List<D> ds = origin.stream().filter(o -> {//将全量的数据和过滤出的数据进行比较,找出后续的子节点Object value = getObject(left, o);Object value2 = getObject(right, f);return value.equals(value2);}).collect(Collectors.toList());if (CollectionUtils.isEmpty(ds)) {return;}//递归调用list.addAll(filter(origin, ds, left, right));});return list;}/*** 获取值** @param <D> parameter* @param firstFiled first filed* @param d d* @return object object* @since 2023.1.1*/private static <D> Object getObject(ZhFunction<D, ?> firstFiled, D d) {String lambdaMethodName = ZhLambdaUtils.getLambdaMethodName(firstFiled);//获取到字段名称String fieldName = ZhLambdaUtils.methodToProperty(lambdaMethodName);Object value = null;try {Field field = FieldUtils.getDeclaredField(d.getClass(), fieldName, true);value = field.get(d);} catch (Exception e) {throw new RuntimeException(e);}return value;}/*** 自定义判断函数*/@FunctionalInterfacepublic interface Adjust {/*** Test** @param value value* @return the boolean* @since 2023.1.1*/boolean test(Object value);}/*** 自定义 Serializable 函数接口,这个接口有大用,至于为什么可以看下面参考博客*/@FunctionalInterfacepublic interface ZhFunction<T, R> extends Function<T, R>, Serializable {}}
测试
寻找字段 Code 为 1681497872765722624,并且关联的父级code为 ParentCode 的所有子集
public static void main(String[] args) {List<A> list = new ArrayList<>();A a = new A("1", "1681497872765722624");A a2 = new A("1681497872765722624", "1681498005196677120");A a3 = new A("1681497872765722624", "1681498062989991936");A a4 = new A("1681497872765722624", "1681498151091347456");A a5 = new A("1681498151091347456", "2");A a6 = new A("1681498151091347456", "3");A a7 = new A("8", "7");A a8 = new A("", "8");list.add(a);list.add(a2);list.add(a3);list.add(a4);list.add(a5);list.add(a6);list.add(a7);list.add(a8);List<A> target = filter(list, A::getCode, A::getParentCode, "1681497872765722624"::equals);target.forEach(System.out::println);
}

参考文档:
函数接口实现Serializable的用处说明
相关文章:
Java封装一个根据指定的字段来获取子集的工具类
工具类 ZhLambdaUtils SuppressWarnings("all") public class ZhLambdaUtils {/*** METHOD_NAME*/private static final String METHOD_NAME "writeReplace";/*** 获取到lambda参数的方法名称** param <T> parameter* param function functi…...
【HUST】网安纳米|2023年研究生纳米技术考试参考
目录 1 纳米材料是什么 2 纳米材料的结构特性 3 纳米结构的其他特性 4 纳米结构的检测技术 5 纳米材料的应用 打印建议:PPT彩印(这样重点比较突出),每面12张PPT,简单做一下关键词目录,亲测可以看清。如…...
【移远QuecPython】EC800M物联网开发板的MQTT协议腾讯云数据上报
【移远QuecPython】EC800M物联网开发板的MQTT协议腾讯云数据上报 文章目录 导入库初始化设置MQTT注册回调订阅发布功能开启服务发送消息函数打包调用测试效果附录:列表的赋值类型和py打包列表赋值BUG复现代码改进优化总结 py打包 导入库 from TenCentYun import TX…...
关灯游戏及扩展
7.8 图形界面应用案例——关灯游戏 题目: [案例]游戏初步——关灯游戏。 关灯游戏是很有意思的益智游戏,玩家通过单击关掉(或打开)一盏灯。如果关(掉(或打开)一个电灯,其周围(上下左右)的电灯也会触及开关,成…...
深度解析:用Python爬虫逆向破解dappradar的URL加密参数(最详细逆向实战教程,小白进阶高手之路)
特别声明:本篇文章仅供学习与研究使用,不得用做任何非法用途,请大家遵守相关法律法规 目录 一、逆向目标二、准备工作三、逆向分析 - 太详细了!3.1 逆向前的一些想法3.1.1 加密字符串属性猜测3.1.2 是否可以手动复制加密API?3.2 XHR断点调试3.3 加密前各参数属性的变化情况…...
论文笔记:AttnMove: History Enhanced Trajectory Recovery via AttentionalNetwork
AAAI 2021 1 intro 1.1 背景 将用户稀疏的轨迹数据恢复至细粒度的轨迹数据是十分重要的恢复稀疏轨迹数据至细粒度轨迹数据是非常困难的 已观察到的用户位置数据十分稀疏,使得未观察到的用户位置存在较多的不确定性真实数据中存在大量噪声,如何有效的挖…...
Django之视图层
目录 一、三板斧的使用 二、JsonReponse序列化类的使用 三、 form表单上传文件 数据准备 数据处理 (1)post请求数据 (2)文件数据获取 四、 FBV与CBV 五、CBV的源码分析 as_view 方法 一、三板斧的使用 HttpResponse 返回字符串类型render 渲染html页面,并…...
DAY54 392.判断子序列 + 115.不同的子序列
392.判断子序列 题目要求:给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是…...
【Nginx】nginx | 微信小程序验证域名配置
【Nginx】nginx | 微信小程序验证域名配置 一、说明二、域名管理 一、说明 小程序需要添加头条的功能,内容涉及到富文本内容显示图片资源存储在minio中,域名访问。微信小程序需要验证才能显示。 二、域名管理 服务器是阿里云,用的宝塔管理…...
大数据Doris(二十二):数据查看导入
文章目录 数据查看导入 数据查看导入 Broker load 导入方式由于是异步的,所以用户必须将创建导入的 Label 记录,并且在查看导入命令中使用 Label 来查看导入结果。查看导入命令在所有导入方式中是通用的,具体语法可执行 HELP SHOW LOAD 查看。 show load order by create…...
STM32 I2C详解
STM32 I2C详解 I2C简介 I2C(Inter IC Bus)是由Philips公司开发的一种通用数据总线 两根通信线: SCL(Serial Clock)串行时钟线,使用同步的时序,降低对硬件的依赖,同时同步的时序稳定…...
软考 系统架构设计师系列知识点之云计算(1)
所属章节: 第11章. 未来信息综合技术 第6节. 云计算和大数据技术概述 大数据和云计算已成为IT领域的两种主流技术。“数据是重要资产”这一概念已成为大家的共识,众多公司争相分析、挖掘大数据背后的重要财富。同时学术界、产业界和政府都对云计算产生了…...
VS Code画流程图:draw.io插件
文章目录 简介快捷键 简介 Draw.io是著名的流程图绘制软件,开源免费,对标Visio,用过的都说好。而且除了提供常规的桌面软件之外,直接访问draw.io就可以在线使用,堪称百分之百跨平台,便捷性直接拉满。 那么…...
计算机 - - - 浏览器网页打开本地exe程序,网页打开微信,网页打开迅雷
效果 在电脑中安装了微信和迅雷,可以通过在地址栏中输入weixin:打开微信,输入magnet:打开迅雷。 同理:在网页中使用a标签,点击后跳转链接打开weixin:,也会同样打开微信。 运用同样的原理,在网页中点击超…...
C_6练习题
一、单项选择题(本大题共20小题,每小题2分,共40分。在每小题给出的四个备选项中,选出一个正确的答案,并将所选项前的字母填写在答题纸的相应位置上。) 下列叙述中正确的是()。 A.C语言程序将从源程序中第一个函数开始执行 B.可以在程序中由用户指定任意一个函数作为…...
XUbuntu22.04之安装pkg-config(一百九十二)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…...
【Proteus仿真】【51单片机】拔河游戏设计
文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真51单片机控制器,使用按键、LED、动态数码管模块等。 主要功能: 系统运行后,指示灯处于中间位置,数码管显示得分0,当按下…...
第3关:集合操作100
任务描述相关知识编程要求测试说明 任务描述 本关任务:使用 集合操作解决实际问题 相关知识 1.集合并操作符 可转换为SQL 若R,S的属性名不同,可使用重命名使相应列名一致后进行并操作 例如:R(A,B,C) S(D,E,F) select A,B from R union sel…...
八:ffmpeg命令提取像素格式和PCM数据
一、提取YUV #提取3秒数据,分辨率和源视频一致 fmpeg -i test_1280x720.mp4 -t 3 -pix_fmt yuv420p yuv420p_orig.yuv#提取3秒数据,分辨率转为320x240 ffmpeg -i test_1280x720.mp4 -t 3 -pix_fmt yuv420p -s 320x240 yuv420p_320x240.yuv 二、提取RGB…...
rinex3.04 导航文件
GPS GLA BDS GLO...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...
Web后端基础(基础知识)
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...
