add method

This commit is contained in:
Looly 2022-03-16 22:33:33 +08:00
parent e00f4ccf86
commit 5fdabe844e
6 changed files with 88 additions and 37 deletions

View File

@ -17,6 +17,7 @@
* 【db 】 增加MongoDB4.x支持pr#568@Gitee * 【db 】 增加MongoDB4.x支持pr#568@Gitee
* 【core 】 FileAppender优化初始List大小pr#2197@Github * 【core 】 FileAppender优化初始List大小pr#2197@Github
* 【core 】 Base32增加pad支持pr#2195@Github * 【core 】 Base32增加pad支持pr#2195@Github
* 【core 】 Dict增加setFields方法pr#578@Gitee
* *
### 🐞Bug修复 ### 🐞Bug修复
* 【core 】 修复ObjectUtil.hasNull传入null返回true的问题pr#555@Gitee * 【core 】 修复ObjectUtil.hasNull传入null返回true的问题pr#555@Gitee

View File

@ -915,4 +915,27 @@ public class BeanUtil {
return false; return false;
} }
/**
* 获取Getter或Setter方法名对应的字段名称规则如下
* <ul>
* <li>getXxxx获取为xxxx如getName得到name</li>
* <li>setXxxx获取为xxxx如setName得到name</li>
* <li>isXxxx获取为xxxx如isName得到name</li>
* <li>其它不满足规则的方法名抛出{@link IllegalArgumentException}</li>
* </ul>
*
* @param getterOrSetterName Getter或Setter方法名
* @return 字段名称
* @throws IllegalArgumentException 非Getter或Setter方法
* @since 5.7.23
*/
public static String getFieldName(String getterOrSetterName) {
if (getterOrSetterName.startsWith("get") || getterOrSetterName.startsWith("set")) {
return StrUtil.removePreAndLowerFirst(getterOrSetterName, 3);
} else if (getterOrSetterName.startsWith("is")) {
return StrUtil.removePreAndLowerFirst(getterOrSetterName, 2);
} else {
throw new IllegalArgumentException("Invalid Getter or Setter name: " + getterOrSetterName);
}
}
} }

View File

