直接上代码,缺包的自行替换为自己项目中存在的

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate; import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import cn.hutool.core.util.ObjectUtil; /**
* @description:数据列表关联,类似于sql中的join
* @author: Binz
* @time:2019-09-29 09:40
*/
public class Java8Util { private static final Logger logger = LoggerFactory.getLogger(Java8Util.class); /**
* @description:关联到主表的基本类型属性去 一对多
* @param: t1 主表
* @param: t2 关联表
* @param: t1JoinKey 主表的关联key
* @param: t2JoinKey 关联表的关联key
* @param: toT1ListProperty 需要赋值到t1的List属性
* @return
* @author: Binz
* @time:2019-09-29 09:44
* <pre>
* 例如:Java8Util.joinToList(users, roles, User::getId, Role::getUserId, User::setRoles);
* </pre>
*/
public static <P,C,JR> void joinToList(Collection<P> t1, Collection<C> t2,Function<P, JR> t1JoinKey ,Function<C,JR> t2JoinKey,BiConsumer<P,List<C>> toT1ListProperty) {
try {
Map<Object,List<C>> valueMap = new HashMap<>();
JR t2JoinValue;
for (C c : t2) {
t2JoinValue = t2JoinKey.apply(c);
valueMap.putIfAbsent(t2JoinValue, new ArrayList<>());
valueMap.get(t2JoinValue).add(c);
}
JR t1JoinValue;
List<C> list;
for (P p : t1) {
t1JoinValue = t1JoinKey.apply(p);
list = valueMap.get(t1JoinValue);
toT1ListProperty.accept(p, list);
}
} catch (Exception e) {
logger.error( ExceptionUtils.getStackTrace(e));
}
} /**
* @description:关联到主表的基本类型属性去 一对多
* @param: t1 主表
* @param: t2 关联表
* @param: t1JoinKey 主表的关联key
* @param: t2JoinKey 关联表的关联key
* @param: getT2PropertyKey 获取t2指定属性
* @param: toT1ListProperty 需要赋值到t1的List属性
* @return
* @author: Binz
* @time:2019-09-29 09:44
* <pre>
* 例如:Java8Util.joinToListProperty(users, roles, User::getId, Role::getUserId, Role::Id ,Role::getName , User::setRoleNames);
* </pre>
*/
public static <P,C,JR,SR> void joinToListProperty(Collection<P> t1, Collection<C> t2,Function<P, JR> t1JoinKey ,Function<C,JR> t2JoinKey,Function<C, SR> getT2PropertyKey ,BiConsumer<P,List<SR>> toT1PropertyKey) {
try {
Map<Object,List<SR>> valueMap = new HashMap<>();
JR t2JoinValue;
for (C c : t2) {
t2JoinValue = t2JoinKey.apply(c);
valueMap.putIfAbsent(t2JoinValue, new ArrayList<>());
valueMap.get(t2JoinValue).add(getT2PropertyKey.apply(c));
}
JR t1JoinValue;
List<SR> list;
for (P p : t1) {
t1JoinValue = t1JoinKey.apply(p);
list = valueMap.get(t1JoinValue);
toT1PropertyKey.accept(p,list);
}
} catch (Exception e) {
logger.error( ExceptionUtils.getStackTrace(e));
}
} public static <P,C,JR,SR> void joinToSetProperty(Collection<P> t1, Collection<C> t2,Function<P, JR> t1JoinKey ,Function<C,JR> t2JoinKey,Function<C, SR> getT2PropertyKey ,BiConsumer<P,Set<SR>> toT1PropertyKey) {
try {
Map<Object,Set<SR>> valueMap = new HashMap<>();
JR t2JoinValue;
for (C c : t2) {
t2JoinValue = t2JoinKey.apply(c);
valueMap.putIfAbsent(t2JoinValue, new HashSet<>());
valueMap.get(t2JoinValue).add(getT2PropertyKey.apply(c));
}
JR t1JoinValue;
Set<SR> list;
for (P p : t1) {
t1JoinValue = t1JoinKey.apply(p);
list = valueMap.get(t1JoinValue);
toT1PropertyKey.accept(p,list);
}
} catch (Exception e) {
logger.error( ExceptionUtils.getStackTrace(e));
}
} /**
* @description:关联到主表的基本类型属性去 一对一
* @param: t1 主表
* @param: t2 关联表
* @param: t1JoinKey 主表的关联key
* @param: t2JoinKey 关联表的关联key
* @param: toT1PropertyKey 把t2 设置到 t1指定的属性
* @return
* @author: Binz
* @time:2019-09-29 09:44
* <pre>
* 例如:joinToEntity(users, accountss, User::getId, Account::getUserId, User::setAccount);
* </pre>
*/
public static <P,C,JR> void joinToEntity(Collection<P> t1, Collection<C> t2,Function<P, JR> t1JoinKey ,Function<C,JR> t2JoinKey,BiConsumer<P,C> toT1EntityProperty) {
try {
Map<Object,List<P>> m1 = new HashMap<>(t1.size());
Object t1KeyValue;
for (P p : t1) {
t1KeyValue = t1JoinKey.apply(p);
m1.putIfAbsent(t1KeyValue, new ArrayList<>());
m1.get(t1KeyValue).add(p);
}
Object t2JoinKeyValue;
List<P> ps;
for (C c : t2) {
t2JoinKeyValue = t2JoinKey.apply(c);
ps = m1.get(t2JoinKeyValue);
if(ps != null) {
for (P p : ps) {
toT1EntityProperty.accept(p, c);
}
}
}
} catch (Exception e) {
logger.error( ExceptionUtils.getStackTrace(e));
}
} /**
* @description:关联到主表的基本类型属性去 一对一
* @param: t1 主表
* @param: t2 关联表
* @param: t1JoinKey 主表的关联key
* @param: t2JoinKey 关联表的关联key
* @param: getT2PropertyKey 从t2获取某一个值
* @param: toT1PropertyKey 把t2获取到的值设置到 t1指定的属性
* @return
* @author: Binz
* @time:2019-09-29 09:44
* <pre>
* 例如:joinToEntity(users, accountss, User::getId, Account::getUserId, User::setAccount);
* </pre>
*/
public static <P,C,JR> void joinToEntityByFilter(Collection<P> t1, Collection<C> t2,Function<P, JR> t1JoinKey ,Function<C,JR> t2JoinKey,Predicate<P> t1Filter,Predicate<C> t2Filter,BiConsumer<P,C> toT1EntityProperty) {
try {
Map<Object,List<P>> m1 = new HashMap<>(t1.size());
Object t1KeyValue;
for (P p : t1) {
if(t1Filter == null || t1Filter.test(p)) {
t1KeyValue = t1JoinKey.apply(p);
m1.putIfAbsent(t1KeyValue, new ArrayList<>());
m1.get(t1KeyValue).add(p);
}
}
Object t2JoinKeyValue;
List<P> ps;
for (C c : t2) {
if(t2Filter == null || t2Filter.test(c)) {
t2JoinKeyValue = t2JoinKey.apply(c);
ps = m1.get(t2JoinKeyValue);
if(ps != null) {
for (P p : ps) {
toT1EntityProperty.accept(p, c);
}
}
}
}
} catch (Exception e) {
logger.error( ExceptionUtils.getStackTrace(e));
}
} /**
* @description:关联到主表的基本类型属性去 一对一
* @param: t1 主表
* @param: t2 关联表
* @param: t1JoinKey 主表的关联key
* @param: t2JoinKey 关联表的关联key
* @param: getT2PropertyKey 从t2获取某一个值
* @param: toT1PropertyKey 把t2获取到的值设置到 t1指定的属性
* @return
* @author: Binz
* @time:2019-09-29 09:44
* <pre>
* 例如:joinToProperty(users, persons, User::getId, Person::getUserId, Person::getRealName User::setRealName);
* </pre>
*/
public static <P,C,JR,SR> void joinToProperty(Collection<P> t1, Collection<C> t2,Function<P, JR> t1JoinKey ,Function<C,JR> t2JoinKey,Function<C, SR> getT2PropertyKey ,BiConsumer<P,SR> toT1PropertyKey) {
try {
Map<Object,List<P>> m1 = new HashMap<>(t1.size());
Object t1KeyValue;
for (P p : t1) {
t1KeyValue = t1JoinKey.apply(p);
m1.putIfAbsent(t1KeyValue, new ArrayList<>());
m1.get(t1KeyValue).add(p);
}
Object t2JoinKeyValue;
List<P> ps;
for (C c : t2) {
t2JoinKeyValue = t2JoinKey.apply(c);
ps = m1.get(t2JoinKeyValue);
if(ps != null) {
for (P p : ps) {
toT1PropertyKey.accept(p, getT2PropertyKey.apply(c));
}
}
}
} catch (Exception e) {
logger.error( ExceptionUtils.getStackTrace(e));
}
} /**
* @description:关联到主表的基本类型属性去 一对一
* @param: t1 主表
* @param: t2 关联表
* @param: t1JoinKey 主表的关联key
* @param: t2JoinKey 关联表的关联key
* @param: t1Filter 表一过滤 可为空
* @param: t2Filter 表二过滤 可为空
* @param: getT2PropertyKey 从t2获取某一个值
* @param: toT1PropertyKey 把t2获取到的值设置到 t1指定的属性
* @return
* @author: Binz
* @time:2019-09-29 09:44
* <pre>
* 例如:
* joinToPropertyByFilter(users, persons, User::getPersonId, Person::getId, e -> {
return e.getId() != null && e.getId() > 3;
},null, Person::getRealName, User::setRealName);
* </pre>
*/
public static <P,C,JR,SR> void joinToPropertyByFilter(Collection<P> t1, Collection<C> t2,Function<P, JR> t1JoinKey ,Function<C,JR> t2JoinKey,Predicate<P> t1Filter,Predicate<C> t2Filter,Function<C, SR> getT2PropertyKey ,BiConsumer<P,SR> toT1PropertyKey) {
try {
Map<Object,List<P>> m1 = new HashMap<>(t1.size());
Object t1KeyValue;
for (P p : t1) {
if(t1Filter == null || t1Filter.test(p)) {
t1KeyValue = t1JoinKey.apply(p);
m1.putIfAbsent(t1KeyValue, new ArrayList<>());
m1.get(t1KeyValue).add(p);
}
}
Object t2JoinKeyValue;
List<P> ps;
for (C c : t2) {
if(t2Filter == null || t2Filter.test(c)) {
t2JoinKeyValue = t2JoinKey.apply(c);
ps = m1.get(t2JoinKeyValue);
if(ps != null) {
for (P p : ps) {
toT1PropertyKey.accept(p, getT2PropertyKey.apply(c));
}
}
}
}
} catch (Exception e) {
logger.error( ExceptionUtils.getStackTrace(e));
}
} /**
* @description:关联到主表的基本类型属性去 一对一
* @param: t1 主表
* @param: t2 关联表
* @param: t1JoinKey 主表的关联key
* @param: t2JoinKey 关联表的关联key
* @param: getT2PropertyKey 从t2获取某一个值
* @param: toT1PropertyKey 把t2获取到的值设置到 t1指定的属性
* @return
* @author: Binz
* @time:2019-09-29 09:44
* <pre>
* 例如:
* joinToPropertys(users, persons, User::getPersonId, Person::getId, (user,person)->{
* user.setRealName("乱设置的"+person.getId());
* user.setAge(person.getAge());
* });
* </pre>
*/
public static <P,C,JR,SR> void joinToPropertys(Collection<P> t1, Collection<C> t2,Function<P, JR> t1JoinKey ,Function<C,JR> t2JoinKey,BiConsumer<P,C> toT1Propertys) {
try {
Map<Object,List<P>> m1 = new HashMap<>(t1.size());
Object t1KeyValue;
for (P p : t1) {
t1KeyValue = t1JoinKey.apply(p);
m1.putIfAbsent(t1KeyValue, new ArrayList<>());
m1.get(t1KeyValue).add(p);
}
Object t2JoinKeyValue;
List<P> ps;
for (C c : t2) {
t2JoinKeyValue = t2JoinKey.apply(c);
ps = m1.get(t2JoinKeyValue);
if(ps != null) {
for (P p : ps) {
toT1Propertys.accept(p, c);
}
}
}
} catch (Exception e) {
logger.error( ExceptionUtils.getStackTrace(e));
}
} /**
* @description:关联到主表的基本类型属性去 一对一
* @param: t1 主表
* @param: t2 关联表
* @param: t1JoinKey 主表的关联key
* @param: t2JoinKey 关联表的关联key
* @param: getT2PropertyKey 从t2获取某一个值
* @param: toT1PropertyKey 把t2获取到的值设置到 t1指定的属性
* @return
* @author: Binz
* @time:2019-09-29 09:44
* <pre>
* 例如:
* joinToPropertysByFilter(users, persons, User::getPersonId, Person::getId , e -> {
return e.getId() != null && e.getId() > 3;
}, (t1,t2)->{
t1.setRealName("有过滤的乱设置的"+t2.getId());
t2.setAge(1);
});
* </pre>
*/
public static <P,C,JR,SR> void joinToPropertysByFilter(Collection<P> t1, Collection<C> t2,Function<P, JR> t1JoinKey ,Function<C,JR> t2JoinKey , Predicate<P> t1Filter,BiConsumer<P,C> toT1Propertys) {
try {
Map<Object,List<P>> m1 = new HashMap<>(t1.size());
Object t1KeyValue;
for (P p : t1) {
if(t1Filter.test(p)) {
t1KeyValue = t1JoinKey.apply(p);
m1.putIfAbsent(t1KeyValue, new ArrayList<>());
m1.get(t1KeyValue).add(p);
}
}
Object t2JoinKeyValue;
List<P> ps;
for (C c : t2) {
t2JoinKeyValue = t2JoinKey.apply(c);
ps = m1.get(t2JoinKeyValue);
if(ps != null) {
for (P p : ps) {
toT1Propertys.accept(p, c);
}
}
}
} catch (Exception e) {
logger.error( ExceptionUtils.getStackTrace(e));
}
} /**
* 通用递归,使用示例
* <br/>List<DepartmentTreeVo> list = new ArrayList<>();
* <br/>Java8Util.recursion(departmentTree, DepartmentTreeVo::getChildren, t -> {
* <br/> list.add(t);
* <br/>});
* @param ts
* @param childsFn
* @param then
*/
public static <T> void recursion(List<T> ts, Function<T, List<T>> childsFn , Consumer<T> then) {
for(T t : ts) {
then.accept(t);
}
for(T t : ts) {
List<T> childs = childsFn.apply(t);
if(ObjectUtil.isNotEmpty(childs)) {
recursion(childs, childsFn, then);
}
}
}
}

