diff --git a/CHANGELOG.md b/CHANGELOG.md index 51b15c717..789d79960 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ * 【core 】 增加Calculator(issue#1090@Github) * 【core 】 IdcardUtil增加getIdcardInfo方法(issue#1092@Github) * 【core 】 改进ObjectUtil.equal,支持BigDecimal判断 +* 【core 】 ArrayConverter增加可选是否忽略错误(issue#I1VNYQ@Gitee) ### Bug修复 * 【core 】 修复Dict.of错误(issue#I1UUO5@Gitee) diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java b/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java index c84c5609f..9c081999b 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java @@ -350,11 +350,7 @@ public class ConverterRegistry implements Serializable { // 数组转换 if (rowType.isArray()) { final ArrayConverter arrayConverter = new ArrayConverter(rowType); - try { - return (T) arrayConverter.convert(value, defaultValue); - } catch (Exception e) { - // 数组转换失败进行下一步 - } + return (T) arrayConverter.convert(value, defaultValue); } // 表示非需要特殊转换的对象 diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/impl/ArrayConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/impl/ArrayConverter.java index 533b95bb9..8653f095f 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/impl/ArrayConverter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/impl/ArrayConverter.java @@ -2,7 +2,7 @@ package cn.hutool.core.convert.impl; import cn.hutool.core.collection.IterUtil; import cn.hutool.core.convert.AbstractConverter; -import cn.hutool.core.convert.ConverterRegistry; +import cn.hutool.core.convert.Convert; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; @@ -15,35 +15,54 @@ import java.util.List; /** * 数组转换器,包括原始类型数组 - * + * * @author Looly */ public class ArrayConverter extends AbstractConverter { private static final long serialVersionUID = 1L; private final Class targetType; - /** 目标元素类型 */ + /** + * 目标元素类型 + */ private final Class targetComponentType; + /** + * 是否忽略元素转换错误 + */ + private boolean ignoreElementError; + /** * 构造 - * + * * @param targetType 目标数组类型 */ public ArrayConverter(Class targetType) { + this(targetType, false); + } + + /** + * 构造 + * + * @param targetType 目标数组类型 + * @param ignoreElementError 是否忽略元素转换错误 + */ + public ArrayConverter(Class targetType, boolean ignoreElementError) { if (null == targetType) { // 默认Object数组 targetType = Object[].class; } - - if(targetType.isArray()) { + + if (targetType.isArray()) { this.targetType = targetType; this.targetComponentType = targetType.getComponentType(); - }else { + } else { //用户传入类为非数组时,按照数组元素类型对待 this.targetComponentType = targetType; this.targetType = ArrayUtil.getArrayType(targetType); } + + this.ignoreElementError = ignoreElementError; } @Override @@ -51,16 +70,27 @@ public class ArrayConverter extends AbstractConverter { return value.getClass().isArray() ? convertArrayToArray(value) : convertObjectToArray(value); } - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings({"unchecked", "rawtypes"}) @Override public Class getTargetType() { return this.targetType; } + /** + * 设置是否忽略元素转换错误 + * + * @param ignoreElementError 是否忽略元素转换错误 + * @since 5.4.3 + */ + public void setIgnoreElementError(boolean ignoreElementError) { + this.ignoreElementError = ignoreElementError; + } + // -------------------------------------------------------------------------------------- Private method start + /** * 数组对数组转换 - * + * * @param array 被转换的数组值 * @return 转换后的数组 */ @@ -74,16 +104,15 @@ public class ArrayConverter extends AbstractConverter { final int len = ArrayUtil.length(array); final Object result = Array.newInstance(targetComponentType, len); - final ConverterRegistry converter = ConverterRegistry.getInstance(); for (int i = 0; i < len; i++) { - Array.set(result, i, converter.convert(targetComponentType, Array.get(array, i))); + Array.set(result, i, convertComponentType(Array.get(array, i))); } return result; } /** * 非数组对数组转换 - * + * * @param value 被转换值 * @return 转换后的数组 */ @@ -98,14 +127,13 @@ public class ArrayConverter extends AbstractConverter { return convertArrayToArray(strings); } - final ConverterRegistry converter = ConverterRegistry.getInstance(); Object result; if (value instanceof List) { // List转数组 final List list = (List) value; result = Array.newInstance(targetComponentType, list.size()); for (int i = 0; i < list.size(); i++) { - Array.set(result, i, converter.convert(targetComponentType, list.get(i))); + Array.set(result, i, convertComponentType(list.get(i))); } } else if (value instanceof Collection) { // 集合转数组 @@ -114,7 +142,7 @@ public class ArrayConverter extends AbstractConverter { int i = 0; for (Object element : collection) { - Array.set(result, i, converter.convert(targetComponentType, element)); + Array.set(result, i, convertComponentType(element)); i++; } } else if (value instanceof Iterable) { @@ -122,16 +150,16 @@ public class ArrayConverter extends AbstractConverter { final List list = IterUtil.toList((Iterable) value); result = Array.newInstance(targetComponentType, list.size()); for (int i = 0; i < list.size(); i++) { - Array.set(result, i, converter.convert(targetComponentType, list.get(i))); + Array.set(result, i, convertComponentType(list.get(i))); } } else if (value instanceof Iterator) { // 可循环对象转数组,可循环对象无法获取长度,因此先转为List后转为数组 final List list = IterUtil.toList((Iterator) value); result = Array.newInstance(targetComponentType, list.size()); for (int i = 0; i < list.size(); i++) { - Array.set(result, i, converter.convert(targetComponentType, list.get(i))); + Array.set(result, i, convertComponentType(list.get(i))); } - }else if (value instanceof Serializable && byte.class == targetComponentType) { + } else if (value instanceof Serializable && byte.class == targetComponentType) { // 用户可能想序列化指定对象 result = ObjectUtil.serialize(value); } else { @@ -144,14 +172,25 @@ public class ArrayConverter extends AbstractConverter { /** * 单元素数组 - * + * * @param value 被转换的值 * @return 数组,只包含一个元素 */ private Object[] convertToSingleElementArray(Object value) { final Object[] singleElementArray = ArrayUtil.newArray(targetComponentType, 1); - singleElementArray[0] = ConverterRegistry.getInstance().convert(targetComponentType, value); + singleElementArray[0] = convertComponentType(value); return singleElementArray; } + + /** + * 转换元素类型 + * + * @param value 值 + * @return 转换后的值,转换失败若{@link #ignoreElementError}为true,返回null,否则抛出异常 + * @since 5.4.3 + */ + private Object convertComponentType(Object value) { + return Convert.convertWithCheck(this.targetComponentType, value, null, this.ignoreElementError); + } // -------------------------------------------------------------------------------------- Private method end } diff --git a/hutool-core/src/test/java/cn/hutool/core/convert/ConvertToArrayTest.java b/hutool-core/src/test/java/cn/hutool/core/convert/ConvertToArrayTest.java index 8670e4c83..fe7fa68f0 100644 --- a/hutool-core/src/test/java/cn/hutool/core/convert/ConvertToArrayTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/convert/ConvertToArrayTest.java @@ -1,16 +1,15 @@ package cn.hutool.core.convert; -import java.io.File; -import java.net.URL; -import java.util.ArrayList; - -import org.junit.Assert; -import org.junit.Ignore; -import org.junit.Test; - import cn.hutool.core.convert.impl.ArrayConverter; import cn.hutool.core.io.FileUtil; import cn.hutool.core.lang.Console; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + +import java.io.File; +import java.net.URL; +import java.util.ArrayList; /** * 类型转换工具单元测试
@@ -35,6 +34,15 @@ public class ConvertToArrayTest { Integer[] intArray2 = Convert.toIntArray(c); Assert.assertArrayEquals(intArray2, new Integer[]{1,2,3,4,5}); } + + @Test + public void toIntArrayTestIgnoreComponentErrorTest() { + String[] b = { "a", "1" }; + + final ArrayConverter arrayConverter = new ArrayConverter(Integer[].class, true); + Integer[] integerArray = (Integer[]) arrayConverter.convert(b, null); + Assert.assertArrayEquals(integerArray, new Integer[]{null, 1}); + } @Test public void toLongArrayTest() {