@ -5,6 +5,8 @@ import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.getter.BasicTypeGetter; import cn.hutool.core.getter.BasicTypeGetter;
import cn.hutool.core.lang.func.Func0;
import cn.hutool.core.lang.func.LambdaUtil;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
@ -17,8 +19,6 @@ import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import cn.hutool.core.lang.func.Func0;
import cn.hutool.core.lang.func.LambdaUtil;
/** /**
* 字典对象扩充了HashMap中的方法 * 字典对象扩充了HashMap中的方法
@ -526,7 +526,7 @@ public class Dict extends LinkedHashMap<String, Object> implements BasicTypeGett
* person.friends[5].name * person.friends[5].name
* </pre> * </pre>
* *
* @param <T> 目标类型 * @param <T> 目标类型
* @param expression 表达式 * @param expression 表达式
* @return 对象 * @return 对象
* @see BeanPath#get(Object) * @see BeanPath#get(Object)
@ -601,9 +601,16 @@ public class Dict extends LinkedHashMap<String, Object> implements BasicTypeGett
} }
/** /**
* 通过lambda批量设置值 * 通过lambda批量设置值<br>
* 实际使用时可以使用getXXX的方法引用来完成键值对的赋值
* <pre>
* User user = GenericBuilder.of(User::new).with(User::setUsername, "hutool").build();
* Dict.create().setFields(user::getNickname, user::getUsername);
* </pre>
*
* @param fields lambda,不能为空 * @param fields lambda,不能为空
* @return this * @return this
* @since 5.7.23
*/ */
public Dict setFields(Func0<?>... fields) { public Dict setFields(Func0<?>... fields) {
Arrays.stream(fields).forEach(f -> set(LambdaUtil.getFieldName(f), f.callWithRuntimeException())); Arrays.stream(fields).forEach(f -> set(LambdaUtil.getFieldName(f), f.callWithRuntimeException()));

View File

@ -1,8 +1,8 @@
package cn.hutool.core.lang.func; package cn.hutool.core.lang.func;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.SimpleCache; import cn.hutool.core.lang.SimpleCache;
import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import java.io.Serializable; import java.io.Serializable;
import java.lang.invoke.SerializedLambda; import java.lang.invoke.SerializedLambda;
@ -29,6 +29,15 @@ public class LambdaUtil {
return _resolve(func); return _resolve(func);
} }
/**
* 解析lambda表达式,加了缓存
* 该缓存可能会在任意不定的时间被清除
*
* @param <R> Lambda返回类型
* @param func 需要解析的 lambda 对象无参方法
* @return 返回解析后的结果
* @since 5.7.23
*/
public static <R> SerializedLambda resolve(Func0<R> func) { public static <R> SerializedLambda resolve(Func0<R> func) {
return _resolve(func); return _resolve(func);
} }
@ -36,14 +45,22 @@ public class LambdaUtil {
/** /**
* 获取lambda表达式函数方法名称 * 获取lambda表达式函数方法名称
* *
* @param <T> Lambda类型 * @param <P> Lambda参数类型
* @param func 函数无参方法 * @param func 函数无参方法
* @return 函数名称 * @return 函数名称
*/ */
public static <T> String getMethodName(Func1<T, ?> func) { public static <P> String getMethodName(Func1<P, ?> func) {
return resolve(func).getImplMethodName(); return resolve(func).getImplMethodName();
} }
/**
* 获取lambda表达式函数方法名称
*
* @param <R> Lambda返回类型
* @param func 函数无参方法
* @return 函数名称
* @since 5.7.23
*/
public static <R> String getMethodName(Func0<R> func) { public static <R> String getMethodName(Func0<R> func) {
return resolve(func).getImplMethodName(); return resolve(func).getImplMethodName();
} }
@ -59,30 +76,31 @@ public class LambdaUtil {
* *
* @param <T> Lambda类型 * @param <T> Lambda类型
* @param func 函数无参方法 * @param func 函数无参方法
* @return 函数名称 * @return 方法名称
* @throws IllegalArgumentException 非Getter或Setter方法 * @throws IllegalArgumentException 非Getter或Setter方法
* @since 5.7.10 * @since 5.7.10
*/ */
public static <T> String getFieldName(Func1<T, ?> func) throws IllegalArgumentException { public static <T> String getFieldName(Func1<T, ?> func) throws IllegalArgumentException {
final String methodName = getMethodName(func); return BeanUtil.getFieldName(getMethodName(func));
if (methodName.startsWith("get") || methodName.startsWith("set")) {
return StrUtil.removePreAndLowerFirst(methodName, 3);
} else if (methodName.startsWith("is")) {
return StrUtil.removePreAndLowerFirst(methodName, 2);
} else {
throw new IllegalArgumentException("Invalid Getter or Setter name: " + methodName);
}
} }
public static <R> String getFieldName(Func0<R> func) throws IllegalArgumentException { /**
final String methodName = getMethodName(func); * 获取lambda表达式Getter或Setter函数方法对应的字段名称规则如下
if (methodName.startsWith("get") || methodName.startsWith("set")) { * <ul>
return StrUtil.removePreAndLowerFirst(methodName, 3); * <li>getXxxx获取为xxxx如getName得到name</li>
} else if (methodName.startsWith("is")) { * <li>setXxxx获取为xxxx如setName得到name</li>
return StrUtil.removePreAndLowerFirst(methodName, 2); * <li>isXxxx获取为xxxx如isName得到name</li>
} else { * <li>其它不满足规则的方法名抛出{@link IllegalArgumentException}</li>
throw new IllegalArgumentException("Invalid Getter or Setter name: " + methodName); * </ul>
} *
* @param <T> Lambda类型
* @param func 函数无参方法
* @return 方法名称
* @throws IllegalArgumentException 非Getter或Setter方法
* @since 5.7.23
*/
public static <T> String getFieldName(Func0<T> func) throws IllegalArgumentException {
return BeanUtil.getFieldName(getMethodName(func));
} }
/** /**

View File

@ -281,8 +281,8 @@ public class MapUtil {
/** /**
* 根据给定的Pair数组创建Map对象 * 根据给定的Pair数组创建Map对象
* *
* @param <K> 键类型 * @param <K> 键类型
* @param <V> 值类型 * @param <V> 值类型
* @param pairs 键值对 * @param pairs 键值对
* @return Map * @return Map
* @since 5.4.1 * @since 5.4.1
@ -629,7 +629,7 @@ public class MapUtil {
} }
Map<K, V> map2 = ReflectUtil.newInstanceIfPossible(map.getClass()); Map<K, V> map2 = ReflectUtil.newInstanceIfPossible(map.getClass());
if(null == map2){ if (null == map2) {
map2 = new HashMap<>(map.size(), 1f); map2 = new HashMap<>(map.size(), 1f);
} }
if (isEmpty(map)) { if (isEmpty(map)) {
@ -662,7 +662,7 @@ public class MapUtil {
* @since 3.1.0 * @since 3.1.0
*/ */
public static <K, V> Map<K, V> filter(Map<K, V> map, Filter<Entry<K, V>> filter) { public static <K, V> Map<K, V> filter(Map<K, V> map, Filter<Entry<K, V>> filter) {
if(null == map || null == filter){ if (null == map || null == filter) {
return map; return map;
} }
return edit(map, t -> filter.accept(t) ? t : null); return edit(map, t -> filter.accept(t) ? t : null);
@ -680,12 +680,12 @@ public class MapUtil {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <K, V> Map<K, V> filter(Map<K, V> map, K... keys) { public static <K, V> Map<K, V> filter(Map<K, V> map, K... keys) {
if(null == map || null == keys){ if (null == map || null == keys) {
return map; return map;
} }
Map<K, V> map2 = ReflectUtil.newInstanceIfPossible(map.getClass()); Map<K, V> map2 = ReflectUtil.newInstanceIfPossible(map.getClass());
if(null == map2){ if (null == map2) {
map2 = new HashMap<>(map.size(), 1f); map2 = new HashMap<>(map.size(), 1f);
} }
if (isEmpty(map)) { if (isEmpty(map)) {
@ -792,9 +792,9 @@ public class MapUtil {
/** /**
* 按照值排序可选是否倒序 * 按照值排序可选是否倒序
* *
* @param map 需要对值排序的map * @param map 需要对值排序的map
* @param <K> 键类型 * @param <K> 键类型
* @param <V> 值类型 * @param <V> 值类型
* @param isDesc 是否倒序 * @param isDesc 是否倒序
* @return 排序后新的Map * @return 排序后新的Map
* @since 5.5.8 * @since 5.5.8
@ -802,7 +802,7 @@ public class MapUtil {
public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map, boolean isDesc) { public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map, boolean isDesc) {
Map<K, V> result = new LinkedHashMap<>(); Map<K, V> result = new LinkedHashMap<>();
Comparator<Entry<K, V>> entryComparator = Entry.comparingByValue(); Comparator<Entry<K, V>> entryComparator = Entry.comparingByValue();
if(isDesc){ if (isDesc) {
entryComparator = entryComparator.reversed(); entryComparator = entryComparator.reversed();
} }
map.entrySet().stream().sorted(entryComparator).forEachOrdered(e -> result.put(e.getKey(), e.getValue())); map.entrySet().stream().sorted(entryComparator).forEachOrdered(e -> result.put(e.getKey(), e.getValue()));

View File

@ -1,13 +1,15 @@
package cn.hutool.core.lang; package cn.hutool.core.lang;
import cn.hutool.core.builder.GenericBuilder;
import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateTime;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import static cn.hutool.core.lang.OptTest.User;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import static cn.hutool.core.lang.OptTest.User;
public class DictTest { public class DictTest {
@Test @Test
public void dictTest(){ public void dictTest(){
@ -62,7 +64,7 @@ public class DictTest {
@Test @Test
public void setFieldsTest() { public void setFieldsTest() {
User user = User.builder().username("hutool").nickname(null).build(); User user = GenericBuilder.of(User::new).with(User::setUsername, "hutool").build();
Dict dict = Dict.create(); Dict dict = Dict.create();
dict.setFields(user::getNickname, user::getUsername); dict.setFields(user::getNickname, user::getUsername);
Assert.assertEquals("hutool", dict.get("username")); Assert.assertEquals("hutool", dict.get("username"));