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...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...
[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...