java实现的类似于sql join操作的工具类,通用递归,最低需要java8的更多相关文章

  1. Redis操作Set工具类封装,Java Redis Set命令封装

    Redis操作Set工具类封装,Java Redis Set命令封装 >>>>>>>>>>>>>>>>& ...

  2. Redis操作List工具类封装,Java Redis List命令封装

    Redis操作List工具类封装,Java Redis List命令封装 >>>>>>>>>>>>>>>> ...

  3. java中文件操作的工具类

    代码: package com.lky.pojo; import java.io.BufferedReader; import java.io.BufferedWriter; import java. ...

  4. Java操作Redis工具类

    依赖 jar 包 <dependency> <groupId>redis.clients</groupId> <artifactId>jedis< ...

  5. Java并发编程系列-(2) 线程的并发工具类

    2.线程的并发工具类 2.1 Fork-Join JDK 7中引入了fork-join框架,专门来解决计算密集型的任务.可以将一个大任务,拆分成若干个小任务,如下图所示: Fork-Join框架利用了 ...

  6. 自己封装的poi操作Excel工具类

    自己封装的poi操作Excel工具类 在上一篇文章<使用poi读写Excel>中分享了一下poi操作Excel的简单示例,这次要分享一下我封装的一个Excel操作的工具类. 该工具类主要完 ...

  7. Java并发(十五):并发工具类——信号量Semaphore

    先做总结: 1.Semaphore是什么? Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源. 把它比作是控制流量的红绿灯,比如XX马路要 ...

  8. Java并发(十四):并发工具类——CountDownLatch

    先做总结: 1.CountDownLatch 是什么? CountDownLatch 允许一个或多个线程等待其他线程(不一定是线程,某个操作)完成之后再执行. CountDownLatch的构造函数接 ...

  9. Java匹马行天下之JavaSE核心技术——工具类

    Java匹马行天之JavaSE核心技术——工具类 一.Object类 java.lang.ObjectObject类是所有类直接或间接的父类 常用的方法: toString():以字符串形式返回对象的 ...

  10. Redis操作Hash工具类封装,Redis工具类封装

    Redis操作Hash工具类封装,Redis工具类封装 >>>>>>>>>>>>>>>>>> ...

