• Bean、List工具


    一、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 
         * @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 
         * @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 
         * @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 
         * @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 
         * @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;
        } 
    }
    
  • 相关阅读:
    蜂蜡/聚苯乙烯大孔树脂微球/硫酸盐修饰聚苯乙烯微球/草莓状银/聚苯乙烯-丙烯腈复合微球的研究
    软件测试找bug小技巧总结,从初级跨入中级测试......
    Apache APISIX 2.12.0 版本发布, 新功能更适配新一年
    Android之 Canvas绘制
    每日leetcode[二进制求和]
    【css】css奇数、偶数、指定数选择器:
    【题解】CF1485C Floor and Mod(二分答案,整除分块)
    java面试(网络)
    瑞吉外卖项目:新增菜品与菜品分页查询
    Python 自动化Web测试
  • 原文地址:https://blog.csdn.net/lj15559275886/article/details/127101578