经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Java » 查看文章
java实现的类似于sql join操作的工具类,通用递归,最低需要java8
来源:cnblogs  作者:Binz  时间:2023/8/29 10:17:00  对本文有异议

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

  1. import java.util.ArrayList;
  2. import java.util.Collection;
  3. import java.util.HashMap;
  4. import java.util.HashSet;
  5. import java.util.List;
  6. import java.util.Map;
  7. import java.util.Set;
  8. import java.util.function.BiConsumer;
  9. import java.util.function.Consumer;
  10. import java.util.function.Function;
  11. import java.util.function.Predicate;
  12. import org.apache.commons.lang3.exception.ExceptionUtils;
  13. import org.slf4j.Logger;
  14. import org.slf4j.LoggerFactory;
  15. import cn.hutool.core.util.ObjectUtil;
  16. /**
  17. * @description:数据列表关联,类似于sql中的join
  18. * @author: Binz
  19. * @time:2019-09-29 09:40
  20. */
  21. public class Java8Util {
  22. private static final Logger logger = LoggerFactory.getLogger(Java8Util.class);
  23. /**
  24. * @description:关联到主表的基本类型属性去 一对多
  25. * @param: t1 主表
  26. * @param: t2 关联表
  27. * @param: t1JoinKey 主表的关联key
  28. * @param: t2JoinKey 关联表的关联key
  29. * @param: toT1ListProperty 需要赋值到t1的List属性
  30. * @return
  31. * @author: Binz
  32. * @time:2019-09-29 09:44
  33. * <pre>
  34. * 例如:Java8Util.joinToList(users, roles, User::getId, Role::getUserId, User::setRoles);
  35. * </pre>
  36. */
  37. 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) {
  38. try {
  39. Map<Object,List<C>> valueMap = new HashMap<>();
  40. JR t2JoinValue;
  41. for (C c : t2) {
  42. t2JoinValue = t2JoinKey.apply(c);
  43. valueMap.putIfAbsent(t2JoinValue, new ArrayList<>());
  44. valueMap.get(t2JoinValue).add(c);
  45. }
  46. JR t1JoinValue;
  47. List<C> list;
  48. for (P p : t1) {
  49. t1JoinValue = t1JoinKey.apply(p);
  50. list = valueMap.get(t1JoinValue);
  51. toT1ListProperty.accept(p, list);
  52. }
  53. } catch (Exception e) {
  54. logger.error( ExceptionUtils.getStackTrace(e));
  55. }
  56. }
  57. /**
  58. * @description:关联到主表的基本类型属性去 一对多
  59. * @param: t1 主表
  60. * @param: t2 关联表
  61. * @param: t1JoinKey 主表的关联key
  62. * @param: t2JoinKey 关联表的关联key
  63. * @param: getT2PropertyKey 获取t2指定属性
  64. * @param: toT1ListProperty 需要赋值到t1的List属性
  65. * @return
  66. * @author: Binz
  67. * @time:2019-09-29 09:44
  68. * <pre>
  69. * 例如:Java8Util.joinToListProperty(users, roles, User::getId, Role::getUserId, Role::Id ,Role::getName , User::setRoleNames);
  70. * </pre>
  71. */
  72. 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) {
  73. try {
  74. Map<Object,List<SR>> valueMap = new HashMap<>();
  75. JR t2JoinValue;
  76. for (C c : t2) {
  77. t2JoinValue = t2JoinKey.apply(c);
  78. valueMap.putIfAbsent(t2JoinValue, new ArrayList<>());
  79. valueMap.get(t2JoinValue).add(getT2PropertyKey.apply(c));
  80. }
  81. JR t1JoinValue;
  82. List<SR> list;
  83. for (P p : t1) {
  84. t1JoinValue = t1JoinKey.apply(p);
  85. list = valueMap.get(t1JoinValue);
  86. toT1PropertyKey.accept(p,list);
  87. }
  88. } catch (Exception e) {
  89. logger.error( ExceptionUtils.getStackTrace(e));
  90. }
  91. }
  92. 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) {
  93. try {
  94. Map<Object,Set<SR>> valueMap = new HashMap<>();
  95. JR t2JoinValue;
  96. for (C c : t2) {
  97. t2JoinValue = t2JoinKey.apply(c);
  98. valueMap.putIfAbsent(t2JoinValue, new HashSet<>());
  99. valueMap.get(t2JoinValue).add(getT2PropertyKey.apply(c));
  100. }
  101. JR t1JoinValue;
  102. Set<SR> list;
  103. for (P p : t1) {
  104. t1JoinValue = t1JoinKey.apply(p);
  105. list = valueMap.get(t1JoinValue);
  106. toT1PropertyKey.accept(p,list);
  107. }
  108. } catch (Exception e) {
  109. logger.error( ExceptionUtils.getStackTrace(e));
  110. }
  111. }
  112. /**
  113. * @description:关联到主表的基本类型属性去 一对一
  114. * @param: t1 主表
  115. * @param: t2 关联表
  116. * @param: t1JoinKey 主表的关联key
  117. * @param: t2JoinKey 关联表的关联key
  118. * @param: toT1PropertyKey 把t2 设置到 t1指定的属性
  119. * @return
  120. * @author: Binz
  121. * @time:2019-09-29 09:44
  122. * <pre>
  123. * 例如:joinToEntity(users, accountss, User::getId, Account::getUserId, User::setAccount);
  124. * </pre>
  125. */
  126. 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) {
  127. try {
  128. Map<Object,List<P>> m1 = new HashMap<>(t1.size());
  129. Object t1KeyValue;
  130. for (P p : t1) {
  131. t1KeyValue = t1JoinKey.apply(p);
  132. m1.putIfAbsent(t1KeyValue, new ArrayList<>());
  133. m1.get(t1KeyValue).add(p);
  134. }
  135. Object t2JoinKeyValue;
  136. List<P> ps;
  137. for (C c : t2) {
  138. t2JoinKeyValue = t2JoinKey.apply(c);
  139. ps = m1.get(t2JoinKeyValue);
  140. if(ps != null) {
  141. for (P p : ps) {
  142. toT1EntityProperty.accept(p, c);
  143. }
  144. }
  145. }
  146. } catch (Exception e) {
  147. logger.error( ExceptionUtils.getStackTrace(e));
  148. }
  149. }
  150. /**
  151. * @description:关联到主表的基本类型属性去 一对一
  152. * @param: t1 主表
  153. * @param: t2 关联表
  154. * @param: t1JoinKey 主表的关联key
  155. * @param: t2JoinKey 关联表的关联key
  156. * @param: getT2PropertyKey 从t2获取某一个值
  157. * @param: toT1PropertyKey 把t2获取到的值设置到 t1指定的属性
  158. * @return
  159. * @author: Binz
  160. * @time:2019-09-29 09:44
  161. * <pre>
  162. * 例如:joinToEntity(users, accountss, User::getId, Account::getUserId, User::setAccount);
  163. * </pre>
  164. */
  165. 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) {
  166. try {
  167. Map<Object,List<P>> m1 = new HashMap<>(t1.size());
  168. Object t1KeyValue;
  169. for (P p : t1) {
  170. if(t1Filter == null || t1Filter.test(p)) {
  171. t1KeyValue = t1JoinKey.apply(p);
  172. m1.putIfAbsent(t1KeyValue, new ArrayList<>());
  173. m1.get(t1KeyValue).add(p);
  174. }
  175. }
  176. Object t2JoinKeyValue;
  177. List<P> ps;
  178. for (C c : t2) {
  179. if(t2Filter == null || t2Filter.test(c)) {
  180. t2JoinKeyValue = t2JoinKey.apply(c);
  181. ps = m1.get(t2JoinKeyValue);
  182. if(ps != null) {
  183. for (P p : ps) {
  184. toT1EntityProperty.accept(p, c);
  185. }
  186. }
  187. }
  188. }
  189. } catch (Exception e) {
  190. logger.error( ExceptionUtils.getStackTrace(e));
  191. }
  192. }
  193. /**
  194. * @description:关联到主表的基本类型属性去 一对一
  195. * @param: t1 主表
  196. * @param: t2 关联表
  197. * @param: t1JoinKey 主表的关联key
  198. * @param: t2JoinKey 关联表的关联key
  199. * @param: getT2PropertyKey 从t2获取某一个值
  200. * @param: toT1PropertyKey 把t2获取到的值设置到 t1指定的属性
  201. * @return
  202. * @author: Binz
  203. * @time:2019-09-29 09:44
  204. * <pre>
  205. * 例如:joinToProperty(users, persons, User::getId, Person::getUserId, Person::getRealName User::setRealName);
  206. * </pre>
  207. */
  208. 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) {
  209. try {
  210. Map<Object,List<P>> m1 = new HashMap<>(t1.size());
  211. Object t1KeyValue;
  212. for (P p : t1) {
  213. t1KeyValue = t1JoinKey.apply(p);
  214. m1.putIfAbsent(t1KeyValue, new ArrayList<>());
  215. m1.get(t1KeyValue).add(p);
  216. }
  217. Object t2JoinKeyValue;
  218. List<P> ps;
  219. for (C c : t2) {
  220. t2JoinKeyValue = t2JoinKey.apply(c);
  221. ps = m1.get(t2JoinKeyValue);
  222. if(ps != null) {
  223. for (P p : ps) {
  224. toT1PropertyKey.accept(p, getT2PropertyKey.apply(c));
  225. }
  226. }
  227. }
  228. } catch (Exception e) {
  229. logger.error( ExceptionUtils.getStackTrace(e));
  230. }
  231. }
  232. /**
  233. * @description:关联到主表的基本类型属性去 一对一
  234. * @param: t1 主表
  235. * @param: t2 关联表
  236. * @param: t1JoinKey 主表的关联key
  237. * @param: t2JoinKey 关联表的关联key
  238. * @param: t1Filter 表一过滤 可为空
  239. * @param: t2Filter 表二过滤 可为空
  240. * @param: getT2PropertyKey 从t2获取某一个值
  241. * @param: toT1PropertyKey 把t2获取到的值设置到 t1指定的属性
  242. * @return
  243. * @author: Binz
  244. * @time:2019-09-29 09:44
  245. * <pre>
  246. * 例如:
  247. * joinToPropertyByFilter(users, persons, User::getPersonId, Person::getId, e -> {
  248. return e.getId() != null && e.getId() > 3;
  249. },null, Person::getRealName, User::setRealName);
  250. * </pre>
  251. */
  252. 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) {
  253. try {
  254. Map<Object,List<P>> m1 = new HashMap<>(t1.size());
  255. Object t1KeyValue;
  256. for (P p : t1) {
  257. if(t1Filter == null || t1Filter.test(p)) {
  258. t1KeyValue = t1JoinKey.apply(p);
  259. m1.putIfAbsent(t1KeyValue, new ArrayList<>());
  260. m1.get(t1KeyValue).add(p);
  261. }
  262. }
  263. Object t2JoinKeyValue;
  264. List<P> ps;
  265. for (C c : t2) {
  266. if(t2Filter == null || t2Filter.test(c)) {
  267. t2JoinKeyValue = t2JoinKey.apply(c);
  268. ps = m1.get(t2JoinKeyValue);
  269. if(ps != null) {
  270. for (P p : ps) {
  271. toT1PropertyKey.accept(p, getT2PropertyKey.apply(c));
  272. }
  273. }
  274. }
  275. }
  276. } catch (Exception e) {
  277. logger.error( ExceptionUtils.getStackTrace(e));
  278. }
  279. }
  280. /**
  281. * @description:关联到主表的基本类型属性去 一对一
  282. * @param: t1 主表
  283. * @param: t2 关联表
  284. * @param: t1JoinKey 主表的关联key
  285. * @param: t2JoinKey 关联表的关联key
  286. * @param: getT2PropertyKey 从t2获取某一个值
  287. * @param: toT1PropertyKey 把t2获取到的值设置到 t1指定的属性
  288. * @return
  289. * @author: Binz
  290. * @time:2019-09-29 09:44
  291. * <pre>
  292. * 例如:
  293. * joinToPropertys(users, persons, User::getPersonId, Person::getId, (user,person)->{
  294. * user.setRealName("乱设置的"+person.getId());
  295. * user.setAge(person.getAge());
  296. * });
  297. * </pre>
  298. */
  299. 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) {
  300. try {
  301. Map<Object,List<P>> m1 = new HashMap<>(t1.size());
  302. Object t1KeyValue;
  303. for (P p : t1) {
  304. t1KeyValue = t1JoinKey.apply(p);
  305. m1.putIfAbsent(t1KeyValue, new ArrayList<>());
  306. m1.get(t1KeyValue).add(p);
  307. }
  308. Object t2JoinKeyValue;
  309. List<P> ps;
  310. for (C c : t2) {
  311. t2JoinKeyValue = t2JoinKey.apply(c);
  312. ps = m1.get(t2JoinKeyValue);
  313. if(ps != null) {
  314. for (P p : ps) {
  315. toT1Propertys.accept(p, c);
  316. }
  317. }
  318. }
  319. } catch (Exception e) {
  320. logger.error( ExceptionUtils.getStackTrace(e));
  321. }
  322. }
  323. /**
  324. * @description:关联到主表的基本类型属性去 一对一
  325. * @param: t1 主表
  326. * @param: t2 关联表
  327. * @param: t1JoinKey 主表的关联key
  328. * @param: t2JoinKey 关联表的关联key
  329. * @param: getT2PropertyKey 从t2获取某一个值
  330. * @param: toT1PropertyKey 把t2获取到的值设置到 t1指定的属性
  331. * @return
  332. * @author: Binz
  333. * @time:2019-09-29 09:44
  334. * <pre>
  335. * 例如:
  336. * joinToPropertysByFilter(users, persons, User::getPersonId, Person::getId , e -> {
  337. return e.getId() != null && e.getId() > 3;
  338. }, (t1,t2)->{
  339. t1.setRealName("有过滤的乱设置的"+t2.getId());
  340. t2.setAge(1);
  341. });
  342. * </pre>
  343. */
  344. 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) {
  345. try {
  346. Map<Object,List<P>> m1 = new HashMap<>(t1.size());
  347. Object t1KeyValue;
  348. for (P p : t1) {
  349. if(t1Filter.test(p)) {
  350. t1KeyValue = t1JoinKey.apply(p);
  351. m1.putIfAbsent(t1KeyValue, new ArrayList<>());
  352. m1.get(t1KeyValue).add(p);
  353. }
  354. }
  355. Object t2JoinKeyValue;
  356. List<P> ps;
  357. for (C c : t2) {
  358. t2JoinKeyValue = t2JoinKey.apply(c);
  359. ps = m1.get(t2JoinKeyValue);
  360. if(ps != null) {
  361. for (P p : ps) {
  362. toT1Propertys.accept(p, c);
  363. }
  364. }
  365. }
  366. } catch (Exception e) {
  367. logger.error( ExceptionUtils.getStackTrace(e));
  368. }
  369. }
  370. /**
  371. * 通用递归,使用示例
  372. * <br/>List<DepartmentTreeVo> list = new ArrayList<>();
  373. * <br/>Java8Util.recursion(departmentTree, DepartmentTreeVo::getChildren, t -> {
  374. * <br/> list.add(t);
  375. * <br/>});
  376. * @param ts
  377. * @param childsFn
  378. * @param then
  379. */
  380. public static <T> void recursion(List<T> ts, Function<T, List<T>> childsFn , Consumer<T> then) {
  381. for(T t : ts) {
  382. then.accept(t);
  383. }
  384. for(T t : ts) {
  385. List<T> childs = childsFn.apply(t);
  386. if(ObjectUtil.isNotEmpty(childs)) {
  387. recursion(childs, childsFn, then);
  388. }
  389. }
  390. }
  391. }

 

原文链接:https://www.cnblogs.com/binz/p/17664073.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号