随机推荐

  1. 代码随想录算法训练营Day52 动态规划

    代码随想录算法训练营 代码随想录算法训练营Day52 动态规划| 300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组 300.最长递增子序列 题目链接:300.最长递增子序列 ...

  2. # 代码随想录算法训练营Day28 回溯算法|93.复原IP地址 78.子集 90.子集II

    代码随想录算法训练营 93.复原IP地址 题目链接:93.复原IP地址 给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式. 有效的 IP 地址 正好由四个整数(每个整数位于 0 到 ...

  3. 【python基础】基本数据类型-字符串类型

    1.初识字符串 字符串就是一系列字符.在python中,用引号括起来文本内容的都是字符串. 其语法格式为:'文本内容'或者"文本内容" 我们发现其中的引号可以是单引号,也可以是双引 ...

  4. Request类源码分析、序列化组件介绍、序列化类的基本使用、常用字段类和参数、反序列化之校验、反序列化之保存、APIVIew+序列化类+Response写的五个接口代码、序列化高级用法之source、序列化高级用法之定制字段的两种方式、多表关联反序列化保存、反序列化字段校验其他、ModelSerializer使用

    目录 一.Request类源码分析 二.序列化组件介绍 三.序列化类的基本使用 查询所有和查询单条 四.常用字段类和参数(了解) 常用字段类 字段参数(校验数据来用的) 五.反序列化之校验 六.反序列 ...

  5. CAPL 脚本基本语句

    CAPL(Communication Access Programming Language)是一种用于汽车通信网络分析和仿真的脚本语言.以下是CAPL脚本的基本语句: 1.变量声明 variable ...

  6. JavaScript如何解决单线程缺陷——webWorker

    解决JavaScript单线程问题--webWorkers 参考文档 使用 Web Workers - Web API 接口参考 | MDN (mozilla.org) MDN的介绍为: Web Wo ...

  7. 常量接口 vs 常量类 vs 枚举区别

    把常量定义在接口里与类里都能通过编译,那2者到底有什么区别呢? 那个更合理? 常量接口 public interface ConstInterfaceA { public static final S ...

  8. 【HMS Core】【In-App Purchases】应用内支付热门FAQ合集

    ​近期收到很多开发者关于应用内支付服务的相关问题,主要集中在以下几个方面,今天和大家分享一下,希望给大家的开发集成带来帮助. [问题描述1] 近期,很多开发者收到关于"全面限制HTTP类型回 ...

  9. 使用 InstructPix2Pix 对 Stable Diffusion 进行指令微调

    本文主要探讨如何使用指令微调的方法教会 Stable Diffusion 按照指令 PS 图像.这样,我们 Stable Diffusion 就能听得懂人话,并根据要求对输入图像进行相应操作,如: 将 ...

  10. 三路快排Java版(图文并茂思路分析)

    快速排序 这里我们直接开始讲相对的最优解 带随机数的三路快排 好了,中间还有很多版本的快排,但是都有一些问题导致在某种极端情况下造成耗费时间极多. 基础快排:在序列本身有序的情况下复杂度为O(n²) ...