Looly 5 years ago
parent
commit
1c4c69cfe8

+ 3 - 1
CHANGELOG.md

@@ -3,9 +3,11 @@
 
 -------------------------------------------------------------------------------------------------------------
 
-# 5.4.1 (2020-08-16)
+# 5.4.1 (2020-08-19)
 
 ### 新特性
+* 【core  】     StrUtil增加firstNonXXX方法(issue#1020@Github)
+* 【core  】     BeanCopier修改规则,可选bean拷贝空字段报错问题(pr#160@Gitee)
 ### Bug修复#
 
 -------------------------------------------------------------------------------------------------------------

+ 3 - 0
bin/package.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+exec mvn -T 1C clean source:jar javadoc:javadoc package -Dmaven.test.skip=false -Dmaven.javadoc.skip=false

+ 2 - 9
hutool-core/src/main/java/cn/hutool/core/bean/copier/BeanCopier.java

@@ -13,7 +13,6 @@ import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.ArrayUtil;
 import cn.hutool.core.util.ModifierUtil;
 import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.ReflectUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.core.util.TypeUtil;
 
@@ -275,19 +274,13 @@ public class BeanCopier<T> implements Copier<T>, Serializable {
 				// valueProvider在没有对值做转换且当类型不匹配的时候,执行默认转换
 				propClass = prop.getFieldClass();
 				if (false ==propClass.isInstance(value)) {
-					value = Convert.convert(propClass, value);
+					value = Convert.convertWithCheck(propClass, value, null, copyOptions.ignoreError);
 					if (null == value && copyOptions.ignoreNullValue) {
 						continue;// 当允许跳过空时,跳过
 					}
 				}
 
-				if(null == setterMethod){
-					// 直接注入值
-					ReflectUtil.setFieldValue(bean, field, value);
-				} else{
-					// 执行set方法注入值
-					ReflectUtil.invoke(bean, setterMethod, value);
-				}
+				prop.setValue(bean, value);
 			} catch (Exception e) {
 				if (false ==copyOptions.ignoreError) {
 					throw new UtilException(e, "Inject [{}] error!", prop.getFieldName());

+ 16 - 1
hutool-core/src/main/java/cn/hutool/core/util/ArrayUtil.java

@@ -7,6 +7,7 @@ import cn.hutool.core.comparator.CompareUtil;
 import cn.hutool.core.exceptions.UtilException;
 import cn.hutool.core.lang.Editor;
 import cn.hutool.core.lang.Filter;
+import cn.hutool.core.lang.Matcher;
 
 import java.lang.reflect.Array;
 import java.nio.ByteBuffer;
@@ -299,9 +300,23 @@ public class ArrayUtil {
 	 */
 	@SuppressWarnings("unchecked")
 	public static <T> T firstNonNull(T... array) {
+		return firstMatch(Objects::nonNull, array);
+	}
+
+	/**
+	 * 返回数组中第一个匹配规则的值
+	 *
+	 * @param <T>   数组元素类型
+	 * @param matcher 匹配接口,实现此接口自定义匹配规则
+	 * @param array 数组
+	 * @return 非空元素,如果不存在非空元素或数组为空,返回{@code null}
+	 * @since 3.0.7
+	 */
+	@SuppressWarnings("unchecked")
+	public static <T> T firstMatch(Matcher<T> matcher, T... array) {
 		if (isNotEmpty(array)) {
 			for (final T val : array) {
-				if (null != val) {
+				if(matcher.match(val)){
 					return val;
 				}
 			}

+ 41 - 0
hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java

@@ -4337,4 +4337,45 @@ public class StrUtil {
 		}
 		return sb.toString();
 	}
+
+	/**
+	 * 返回第一个非{@code null} 元素
+	 *
+	 * @param strs 多个元素
+	 * @param <T>  元素类型
+	 * @return 第一个非空元素,如果给定的数组为空或者都为空,返回{@code null}
+	 * @since 5.4.1
+	 */
+	@SuppressWarnings("unchecked")
+	public <T extends CharSequence> T firstNonNull(T... strs) {
+		return ArrayUtil.firstNonNull(strs);
+	}
+
+	/**
+	 * 返回第一个非empty 元素
+	 *
+	 * @param strs 多个元素
+	 * @param <T>  元素类型
+	 * @return 第一个非空元素,如果给定的数组为空或者都为空,返回{@code null}
+	 * @since 5.4.1
+	 * @see #isNotEmpty(CharSequence)
+	 */
+	@SuppressWarnings("unchecked")
+	public <T extends CharSequence> T firstNonEmpty(T... strs) {
+			return ArrayUtil.firstMatch(StrUtil::isNotEmpty, strs);
+	}
+
+	/**
+	 * 返回第一个非blank 元素
+	 *
+	 * @param strs 多个元素
+	 * @param <T>  元素类型
+	 * @return 第一个非空元素,如果给定的数组为空或者都为空,返回{@code null}
+	 * @since 5.4.1
+	 * @see #isNotBlank(CharSequence)
+	 */
+	@SuppressWarnings("unchecked")
+	public <T extends CharSequence> T firstNonBlank(T... strs) {
+		return ArrayUtil.firstMatch(StrUtil::isNotBlank, strs);
+	}
 }

+ 12 - 0
hutool-core/src/test/java/cn/hutool/core/util/CharUtilTest.java

@@ -26,4 +26,16 @@ public class CharUtilTest {
 		char a = 'a';
 		Assert.assertTrue(CharUtil.isChar(a));
 	}
+
+	@Test
+	public void isBlankCharTest(){
+		char a = '\u00A0';
+		Assert.assertTrue(CharUtil.isBlankChar(a));
+
+		char a2 = '\u0020';
+		Assert.assertTrue(CharUtil.isBlankChar(a2));
+
+		char a3 = '\u3000';
+		Assert.assertTrue(CharUtil.isBlankChar(a3));
+	}
 }