diff --git a/mapstruct-plus/src/main/java/io/github/linpeilie/Converter.java b/mapstruct-plus/src/main/java/io/github/linpeilie/Converter.java index 92ae3a717d708e25fde2c0cae008f7f32c8c1344..8796ae4ed586f37ea9fb1a354a862033c17fbffc 100644 --- a/mapstruct-plus/src/main/java/io/github/linpeilie/Converter.java +++ b/mapstruct-plus/src/main/java/io/github/linpeilie/Converter.java @@ -1,10 +1,13 @@ package io.github.linpeilie; +import io.github.linpeilie.utils.CollectionUtils; +import io.github.linpeilie.utils.ObjectUtils; + import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.stream.Collectors; +import java.util.function.Consumer; public class Converter { @@ -20,77 +23,134 @@ public class Converter { @SuppressWarnings("unchecked") public T convert(S source, Class targetType) { - if (source == null) { + if (ObjectUtils.isAnyNull(source, targetType)) { return null; } - BaseMapper mapper = (BaseMapper) converterFactory.getMapper(source.getClass(), targetType); - if (mapper != null) { - return mapper.convert(source); + Class sourceType = source.getClass(); + BaseMapper mapper = (BaseMapper) converterFactory.getMapper(sourceType, targetType); + if (ObjectUtils.isNull(mapper)) { + throw new ConvertException("cannot find converter from " + sourceType.getSimpleName() + " to " + targetType.getSimpleName()); } - throw new ConvertException( - "cannot find converter from " + source.getClass().getSimpleName() + " to " + targetType.getSimpleName()); + return mapper.convert(source); + } + + public T convert(S source, Class targetType, Consumer beanConsumer) { + T bean = convert(source, targetType); + return ObjectUtils.handleIfNull(bean, beanConsumer); } @SuppressWarnings("unchecked") public T convert(S source, T target) { - if (source == null) { - return null; - } - if (target == null) { + if (ObjectUtils.isAnyNull(source, target)) { return null; } - BaseMapper mapper = (BaseMapper) converterFactory.getMapper(source.getClass(), target.getClass()); - if (mapper != null) { - return mapper.convert(source, target); + Class sourceType = source.getClass(); + Class targetType = target.getClass(); + BaseMapper mapper = (BaseMapper) converterFactory.getMapper(sourceType, targetType); + if (ObjectUtils.isNull(mapper)) { + throw new ConvertException("cannot find converter from " + sourceType.getSimpleName() + " to " + targetType.getSimpleName()); } - throw new ConvertException("cannot find converter from " + source.getClass().getSimpleName() + " to " + - target.getClass().getSimpleName()); + return mapper.convert(source, target); + } + + public T convert(S source, T target, Consumer beanConsumer) { + T bean = convert(source, target); + return ObjectUtils.handleIfNull(bean, beanConsumer); } - public List convert(List source, Class targetType) { - if (source == null || source.isEmpty()) { + public List convert(List sourceList, Class targetType) { + return convert(sourceList, targetType, (Consumer) null); + } + + @SuppressWarnings("unchecked") + public List convert(List sourceList, Class targetType, Consumer beanConsumer) { + if (CollectionUtils.isEmpty(sourceList)) { return new ArrayList<>(); } - return source.stream().map(item -> convert(item, targetType)).collect(Collectors.toList()); + if (ObjectUtils.isNull(targetType)) { + throw new ConvertException("targetType cannot be null"); + } + Class sourceType = sourceList.getFirst().getClass(); + BaseMapper mapper = (BaseMapper) converterFactory.getMapper(sourceType, targetType); + if (ObjectUtils.isNull(mapper)) { + throw new ConvertException("cannot find converter from " + sourceType.getSimpleName() + " to " + targetType.getSimpleName()); + } + // 如果 beanConsumer 本来就为 null,则不再调用带 Consumer 参数的 convert 方法,避免在循环中进行不必要的非空判断 + if (ObjectUtils.isNotNull(beanConsumer)) { + return CollectionUtils.toList(sourceList, source -> { + T bean = mapper.convert(source); + beanConsumer.accept(bean); + return bean; + }); + } + return mapper.convert(sourceList); } - @SuppressWarnings("unchecked") - public T convert(S source, Class target, CycleAvoidingMappingContext context) { - if (source == null) { + public T convert(S source, Class targetType, CycleAvoidingMappingContext context) { + if (ObjectUtils.isAnyNull(source, targetType)) { return null; } - BaseCycleAvoidingMapper mapper = - (BaseCycleAvoidingMapper) converterFactory.getCycleAvoidingMapper(source.getClass(), target); - if (mapper != null) { - return mapper.convert(source, context); + Class sourceType = source.getClass(); + BaseCycleAvoidingMapper mapper = (BaseCycleAvoidingMapper) converterFactory.getCycleAvoidingMapper(sourceType, targetType); + if (ObjectUtils.isNull(mapper)) { + throw new ConvertException("cannot find converter from " + sourceType.getSimpleName() + " to " + targetType.getSimpleName()); } - throw new ConvertException("cannot find converter from " + source.getClass().getSimpleName() + " to " + - target.getSimpleName()); + return mapper.convert(source, context); } - public List convert(List source, Class targetType, CycleAvoidingMappingContext context) { - if (source == null || source.isEmpty()) { - return new ArrayList<>(); - } - return source.stream().map(item -> convert(item, targetType, context)).collect(Collectors.toList()); + public T convert(S source, Class targetType, CycleAvoidingMappingContext context, Consumer beanConsumer) { + T bean = convert(source, targetType, context); + return ObjectUtils.handleIfNull(bean, beanConsumer); + } + + public List convert(List sourceList, Class targetType, CycleAvoidingMappingContext context) { + return convert(sourceList, targetType, context, null); } + @SuppressWarnings("unchecked") + public List convert(List sourceList, Class targetType, CycleAvoidingMappingContext context, Consumer beanConsumer) { + if (CollectionUtils.isEmpty(sourceList)) { + return new ArrayList<>(); + } + if (ObjectUtils.isNull(targetType)) { + throw new ConvertException("targetType cannot be null"); + } + Class sourceType = sourceList.getFirst().getClass(); + BaseCycleAvoidingMapper mapper = (BaseCycleAvoidingMapper) converterFactory.getCycleAvoidingMapper(sourceType, targetType); + if (ObjectUtils.isNull(mapper)) { + throw new ConvertException("cannot find converter from " + sourceType.getSimpleName() + " to " + targetType.getSimpleName()); + } + // 如果 beanConsumer 本来就为 null,则不再调用带 Consumer 参数的 convert 方法,避免在循环中进行不必要的非空判断 + if (ObjectUtils.isNotNull(beanConsumer)) { + return CollectionUtils.toList(sourceList, source -> { + T bean = mapper.convert(source, context); + beanConsumer.accept(bean); + return bean; + }); + } + return mapper.convert(sourceList, context); + } - public T convert(Map map, Class target) { - if (map == null || map.isEmpty()) { + public T convert(Map map, Class targetType) { + if (CollectionUtils.isEmpty(map) || map.values().stream().allMatch(Objects::isNull)) { return null; } - if (map.values().stream().allMatch(Objects::isNull)) { - return null; + if (ObjectUtils.isNull(targetType)) { + throw new ConvertException("targetType cannot be null"); } - final BaseMapMapper mapper = converterFactory.getMapMapper(target); - if (mapper != null) { - return mapper.convert(map); + + final BaseMapMapper mapper = converterFactory.getMapMapper(targetType); + if (ObjectUtils.isNull(mapper)) { + throw new ConvertException("cannot find converter from " + map.getClass().getName() + " to " + targetType.getSimpleName()); } - throw new ConvertException("cannot find converter from " + map.getClass().getName() + " to " + - target.getSimpleName()); + return mapper.convert(map); + } + + public T convert(Map map, Class targetType, Consumer beanConsumer) { + T bean = convert(map, targetType); + return ObjectUtils.handleIfNull(bean, beanConsumer); } } diff --git a/mapstruct-plus/src/main/java/io/github/linpeilie/utils/CollectionUtils.java b/mapstruct-plus/src/main/java/io/github/linpeilie/utils/CollectionUtils.java index 711d4fb7ca87439c769a3b07303c26de409897e2..f24aff4a7a7542d1d983f1e3b8e05c1f834c1432 100644 --- a/mapstruct-plus/src/main/java/io/github/linpeilie/utils/CollectionUtils.java +++ b/mapstruct-plus/src/main/java/io/github/linpeilie/utils/CollectionUtils.java @@ -1,23 +1,52 @@ package io.github.linpeilie.utils; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; +import java.util.*; +import java.util.function.Function; import java.util.stream.Collectors; public class CollectionUtils { + /** + * 判断集合是否为空 + * + * @param collection 集合对象 + * @return 是否为空 + */ public static boolean isEmpty(Collection collection) { return collection == null || collection.isEmpty(); } + /** + * 判断集合是否不为空 + * + * @param collection 集合对象 + * @return 是否不为空 + */ public static boolean isNotEmpty(Collection collection) { return !isEmpty(collection); } + /** + * 判断Map是否为空 + * + * @param map Map对象 + * @return 是否为空 + */ + public static boolean isEmpty(Map map) { + return null == map || map.isEmpty(); + } + + /** + * 判断Map是否不为空 + * + * @param map Map对象 + * @return 是否不为空 + */ + public static boolean isNotEmpty(Map map) { + return !isEmpty(map); + } + + @SafeVarargs public static List newArrayList(T... values) { if (values == null || values.length == 0) { return new ArrayList<>(); @@ -34,4 +63,26 @@ public class CollectionUtils { return list.stream().map(str -> prefix + str + suffix).collect(Collectors.joining(delimiter)); } + /** + * 将collection转化为List集合,但是两者的泛型不同
+ * {@code Collection ------> List } + * + * @param collection 需要转化的集合 + * @param function collection中的泛型转化为list泛型的lambda表达式 + * @param collection中的泛型 + * @param List中的泛型 + * @return 转化后的list + */ + public static List toList(Collection collection, Function function) { + if (CollectionUtils.isEmpty(collection)) { + return CollectionUtils.newArrayList(); + } + return collection + .stream() + .map(function) + .filter(Objects::nonNull) + // 注意此处不要使用 .toList() 新语法 因为返回的是不可变List 会导致序列化问题 + .collect(Collectors.toList()); + } + } diff --git a/mapstruct-plus/src/main/java/io/github/linpeilie/utils/ObjectUtils.java b/mapstruct-plus/src/main/java/io/github/linpeilie/utils/ObjectUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..83c5dc948e36f3252da05af7652580f7767c2e94 --- /dev/null +++ b/mapstruct-plus/src/main/java/io/github/linpeilie/utils/ObjectUtils.java @@ -0,0 +1,115 @@ +package io.github.linpeilie.utils; + +import java.util.function.Consumer; +import java.util.function.Function; + +public class ObjectUtils { + + /** + * 检查对象是否为null
+ * 判断标准为: + * + *
+     * 1. == null
+     * 2. equals(null)
+     * 
+ * + * @param obj 对象 + * @return 是否为null + */ + public static boolean isNull(Object obj) { + //noinspection ConstantConditions + return null == obj || obj.equals(null); + } + + /** + * 检查对象是否不为null + *
+     * 1. != null
+     * 2. not equals(null)
+     * 
+ * + * @param obj 对象 + * @return 是否为非null + */ + public static boolean isNotNull(Object obj) { + return !isNull(obj); + } + + /** + * 是否包含{@code null}元素 + * + * @param 数组元素类型 + * @param array 被检查的数组 + * @return 是否包含{@code null}元素 + */ + @SuppressWarnings("unchecked") + public static boolean isAnyNull(T... array) { + if (ArrayUtil.isNotEmpty(array)) { + for (T element : array) { + if (isNull(element)) { + return true; + } + } + } + return array == null; + } + + /** + * 是否全都不为{@code null}元素 + * + * @param 数组元素类型 + * @param array 被检查的数组 + * @return 是否全都不为{@code null}元素 + */ + @SuppressWarnings("unchecked") + public static boolean isAllNotNull(T... array) { + return !isAnyNull(array); + } + + /** + * 如果给定对象不为null 则以给定对象作为参数执行handle方法 + * + * @param 被检查对象 + * @param source Object 类型对象 + * @param handle 非空时自定义的处理方法 + * @return 处理后的对象 + */ + public static T handleIfNull(T source, Consumer handle) { + if (isAllNotNull(source, handle)) { + handle.accept(source); + } + return source; + } + + /** + * 如果给定对象为{@code null} 返回默认值, 如果不为null 返回自定义handle处理后的返回值 + * + * @param 被检查对象为{@code null}返回默认值,否则返回自定义handle处理后的返回值 + * @param 被检查的对象类型 + * @param source Object 类型对象 + * @param handle 非空时自定义的处理方法 + * @param defaultValue 默认为空的返回值 + * @return 处理后的返回值 + */ + public static T defaultIfNull(R source, Function handle, final T defaultValue) { + if (isNotNull(source)) { + return handle.apply(source); + } + return defaultValue; + } + + /** + * 如果给定对象为{@code null} 返回默认值, 如果不为null 返回自定义handle处理后的返回值 + * + * @param 被检查对象为{@code null}返回默认值,否则返回自定义handle处理后的返回值 + * @param 被检查的对象类型 + * @param source Object 类型对象 + * @param handle 非空时自定义的处理方法 + * @return 处理后的返回值 + */ + public static T defaultIfNull(R source, Function handle) { + return defaultIfNull(source, handle, null); + } + +}