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...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...

Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
Java数值运算常见陷阱与规避方法
整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...