Java的驼峰与下划线的属性对象互相转换
程序员文章站
2022-05-13 10:40:16
...
import com.xxxx.util.constant.PropertyNameStyle; import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.util.ClassUtils; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.function.Function; @Slf4j public class GenericPropertyConverter { public static final char UNDERLINE_CHAR = '_'; public static <T> T convertObject(Object originObj, PropertyNameStyle originStyle, Class<T> targetClass) { return baseConvertObject(originObj, originStyle, targetClass, null, null); } public static <T, F> List<T> convertObject(List<F> originLst, PropertyNameStyle originStyle, Class<T> targetClass) { if (Objects.isNull(originLst)) { return null; } List<T> result = Lists.newArrayListWithCapacity(originLst.size()); originLst.forEach(o -> result.add(convertObject(o, originStyle, targetClass))); return result; } /** * * @param originObj 待转换的源对象,【不可为null】 * @param originStyle 源对象的property的命名风格,【不可为null】 * @param targetClass 目标对象,【不可为null】FieldNamingPolicy * @param customizePropertyNameMap 自定义转换属性,【可为null】 * @param excludePropertyNameList 自定义的排除属性,【可为null】 * @return */ public static <T> T baseConvertObject(Object originObj, PropertyNameStyle originStyle, Class<T> targetClass, Map<String, String> customizePropertyNameMap, List<String> excludePropertyNameList) { T targetObj; try { targetObj = targetClass.newInstance(); } catch (InstantiationException | IllegalAccessException e) { log.error("通用的风格属性名转换时出错\n{}", e.getMessage()); return null; } Class<?> originClass = originObj.getClass(); PropertyDescriptor[] originPds = BeanUtils.getPropertyDescriptors(originClass), targetPds = BeanUtils.getPropertyDescriptors(targetClass); Function<String, String> propertyConvertFunc = PropertyNameStyle.CAMEL.equals(originStyle) ? GenericPropertyConverter::camel2Underline : GenericPropertyConverter::underline2Camel; for (PropertyDescriptor originPd : originPds) { String propertyName = originPd.getName(); if ("class".equals(propertyName)) { continue; } if (CollectionUtils.isNotEmpty(excludePropertyNameList) && excludePropertyNameList.contains(propertyName)) { continue; } String newPropertyName = StringUtils.EMPTY; if (MapUtils.isNotEmpty(customizePropertyNameMap)) { newPropertyName = customizePropertyNameMap.get(propertyName); } if (StringUtils.isBlank(newPropertyName)) { newPropertyName = propertyConvertFunc.apply(propertyName); } if (StringUtils.isBlank(newPropertyName)) { continue; } Class<?> originPropertyType = originPd.getPropertyType(); for (PropertyDescriptor targetPd : targetPds) { if (newPropertyName.equals(targetPd.getName()) == false) { continue; } Method originReadMethod = originPd.getReadMethod(), targetWriteMethod = targetPd.getWriteMethod(); if (originReadMethod != null && targetWriteMethod != null && ClassUtils.isAssignable(targetWriteMethod.getParameterTypes()[0], originPropertyType)) { try { if (Modifier.isPublic(originReadMethod.getDeclaringClass().getModifiers()) == false) { originReadMethod.setAccessible(true); } Object value = originReadMethod.invoke(originObj); if (Modifier.isPublic(targetWriteMethod.getDeclaringClass().getModifiers()) == false) { targetWriteMethod.setAccessible(true); } targetWriteMethod.invoke(targetObj, value); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) { log.error("通用的风格属性名转换时出错\n{}", e1.getMessage()); return null; } } } } return targetObj; } /** * 驼峰转下划线 * * @param camelStr * @return */ public static String camel2Underline(String camelStr) { if (StringUtils.isEmpty(camelStr)) { return StringUtils.EMPTY; } int len = camelStr.length(); StringBuilder strb = new StringBuilder(len + len >> 1); for (int i = 0; i < len; i++) { char c = camelStr.charAt(i); if (Character.isUpperCase(c)) { strb.append(UNDERLINE_CHAR); strb.append(Character.toLowerCase(c)); } else { strb.append(c); } } return strb.toString(); } /** * 下划线转驼峰 * * @param underlineStr * @return */ public static String underline2Camel(String underlineStr) { if (StringUtils.isEmpty(underlineStr)) { return StringUtils.EMPTY; } int len = underlineStr.length(); StringBuilder strb = new StringBuilder(len); for (int i = 0; i < len; i++) { char c = underlineStr.charAt(i); if (c == UNDERLINE_CHAR && (++i) < len) { c = underlineStr.charAt(i); strb.append(Character.toUpperCase(c)); } else { strb.append(c); } } return strb.toString(); } }
推荐阅读
-
java Bean与json对象间的转换实例讲解
-
Java实现图片与二进制的互相转换
-
java对象与json对象间的相互转换
-
Java实现的Excel列号数字与字母互相转换功能
-
Java的驼峰与下划线的属性对象互相转换
-
JAVA 基础 /第七课: 面向对象 / JAVA类的属性,类变量与实例变量
-
对象流,它们是一对高级流,负责即将java对象与字节之间在读写的过程中进行转换。 * java.io.ObjectOutputStream * java.io.ObjectInputStream
-
JAXB处理java对象与xml格式之间的转换
-
java Bean与json对象间的转换实例讲解
-
java类与对象(属性,方法)的使用