对象属性值按长度拆分扩展一个新集合
package com.xx.xx.core.utils; import cn.hutool.core.util.ReflectUtil; import com.xx.tools.utils.BeanUtil; import com.xx.tools.utils.StringUtil; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; import tk.mybatis.mapper.weekend.reflection.ReflectionOperationException; import java.beans.Introspector; import java.io.Serializable; import java.lang.invoke.SerializedLambda; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; import java.util.regex.Pattern; import java.util.stream.Collectors; /** * 使用方式: * 第一步:指定规则:拆分字段名,拆分长度 * List<ListSplitHelper.FieldSplitRule> fields = ListUtil.of( * ListSplitHelper.of(NursingRecordMaternal::getHandlingContent, 6) * ); * 第二步:扩展集合 * List<NursingRecordMaternal> dataList = ListSplitHelper.process(list, fields, false); * * 业务场景:参考 护理文书>护理记录单>产前记录:处置或附注, 要求超出部分放到下一个单元格展示 * **/ public class ListSplitHelper { private static final Pattern GET_PATTERN = Pattern.compile("^get[A-Z].*"); private static final Pattern IS_PATTERN = Pattern.compile("^is[A-Z].*"); /** * * @Description: 扩展原集合 : 根据字段允许的最大属性值进行拆分扩展 * @param: list 原集合 * @param: ruleFields 待拆分的属性 * @param isAllCopy 是否全量拷贝 : true 全量拷贝,false 只拷贝id及规则属性 * @Return: java.util.List<T> * @Throws: * @Date: 2024/4/28 17:51 **/ public static <T> List<T> process(List<T> list, List<FieldSplitRule> ruleFields, boolean isAllCopy) { List<T> expandedList = new ArrayList<>(); for (T original : list) { //包装适配 List<FieldWrapper> fieldWrapperList = wrapper(ruleFields, original); //新集合长度 Integer size = fieldWrapperList.stream().map(field -> field.getArr().length).max(Integer::compare).orElse(0); AtomicInteger index = new AtomicInteger(0); //扩展新集合 for (int i = 0; i < size; i++) { T newObj = (T) ReflectUtil.newInstance(original.getClass()); if(isAllCopy) { BeanUtil.copyProperties(original, newObj); } else { if(index.get() == 0) { BeanUtil.copyProperties(original, newObj); } else { ReflectUtil.setFieldValue(newObj, "id", ReflectUtil.getFieldValue(original, "id")); } } for (FieldWrapper wrapper : fieldWrapperList) { String[] arr = wrapper.getArr(); if(arr.length > i) { ReflectUtil.setFieldValue(newObj, wrapper.getFieldName(), arr[i]); } } expandedList.add(newObj); index.incrementAndGet(); } } return expandedList; } public static <T, B> FieldSplitRule of(MyFn<T, B> fieldFunction, int ruleCutLength) { String fieldName = fnToFieldName(fieldFunction); return new FieldSplitRule(fieldName, ruleCutLength); } private static <T> List<FieldWrapper> wrapper(List<FieldSplitRule> ruleFields, T object) { List<FieldWrapper> fieldWrapperList = ruleFields.stream() .map(rule -> new FieldWrapper(rule, object)) .collect(Collectors.toList()); return fieldWrapperList; } private static String fnToFieldName(MyFn<?, ?> fn) { try { Method method = fn.getClass().getDeclaredMethod("writeReplace"); method.setAccessible(Boolean.TRUE); SerializedLambda serializedLambda = (SerializedLambda)method.invoke(fn); String getter = serializedLambda.getImplMethodName(); if (GET_PATTERN.matcher(getter).matches()) { getter = getter.substring(3); } else if (IS_PATTERN.matcher(getter).matches()) { getter = getter.substring(2); } return Introspector.decapitalize(getter); } catch (ReflectiveOperationException var4) { throw new ReflectionOperationException(var4); } } @AllArgsConstructor @NoArgsConstructor @Accessors(chain = true) @Data public static class FieldSplitRule { /** 分割-属性名 */ private String ruleFieldName; /** 分割-长度 */ private int ruleCutLength; } @Accessors(chain = true) @Data private static class FieldWrapper<T> { /** 对象 */ private T object; private FieldSplitRule fieldSplitRule; /** 分割后的数组 */ private String[] arr; private FieldWrapper() { } private FieldWrapper(FieldSplitRule fieldSplitRule, T object) { this.fieldSplitRule = fieldSplitRule; this.object = object; this.arr = cutStrValue(object); } private String getFieldName() { return fieldSplitRule.getRuleFieldName(); } /** * @return 属性值 **/ private Object getFieldValue(T object) { return ReflectUtil.getFieldValue(object, fieldSplitRule.getRuleFieldName()); } /** * 分割字段内容 * @return 分割后的内容列表 **/ private String[] cutStrValue(T object) { Object fieldValue = getFieldValue(object); if(fieldValue == null) { return new String[0]; } if(!(fieldValue instanceof String)) { throw new RuntimeException("类型不是字符串"); } String[] arr = StringUtil.cut(String.valueOf(fieldValue), fieldSplitRule.getRuleCutLength()); setArr(arr); return arr; } } public interface MyFn<T, R> extends Function<T, R>, Serializable { } }