mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-07-21 15:09:48 +08:00
fix code
This commit is contained in:
@@ -103,6 +103,7 @@ public class ArrayUtil extends PrimitiveArrayUtil {
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------- isBlank
|
||||
|
||||
/**
|
||||
* <p>指定字符串数组中,是否包含空字符串。</p>
|
||||
* <p>如果指定的字符串数组的长度为 0,或者其中的任意一个元素是空字符串,则返回 true。</p>
|
||||
@@ -1186,6 +1187,23 @@ public class ArrayUtil extends PrimitiveArrayUtil {
|
||||
return (E) ArrayWrapper.of(array).get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取满足条件的第一个元素
|
||||
*
|
||||
* @param array 数组
|
||||
* @param predicate 条件
|
||||
* @param <E> 元素类型
|
||||
* @return 满足条件的第一个元素,未找到返回{@code null}
|
||||
*/
|
||||
public static <E> E get(final E[] array, final Predicate<E> predicate) {
|
||||
for (final E e : array) {
|
||||
if (predicate.test(e)) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数组中所有指定位置的元素值,组成新数组
|
||||
*
|
||||
@@ -1249,12 +1267,12 @@ public class ArrayUtil extends PrimitiveArrayUtil {
|
||||
* @param array 数组
|
||||
* @param beginInclude 开始位置(包括)
|
||||
* @param endExclude 结束位置(不包括)
|
||||
* @param <A> 数组类型
|
||||
* @return 新的数组
|
||||
* @since 4.0.6
|
||||
* @param <A> 数组类型
|
||||
*/
|
||||
public static <A> A sub(final A array,
|
||||
final int beginInclude, final int endExclude) {
|
||||
final int beginInclude, final int endExclude) {
|
||||
return ArrayWrapper.of(array).getSub(beginInclude, endExclude);
|
||||
}
|
||||
|
||||
@@ -1265,12 +1283,12 @@ public class ArrayUtil extends PrimitiveArrayUtil {
|
||||
* @param beginInclude 开始位置(包括)
|
||||
* @param endExclude 结束位置(不包括)
|
||||
* @param step 步进
|
||||
* @param <A> 数组类型
|
||||
* @return 新的数组
|
||||
* @since 4.0.6
|
||||
* @param <A> 数组类型
|
||||
*/
|
||||
public static <A> A sub(final A array,
|
||||
final int beginInclude, final int endExclude, final int step) {
|
||||
final int beginInclude, final int endExclude, final int step) {
|
||||
return ArrayWrapper.of(array).getSub(beginInclude, endExclude, step);
|
||||
}
|
||||
|
||||
|
@@ -12,6 +12,7 @@
|
||||
|
||||
package org.dromara.hutool.core.bean;
|
||||
|
||||
import org.dromara.hutool.core.array.ArrayUtil;
|
||||
import org.dromara.hutool.core.lang.Assert;
|
||||
import org.dromara.hutool.core.map.CaseInsensitiveMap;
|
||||
import org.dromara.hutool.core.reflect.FieldUtil;
|
||||
@@ -149,7 +150,6 @@ public class BeanDesc implements Serializable {
|
||||
/**
|
||||
* 初始化<br>
|
||||
* 只有与属性关联的相关Getter和Setter方法才会被读取,无关的getXXX和setXXX都被忽略
|
||||
*
|
||||
*/
|
||||
private void init() {
|
||||
final Method[] gettersAndSetters = MethodUtil.getPublicMethods(this.beanClass, MethodUtil::isGetterOrSetterIgnoreCase);
|
||||
@@ -209,22 +209,57 @@ public class BeanDesc implements Serializable {
|
||||
final Class<?> fieldType = field.getType();
|
||||
final boolean isBooleanField = BooleanUtil.isBoolean(fieldType);
|
||||
|
||||
// Getter: name -> getName, Setter: name -> setName
|
||||
final Method[] getterAndSetter = findGetterAndSetter(fieldName, fieldType, gettersOrSetters, ignoreCase);
|
||||
|
||||
if (isBooleanField) {
|
||||
if (null == getterAndSetter[0]) {
|
||||
// isName -> isName or isIsName
|
||||
// name -> isName
|
||||
getterAndSetter[0] = findGetterForBoolean(fieldName, gettersOrSetters, ignoreCase);
|
||||
}
|
||||
if (null == getterAndSetter[1]) {
|
||||
// isName -> setName
|
||||
getterAndSetter[1] = findSetterForBoolean(fieldName, gettersOrSetters, ignoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
return new PropDesc(field, getterAndSetter[0], getterAndSetter[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找字段对应的Getter和Setter方法<br>
|
||||
* 此方法不区分是否为boolean字段,查找规则为:
|
||||
* <ul>
|
||||
* <li>Getter要求无参数且返回值是字段类型或字段的父类</li>
|
||||
* <li>Getter中,如果字段为name,匹配getName</li>
|
||||
* <li>Setter要求一个参数且参数必须为字段类型或字段的子类</li>
|
||||
* <li>Setter中,如果字段为name,匹配setName</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param fieldName 字段名
|
||||
* @param fieldType 字段类型
|
||||
* @param gettersOrSetters 类中所有的Getter或Setter方法
|
||||
* @return PropDesc
|
||||
*/
|
||||
private Method[] findGetterAndSetter(final String fieldName, final Class<?> fieldType,
|
||||
final Method[] gettersOrSetters, final boolean ignoreCase) {
|
||||
Method getter = null;
|
||||
Method setter = null;
|
||||
String methodName;
|
||||
for (final Method method : gettersOrSetters) {
|
||||
methodName = method.getName();
|
||||
if (method.getParameterCount() == 0) {
|
||||
if (0 == method.getParameterCount()) {
|
||||
// 无参数,可能为Getter方法
|
||||
if (isMatchGetter(methodName, fieldName, isBooleanField, ignoreCase)) {
|
||||
// 方法名与字段名匹配,则为Getter方法
|
||||
if (StrUtil.equals(methodName, StrUtil.genGetter(fieldName), ignoreCase) &&
|
||||
method.getReturnType().isAssignableFrom(fieldType)) {
|
||||
// getter的返回类型必须为字段类型或字段的父类
|
||||
getter = method;
|
||||
}
|
||||
} else if (isMatchSetter(methodName, fieldName, isBooleanField, ignoreCase)) {
|
||||
// setter方法的参数类型和字段类型必须一致,或参数类型是字段类型的子类
|
||||
if(fieldType.isAssignableFrom(method.getParameterTypes()[0])){
|
||||
setter = method;
|
||||
}
|
||||
} else if (StrUtil.equals(methodName, StrUtil.genSetter(fieldName), ignoreCase) &&
|
||||
fieldType.isAssignableFrom(method.getParameterTypes()[0])) {
|
||||
// setter方法的参数必须为字段类型或字段的子类
|
||||
setter = method;
|
||||
}
|
||||
if (null != getter && null != setter) {
|
||||
// 如果Getter和Setter方法都找到了,不再继续寻找
|
||||
@@ -232,104 +267,85 @@ public class BeanDesc implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
return new PropDesc(field, getter, setter);
|
||||
return new Method[]{getter, setter};
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法是否为Getter方法<br>
|
||||
* 匹配规则如下(忽略大小写):
|
||||
* 针对Boolean或boolean类型字段,查找其对应的Getter方法,规则为:
|
||||
* <ul>
|
||||
* <li>方法必须无参数且返回boolean或Boolean</li>
|
||||
* <li>如果字段为isName, 匹配isName、isIsName方法,两个方法均存在,则按照提供的方法数组优先匹配。</li>
|
||||
* <li>如果字段为name, 匹配isName方法</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* 需要注意的是,以下两种格式不匹配,由{@link #findGetterAndSetter(String, Class, Method[], boolean)}完成:
|
||||
* <ul>
|
||||
* <li>如果字段为name, 匹配getName</li>
|
||||
* <li>如果字段为isName, 匹配getIsName</li>
|
||||
* </ul>
|
||||
*
|
||||
* <pre>
|
||||
* 字段名 -》 方法名
|
||||
* isName -》 isName
|
||||
* isName -》 isIsName
|
||||
* isName -》 getIsName
|
||||
* name -》 isName
|
||||
* name -》 getName
|
||||
* </pre>
|
||||
*
|
||||
* @param methodName 方法名
|
||||
* @param fieldName 字段名
|
||||
* @param isBooleanField 是否为Boolean类型字段
|
||||
* @param ignoreCase 匹配是否忽略大小写
|
||||
* @return 是否匹配
|
||||
* @param fieldName 字段名
|
||||
* @param gettersOrSetters 所有方法
|
||||
* @param ignoreCase 是否忽略大小写
|
||||
* @return 查找到的方法,{@code null}表示未找到
|
||||
*/
|
||||
private boolean isMatchGetter(String methodName, String fieldName, final boolean isBooleanField, final boolean ignoreCase) {
|
||||
final String handledFieldName;
|
||||
if (ignoreCase) {
|
||||
// 全部转为小写,忽略大小写比较
|
||||
methodName = methodName.toLowerCase();
|
||||
handledFieldName = fieldName.toLowerCase();
|
||||
fieldName = handledFieldName;
|
||||
} else {
|
||||
handledFieldName = StrUtil.upperFirst(fieldName);
|
||||
}
|
||||
private Method findGetterForBoolean(final String fieldName, final Method[] gettersOrSetters, final boolean ignoreCase) {
|
||||
// 查找isXXX
|
||||
return ArrayUtil.get(gettersOrSetters, m -> {
|
||||
if (0 != m.getParameterCount() || false == BooleanUtil.isBoolean(m.getReturnType())) {
|
||||
// getter方法要求无参数且返回boolean或Boolean
|
||||
return false;
|
||||
}
|
||||
|
||||
// 针对Boolean类型特殊检查
|
||||
if (isBooleanField) {
|
||||
if (fieldName.startsWith("is")) {
|
||||
// 字段已经是is开头
|
||||
if (methodName.equals(fieldName) // isName -》 isName
|
||||
|| ("get" + handledFieldName).equals(methodName)// isName -》 getIsName
|
||||
|| ("is" + handledFieldName).equals(methodName)// isName -》 isIsName
|
||||
) {
|
||||
if (StrUtil.startWith(fieldName, "is", ignoreCase)) {
|
||||
// isName -》 isName
|
||||
if(StrUtil.equals(fieldName, m.getName(), ignoreCase)){
|
||||
return true;
|
||||
}
|
||||
} else if (("is" + handledFieldName).equals(methodName)) {
|
||||
// 字段非is开头, name -》 isName
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 包括boolean的任何类型只有一种匹配情况:name -》 getName
|
||||
return ("get" + handledFieldName).equals(methodName);
|
||||
// name -》 isName
|
||||
// isName -》 isIsName
|
||||
return StrUtil.equals(StrUtil.upperFirstAndAddPre(fieldName, "is"), m.getName(), ignoreCase);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法是否为Setter方法<br>
|
||||
* 匹配规则如下(忽略大小写):
|
||||
* 针对Boolean或boolean类型字段,查找其对应的Setter方法,规则为:
|
||||
* <ul>
|
||||
* <li>方法必须为1个boolean或Boolean参数</li>
|
||||
* <li>如果字段为isName,匹配setName</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* 需要注意的是,以下两种格式不匹配,由{@link #findGetterAndSetter(String, Class, Method[], boolean)}完成:
|
||||
* <ul>
|
||||
* <li>如果字段为name, 匹配setName</li>
|
||||
* <li>如果字段为isName, 匹配setIsName</li>
|
||||
* </ul>
|
||||
*
|
||||
* <pre>
|
||||
* 字段名 -》 方法名
|
||||
* isName -》 setName
|
||||
* isName -》 setIsName
|
||||
* name -》 setName
|
||||
* </pre>
|
||||
*
|
||||
* @param methodName 方法名
|
||||
* @param fieldName 字段名
|
||||
* @param isBooleanField 是否为Boolean类型字段
|
||||
* @param ignoreCase 匹配是否忽略大小写
|
||||
* @return 是否匹配
|
||||
* @param fieldName 字段名
|
||||
* @param gettersOrSetters 所有方法
|
||||
* @param ignoreCase 是否忽略大小写
|
||||
* @return 查找到的方法,{@code null}表示未找到
|
||||
*/
|
||||
private boolean isMatchSetter(String methodName, String fieldName, final boolean isBooleanField, final boolean ignoreCase) {
|
||||
final String handledFieldName;
|
||||
if (ignoreCase) {
|
||||
// 全部转为小写,忽略大小写比较
|
||||
methodName = methodName.toLowerCase();
|
||||
handledFieldName = fieldName.toLowerCase();
|
||||
fieldName = handledFieldName;
|
||||
} else {
|
||||
handledFieldName = StrUtil.upperFirst(fieldName);
|
||||
}
|
||||
|
||||
// 非标准Setter方法跳过
|
||||
if (!methodName.startsWith("set")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 针对Boolean类型特殊检查
|
||||
if (isBooleanField && fieldName.startsWith("is")) {
|
||||
// 字段是is开头
|
||||
if (("set" + StrUtil.removePrefix(fieldName, "is")).equals(methodName)// isName -》 setName
|
||||
|| ("set" + handledFieldName).equals(methodName)// isName -》 setIsName
|
||||
) {
|
||||
return true;
|
||||
private Method findSetterForBoolean(final String fieldName, final Method[] gettersOrSetters, final boolean ignoreCase) {
|
||||
// 查找isXXX
|
||||
return ArrayUtil.get(gettersOrSetters, m -> {
|
||||
if (1 != m.getParameterCount() || false == BooleanUtil.isBoolean(m.getParameterTypes()[0])) {
|
||||
// setter方法要求1个boolean或Boolean参数
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 包括boolean的任何类型只有一种匹配情况:name -》 setName
|
||||
return ("set" + handledFieldName).equals(methodName);
|
||||
if (StrUtil.startWith(fieldName, "is", ignoreCase)) {
|
||||
// isName -》 setName
|
||||
return StrUtil.equals(
|
||||
"set" + StrUtil.removePrefix(fieldName, "is", ignoreCase),
|
||||
m.getName(), ignoreCase);
|
||||
}
|
||||
|
||||
// 其它不匹配
|
||||
return false;
|
||||
});
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------------ Private method end
|
||||
}
|
||||
|
@@ -1113,18 +1113,10 @@ public class CharSequenceUtil extends StrValidator {
|
||||
*
|
||||
* @param str 字符串
|
||||
* @param prefix 前缀
|
||||
* @return 切掉后的字符串,若前缀不是 preffix, 返回原字符串
|
||||
* @return 切掉后的字符串,若前缀不是 prefix, 返回原字符串
|
||||
*/
|
||||
public static String removePrefix(final CharSequence str, final CharSequence prefix) {
|
||||
if (isEmpty(str) || isEmpty(prefix)) {
|
||||
return str(str);
|
||||
}
|
||||
|
||||
final String str2 = str.toString();
|
||||
if (str2.startsWith(prefix.toString())) {
|
||||
return subSuf(str2, prefix.length());// 截取后半段
|
||||
}
|
||||
return str2;
|
||||
return removePrefix(str, prefix, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1135,12 +1127,24 @@ public class CharSequenceUtil extends StrValidator {
|
||||
* @return 切掉后的字符串,若前缀不是 prefix, 返回原字符串
|
||||
*/
|
||||
public static String removePrefixIgnoreCase(final CharSequence str, final CharSequence prefix) {
|
||||
return removePrefix(str, prefix, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 去掉指定前缀
|
||||
*
|
||||
* @param str 字符串
|
||||
* @param prefix 前缀
|
||||
* @param ignoreCase 是否忽略大小写
|
||||
* @return 切掉后的字符串,若前缀不是 prefix, 返回原字符串
|
||||
*/
|
||||
public static String removePrefix(final CharSequence str, final CharSequence prefix, final boolean ignoreCase) {
|
||||
if (isEmpty(str) || isEmpty(prefix)) {
|
||||
return str(str);
|
||||
}
|
||||
|
||||
final String str2 = str.toString();
|
||||
if (startWithIgnoreCase(str, prefix)) {
|
||||
if (startWith(str, prefix, ignoreCase)) {
|
||||
return subSuf(str2, prefix.length());// 截取后半段
|
||||
}
|
||||
return str2;
|
||||
|
Reference in New Issue
Block a user