• 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;
        } 
    }
    
  • 相关阅读:
    酒店客房管理系统设计与实现(论文+源码)_kaic
    快速排序及其拓展应用
    sip服务器 国标gb28181
    无涯教程-JavaScript - SUMXMY2函数
    来认识并了解一下:不一样的杨氏矩阵
    用DIV+CSS技术制作一个简单的网页 我的家乡主题
    DevExpress WinForms TreeMap组件,用嵌套矩形可视化复杂分层数据
    node、npm、nvm相关概念区别
    图像处理中底层、高层特征、上下文信息理解
    【linux】ubunda repo是什么
  • 原文地址:https://blog.csdn.net/lj15559275886/article/details/127101578