diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaUtil.java b/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaUtil.java
index c57a41f47..cfec37eea 100644
--- a/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaUtil.java
@@ -2,7 +2,11 @@ package cn.hutool.core.lang.func;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.SimpleCache;
+import cn.hutool.core.text.CharPool;
+import cn.hutool.core.text.StrPool;
+import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ReflectUtil;
+import cn.hutool.core.util.StrUtil;
import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
@@ -53,6 +57,18 @@ public class LambdaUtil {
return resolve(func).getImplMethodName();
}
+ /**
+ * 获取lambda实现类
+ *
+ * @param func lambda
+ * @param
类型
+ * @return lambda实现类
+ */
+ public static
Class
getInstantiatedClass(Func1
func) {
+ String instantiatedMethodType = resolve(func).getInstantiatedMethodType();
+ return ClassUtil.loadClass(StrUtil.replace(StrUtil.sub(instantiatedMethodType, 2, StrUtil.indexOf(instantiatedMethodType, ';')), StrPool.SLASH, StrPool.DOT));
+ }
+
/**
* 获取lambda表达式函数(方法)名称
*
@@ -65,6 +81,17 @@ public class LambdaUtil {
return resolve(func).getImplMethodName();
}
+ /**
+ * 获取lambda实现类
+ *
+ * @param func lambda
+ * @param 类型
+ * @return lambda实现类
+ */
+ public static Class getImplClass(Func0> func) {
+ return ClassUtil.loadClass(resolve(func).getImplClass().replace(CharPool.SLASH, CharPool.DOT));
+ }
+
/**
* 获取lambda表达式Getter或Setter函数(方法)对应的字段名称,规则如下:
*
diff --git a/hutool-core/src/main/java/cn/hutool/core/map/MapUtil.java b/hutool-core/src/main/java/cn/hutool/core/map/MapUtil.java
index 63b8c02b7..9cfee1744 100644
--- a/hutool-core/src/main/java/cn/hutool/core/map/MapUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/map/MapUtil.java
@@ -27,6 +27,8 @@ import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+import java.util.function.BiFunction;
/**
* Map相关工具类
@@ -548,7 +550,7 @@ public class MapUtil {
* @since 5.0.4
*/
public static String sortJoin(Map, ?> params, String separator, String keyValueSeparator, boolean isIgnoreNull,
- String... otherParams) {
+ String... otherParams) {
return join(sort(params), separator, keyValueSeparator, isIgnoreNull, otherParams);
}
@@ -668,6 +670,25 @@ public class MapUtil {
return edit(map, t -> filter.accept(t) ? t : null);
}
+
+ /**
+ * 变更
+ * 变更过程通过传入的 {@link BiFunction} 实现来返回一个值可以为不同类型的 {@link Map}
+ *
+ * @param map 原有的map
+ * @param biFunction {@code lambda},参数包含{@code key},{@code value},返回值会作为新的{@code value}
+ * @param {@code key}的类型
+ * @param {@code value}的类型
+ * @param 新的,修改后的{@code value}的类型
+ * @return 值可以为不同类型的 {@link Map}
+ */
+ public static Map change(Map map, BiFunction biFunction) {
+ if (null == map || null == biFunction) {
+ return MapUtil.newHashMap();
+ }
+ return map.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, m -> biFunction.apply(m.getKey(), m.getValue())));
+ }
+
/**
* 过滤Map保留指定键值对,如果键不存在跳过
*
diff --git a/hutool-core/src/main/java/cn/hutool/core/util/EnumUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/EnumUtil.java
index 4a1365d9e..b7adbe0f1 100644
--- a/hutool-core/src/main/java/cn/hutool/core/util/EnumUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/util/EnumUtil.java
@@ -1,13 +1,13 @@
package cn.hutool.core.util;
import cn.hutool.core.lang.Assert;
+import cn.hutool.core.lang.func.Func1;
+import cn.hutool.core.lang.func.LambdaUtil;
import cn.hutool.core.map.MapUtil;
import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.function.Function;
/**
* 枚举工具类
@@ -210,6 +210,35 @@ public class EnumUtil {
return names;
}
+
+ /**
+ * 通过 某字段对应值 获取 枚举,获取不到时为 {@code null}
+ *
+ * @param condition 条件字段
+ * @param value 条件字段值
+ * @param 枚举类型
+ * @param 字段类型
+ * @return 对应枚举 ,获取不到时为 {@code null}
+ */
+ public static , C> E getBy(Func1 condition, C value) {
+ return Arrays.stream(LambdaUtil.getInstantiatedClass(condition).getEnumConstants()).filter(e -> condition.callWithRuntimeException(e).equals(value)).findAny().orElse(null);
+ }
+
+ /**
+ * 通过 某字段对应值 获取 枚举中另一字段值,获取不到时为 {@code null}
+ *
+ * @param field 你想要获取的字段
+ * @param condition 条件字段
+ * @param value 条件字段值
+ * @param 枚举类型
+ * @param 想要获取的字段类型
+ * @param 条件字段类型
+ * @return 对应枚举中另一字段值 ,获取不到时为 {@code null}
+ */
+ public static , F, C> F getFieldBy(Function field, Func1 condition, C value) {
+ return Arrays.stream(LambdaUtil.getInstantiatedClass(condition).getEnumConstants()).filter(e -> condition.callWithRuntimeException(e).equals(value)).findAny().map(field).orElse(null);
+ }
+
/**
* 获取枚举字符串值和枚举对象的Map对应,使用LinkedHashMap保证有序
* 结果中键为枚举名,值为枚举对象
diff --git a/hutool-core/src/test/java/cn/hutool/core/lang/func/LambdaUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/lang/func/LambdaUtilTest.java
index b74a30a20..d78f385ee 100644
--- a/hutool-core/src/test/java/cn/hutool/core/lang/func/LambdaUtilTest.java
+++ b/hutool-core/src/test/java/cn/hutool/core/lang/func/LambdaUtilTest.java
@@ -1,25 +1,39 @@
package cn.hutool.core.lang.func;
-import lombok.Data;
import org.junit.Assert;
import org.junit.Test;
+import lombok.Data;
+
public class LambdaUtilTest {
@Test
- public void getMethodNameTest(){
+ public void getMethodNameTest() {
String methodName = LambdaUtil.getMethodName(MyTeacher::getAge);
Assert.assertEquals("getAge", methodName);
}
@Test
- public void getFieldNameTest(){
+ public void getFieldNameTest() {
String fieldName = LambdaUtil.getFieldName(MyTeacher::getAge);
Assert.assertEquals("age", fieldName);
}
+ @Test
+ public void getImplClassTest() {
+ // 一般用于封装工具类时减少参数使用
+ Class aClass = LambdaUtil.getInstantiatedClass(MyTeacher::getAge);
+ Assert.assertEquals(MyTeacher.class, aClass);
+
+ // 一般用于封装工具类时减少参数使用
+ MyTeacher myTeacher = new MyTeacher();
+ Class bClass = LambdaUtil.getImplClass(myTeacher::getAge);
+ Assert.assertEquals(MyTeacher.class, bClass);
+ }
+
@Data
- static class MyTeacher{
+ static class MyTeacher {
+
public String age;
}
}
diff --git a/hutool-core/src/test/java/cn/hutool/core/map/MapUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/map/MapUtilTest.java
index ed47980fe..58ce564a1 100644
--- a/hutool-core/src/test/java/cn/hutool/core/map/MapUtilTest.java
+++ b/hutool-core/src/test/java/cn/hutool/core/map/MapUtilTest.java
@@ -1,15 +1,44 @@
package cn.hutool.core.map;
import cn.hutool.core.convert.Convert;
+import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.StrUtil;
+import lombok.Builder;
+import lombok.Data;
import org.junit.Assert;
import org.junit.Test;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
public class MapUtilTest {
+ enum PeopleEnum {GIRL, BOY, CHILD}
+
+ @Data
+ @Builder
+ public static class User {
+ private Long id;
+ private String name;
+ }
+
+ @Data
+ @Builder
+ public static class Group {
+ private Long id;
+ private List users;
+ }
+
+ @Data
+ @Builder
+ public static class UserGroup {
+ private Long userId;
+ private Long groupId;
+ }
+
+
@Test
public void filterTest() {
Map map = MapUtil.newHashMap();
@@ -26,6 +55,47 @@ public class MapUtilTest {
Assert.assertEquals("4", map2.get("d"));
}
+ @Test
+ public void changeTest() {
+ // Add test like a foreigner
+ Map adjectivesMap = MapUtil.builder()
+ .put(0, "lovely")
+ .put(1, "friendly")
+ .put(2, "happily")
+ .build();
+
+ Map resultMap = MapUtil.change(adjectivesMap, (k, v) -> v + " " + PeopleEnum.values()[k].name().toLowerCase());
+
+ Assert.assertEquals("lovely girl", resultMap.get(0));
+ Assert.assertEquals("friendly boy", resultMap.get(1));
+ Assert.assertEquals("happily child", resultMap.get(2));
+
+ // 下单用户,Queue表示正在 .排队. 抢我抢不到的二次元周边!
+ Queue customers = new ArrayDeque<>(Arrays.asList("刑部尚书手工耿", "木瓜大盗大漠叔", "竹鼠发烧找华农", "朴实无华朱一旦"));
+ // 分组
+ List groups = Stream.iterate(0L, i -> ++i).limit(4).map(i -> Group.builder().id(i).build()).collect(Collectors.toList());
+ // 如你所见,它是一个map,key由用户id,value由用户组成
+ Map idUserMap = Stream.iterate(0L, i -> ++i).limit(4).map(i -> User.builder().id(i).name(customers.poll()).build()).collect(Collectors.toMap(User::getId, Function.identity()));
+ // 如你所见,它是一个map,key由分组id,value由用户ids组成,典型的多对多关系
+ Map> groupIdUserIdsMap = groups.stream().flatMap(group -> idUserMap.keySet().stream().map(userId -> UserGroup.builder().groupId(group.getId()).userId(userId).build())).collect(Collectors.groupingBy(UserGroup::getUserId, Collectors.mapping(UserGroup::getGroupId, Collectors.toList())));
+
+ // 神奇的魔法发生了, 分组id和用户ids组成的map,竟然变成了订单编号和用户实体集合组成的map
+ Map> groupIdUserMap = MapUtil.change(groupIdUserIdsMap, (groupId, userIds) -> userIds.stream().map(idUserMap::get).collect(Collectors.toList()));
+
+ // 然后你就可以拿着这个map,去封装groups,使其能够在订单数据带出客户信息啦
+ groups.forEach(group -> Opt.ofNullable(group.getId()).map(groupIdUserMap::get).ifPresent(group::setUsers));
+
+ // 下面是测试报告
+ groups.forEach(group -> {
+ List users = group.getUsers();
+ Assert.assertEquals("刑部尚书手工耿", users.get(0).getName());
+ Assert.assertEquals("木瓜大盗大漠叔", users.get(1).getName());
+ Assert.assertEquals("竹鼠发烧找华农", users.get(2).getName());
+ Assert.assertEquals("朴实无华朱一旦", users.get(3).getName());
+ });
+ // 能写代码真开心
+ }
+
@Test
public void filterMapWrapperTest() {
Map map = MapUtil.newHashMap();
diff --git a/hutool-core/src/test/java/cn/hutool/core/util/EnumUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/EnumUtilTest.java
index 555d8f644..d95d2d963 100644
--- a/hutool-core/src/test/java/cn/hutool/core/util/EnumUtilTest.java
+++ b/hutool-core/src/test/java/cn/hutool/core/util/EnumUtilTest.java
@@ -9,7 +9,7 @@ import java.util.Map;
/**
* EnumUtil单元测试
- *
+ *
* @author looly
*
*/
@@ -20,39 +20,53 @@ public class EnumUtilTest {
List names = EnumUtil.getNames(TestEnum.class);
Assert.assertEquals(CollUtil.newArrayList("TEST1", "TEST2", "TEST3"), names);
}
-
+
@Test
public void getFieldValuesTest() {
List