集合循环赋值封装
CollectionUtils
package com.test.common.utils;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.test.common.function.Filter;
import com.test.common.function.Function;
import org.apache.ibatis.reflection.property.PropertyNamer;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public abstract class CollectionUtils {
private static final Map<String,Method> METHOD_CACHE = new ConcurrentHashMap<>(256);
private static final Map<Function,String> FUNCTION_CACHE = new ConcurrentHashMap<>(256);
public static <T,E> void loopSetVal(Collection<T> target, Collection<E> source, Filter<? super T,? super E> filter,
Function<? super T, ?> targetF, Function<? super E, ?> sourceF) {
Assert.isTrue(CollUtil.isNotEmpty(target), "target不能为空");
Assert.isTrue(CollUtil.isNotEmpty(source), "source不能为空");
Assert.isTrue(ObjectUtil.isNotNull(filter) && ObjectUtil.isNotNull(target) && ObjectUtil.isNotNull(sourceF),
"filter、targetF、sourceF不能为空");
if(checkExistsNullValue(target) || checkExistsNullValue(source)) {
throw new IllegalArgumentException("target或source中存在null元素");
}
boolean mapFlag = source.stream().findFirst().get() instanceof Map;
String targetMName = LambdaUtils.extract(targetF).getImplMethodName();
String targetFName = PropertyNamer.methodToProperty(targetMName);
String setMName = "set" + targetFName.substring(0,1).toUpperCase(Locale.ROOT) + targetFName.substring(1);
Class<?> targetCla = target.stream().findFirst().get().getClass();
String getMethodName = "get" + targetFName.substring(0,1).toUpperCase(Locale.ROOT) + targetFName.substring(1);
Method getMethod = METHOD_CACHE.computeIfAbsent(StringUtils.generateKeyNullSafe(targetCla.getName(),getMethodName),(k)-> ReflectionUtils.findMethod(targetCla, getMethodName));
Method targetMethod = METHOD_CACHE.computeIfAbsent(StringUtils.generateKeyNullSafe(targetCla.getName(), setMName),(k)-> ReflectionUtils.findMethod(targetCla, setMName, getMethod.getReturnType()));
Assert.isTrue(ObjectUtil.isNotNull(targetMethod),String.format("类:[%s]中不存在方法:[%s]",targetCla.getName(),setMName));
ValueGetter<E> valueGetter = new EntityValueGetter();
if(mapFlag) {
valueGetter = new MapValueGetter();
}
for (T t : target) {
for (E e : source) {
if(filter.test(t,e)) {
Object value = valueGetter.getValue(sourceF, e);
ReflectionUtils.invokeMethod(targetMethod, t, value);
break;
}
}
}
FUNCTION_CACHE.remove(sourceF);
}
private static final class EntityValueGetter<T> implements ValueGetter<T> {
@Override
public Object getValue(Function<? super T, ?> func, T t) {
this.checkNotNull(func);
String methodName = FUNCTION_CACHE.computeIfAbsent(func, (k)->LambdaUtils.extract(func).getImplMethodName());
Assert.isTrue(StrUtil.isNotEmpty(methodName), "根据lambda表达式获取方法名称失败");
Class<?> clazz = t.getClass();
Method method = METHOD_CACHE.computeIfAbsent(StringUtils.generateKeyNullSafe(clazz.getName(), methodName),(k)->ReflectionUtils.findMethod(clazz, methodName));
Assert.isTrue(ObjectUtil.isNotNull(method), String.format("类:[%s]中不存在方法:[%s]",clazz.getName(),methodName));
return ReflectionUtils.invokeMethod(method, t);
}
}
private static final class MapValueGetter<T extends Map> implements ValueGetter<T> {
@Override
public Object getValue(Function<? super T, ?> func, T t) {
Assert.isTrue(t instanceof Map, "只支持对map类型操作");
this.checkNotNull(func);
return func.apply(t);
}
}
private interface ValueGetter<T> {
Object getValue(Function<? super T,?> func, T t);
default void checkNotNull(Function<? super T,?> func) {
Assert.isTrue(ObjectUtil.isNotNull(func), "func不能为空");
}
}
public static boolean checkExistsNullValue(Collection<?> collection) {
return collection.stream().anyMatch(Objects::isNull);
}
}
Filter
package com.test.common.function;
@FunctionalInterface
public interface Filter<T, R> {
boolean test(T t, R r);
}
Function
package com.test.common.function;
import java.io.Serializable;
@FunctionalInterface
public interface Function<T, R> extends java.util.function.Function<T, R>, Serializable {
R apply(T t);
}
LambdaUtils
package com.test.common.utils;
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import com.baomidou.mybatisplus.core.toolkit.support.*;
import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.function.Function;
public abstract class LambdaUtils {
public static LambdaMeta extract(Function func) {
if(!(func instanceof Serializable)) {
throw new IllegalArgumentException("func无法进行序列化");
}
if (func instanceof Proxy) {
return new IdeaProxyLambdaMeta((Proxy) func);
}
try {
Method method = func.getClass().getDeclaredMethod("writeReplace");
return new ReflectLambdaMeta((SerializedLambda) ReflectionKit.setAccessible(method).invoke(func));
} catch (Throwable e) {
return new ShadowLambdaMeta(com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda.extract((Serializable) func));
}
}
}