集合循环赋值封装

集合循环赋值封装

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);

    /**
     * 取source元素中sourceF属性的值为target中元素的targetF属性赋值
     * 通过filter进行target和source中元素的匹配
     * */
    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元素");
        }

        // 标识source中的元素是否是map
        boolean mapFlag = source.stream().findFirst().get() instanceof Map;

        // target中对象的get方法名称
        String targetMName = LambdaUtils.extract(targetF).getImplMethodName();

        // targetMName方法对应的属性名称 如 getName => name
        String targetFName = PropertyNamer.methodToProperty(targetMName);

        // 获取target中对象的set方法名称
        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));

        // target中对象的set方法实例
        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);
            // 对象的get方法名称
            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不能为空");
        }
    }


    /**
     * 校验集合中是否存在null元素
     * */
    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无法进行序列化");
        }
        // 1. IDEA 调试模式下 lambda 表达式是一个代理
        if (func instanceof Proxy) {
            return new IdeaProxyLambdaMeta((Proxy) func);
        }
        // 2. 反射读取
        try {
            Method method = func.getClass().getDeclaredMethod("writeReplace");
            return new ReflectLambdaMeta((SerializedLambda) ReflectionKit.setAccessible(method).invoke(func));
        } catch (Throwable e) {
            // 3. 反射失败使用序列化的方式读取
            return new ShadowLambdaMeta(com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda.extract((Serializable) func));
        }
    }

}

你可能感兴趣的:(java)