Bean、List工具

本文介绍了一个Java工具类库,包含Bean操作和List操作。BeanUtil类允许通过lambda表达式获取Bean的字段名和类名,而classListUtil类提供了检查List中是否存在重复数据的方法。这些工具类提高了代码的可读性和便捷性。
摘要由CSDN通过智能技术生成

一、Bean操作类

使用表达式,获取Bean中字段名,不用使用字符串或者常量方式

1.1、定义两个接口

@FunctionalInterface
public interface IGetter<T> extends Serializable {
    Object get(T source);
}

 @FunctionalInterface
public interface ISetter<T, U> extends Serializable {
    void set(T t, U u);
}

1.2、定义Bean操作类

/**
 * Bean操作类
 * (1)lambda方式获取字段名
 * (2)lambda方式获取类
 */
public class BeanUtil {

    private final static Logger log = LoggerFactory.getLogger(BeanUtil.class);

    /**
     * 通过getter的方法引用获取对象类
     *
     * @param fn
     * @param <T>
     * @return
     */
    public static <T> Class<T> getClassName(IGetter<T> fn) {
        try {
            SerializedLambda lambda = getSerializedLambda(fn);
            String implClass = lambda.getImplClass();
            return (Class<T>) Class.forName(implClass.replace("/","."));
        } catch (Exception e) {
            log.error("通过getter的方法引用获取对象类失败", e);
            return null;
        }
    }


    /**
     * 通过getter的方法引用获取字段名
     */
    public static <T> String getFieldName(IGetter<T> fn) {
        try {
            SerializedLambda lambda = getSerializedLambda(fn);
            String methodName = lambda.getImplMethodName();
            String prefix = null;
            if (methodName.startsWith("get")) {
                prefix = "get";
            } else if (methodName.startsWith("is")) {
                prefix = "is";
            }
            if (prefix == null) {
                log.error("无效的getter方法: " + methodName);
            }
            return toLowerCaseFirstOne(methodName.replace(prefix, ""));
        } catch (Exception e) {
            log.error("通过getter的方法引用获取字段名失败", e);
            return null;
        }
    }

    /**
     * 通过setter的方法引用获取字段名
     *
     * @throws Exception
     */
    public static <T, U> String getFieldName(ISetter<T, U> fn) {
        try {
            SerializedLambda lambda = getSerializedLambda(fn);
            String methodName = lambda.getImplMethodName();
            if (!methodName.startsWith("set")) {
                log.error("无效的setter方法:" + methodName);
            }
            return toLowerCaseFirstOne(methodName.replace("set", ""));
        } catch (Exception e) {
            log.error("通过setter的方法引用获取字段名失败", e);
            return null;
        }

    }

    /**
     * 获取 lambda
     *
     * @param fn
     * @return
     * @throws Exception
     */
    private static SerializedLambda getSerializedLambda(Serializable fn) throws Exception {
        Method method = fn.getClass().getDeclaredMethod("writeReplace");
        method.setAccessible(Boolean.TRUE);
        SerializedLambda lambda = (SerializedLambda) method.invoke(fn);
        return lambda;
    }

    /**
     * 字符串首字母转小写
     */
    private static String toLowerCaseFirstOne(String field) {
        if (Character.isLowerCase(field.charAt(0)))
            return field;
        else {
            char firstOne = Character.toLowerCase(field.charAt(0));
            String other = field.substring(1);
            return new StringBuilder().append(firstOne).append(other).toString();
        }
    } 
}

1.3、使用表达式获取字段名

String nameField=BeanUtil.getFieldName(User::getName);

二、List操作类

记录一些list操作方法:包括重复校验list(根据传入字段)获取重复数据项

public class ListUtil {

    /**
     * 校验集合是否存在重复数据
     *
     * @param list 需要校验的集合
     * @param fns  lambda表达式
     * @param <E>
     * @return true 重复  false 不重复
     */
    public static <E> boolean hasRepeatData(List<E> list, IGetter<E>... fns) {
        if (CollectionUtils.isEmpty(list) || CollectionUtils.isEmpty(Arrays.asList(fns))) return false;
        List<String> fieldNames = new ArrayList<>();
        for (IGetter<E> fn : fns) {
            fieldNames.add(BeanUtil.getFieldName(fn));
        }
        return hasRepeatData(list, fieldNames);
         
    }

    /**
     * 校验集合是否存在重复数据
     *
     * @param list       需要校验的集合
     * @param fieldNames 字段名集合
     * @param <E>
     * @return true 重复  false 不重复
     */
    public static <E> boolean hasRepeatData(List<E> list, List<String> fieldNames) {
        if (CollectionUtils.isEmpty(list) || CollectionUtils.isEmpty(Arrays.asList(fieldNames))) return false;
        Map<String, Long> map = list.stream().collect(Collectors.groupingBy(p -> {
            String key = "";
            for (String fieldName : fieldNames) {
                key += String.valueOf(ReflectionUtils.getFieldValue(p, fieldName));
            }
            return key;
        }, Collectors.counting()));
        for (Map.Entry<String, Long> entry : map.entrySet()) {
            if (entry.getValue() > 1L) return true;
        }
        return false;
    }

    /**
     * 获取重复数据
     *
     * @param list 获取重复数据的集合
     * @param fns  lambda表达式
     * @param <E>
     * @return
     */
    public static <E> E getRepeatData(List<E> list, IGetter<E>... fns) {
        if (CollectionUtils.isEmpty(list) || CollectionUtils.isEmpty(Arrays.asList(fns))) return null;
        List<String> fieldNames = new ArrayList<>();
        for (IGetter<E> fn : fns) {
            fieldNames.add(BeanUtil.getFieldName(fn));
        }
        return getRepeatData(list, fieldNames);
    }

    /**
     * 获取重复数据
     *
     * @param list       获取重复数据的集合
     * @param fieldNames 字段名称集合
     * @param <E>
     * @return
     */
    public static <E> E getRepeatData(List<E> list, List<String> fieldNames) {
        if (CollectionUtils.isEmpty(list) || CollectionUtils.isEmpty(Arrays.asList(fieldNames))) return null;
        Map<String, List<E>> maps = list.stream().collect(Collectors.groupingBy(p -> {
            String key = "";
            for (String fieldName : fieldNames) {
                key += String.valueOf(ReflectionUtils.getFieldValue(p, fieldName));
            }
            return key;
        }));
        for (Map.Entry<String, List<E>> entry : maps.entrySet()) {
            if (!CollectionUtils.isEmpty(entry.getValue()) && entry.getValue().size() > 1) {
                return entry.getValue().get(0);
            }
        }
        return null;
    } 
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笑谈子云亭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值