登录
注册
开源
企业版
高校版
搜索
帮助中心
使用条款
关于我们
开源
企业版
高校版
私有云
模力方舟
登录
注册
代码拉取完成,页面将自动刷新
开源项目
>
程序开发
>
常用工具包
&&
捐赠
捐赠前请先登录
取消
前往登录
扫描微信二维码支付
取消
支付完成
支付提示
将跳转至支付宝完成支付
确定
取消
Watch
不关注
关注所有动态
仅关注版本发行动态
关注但不提醒动态
4K
Star
24.1K
Fork
8.2K
GVP
chinabugotech
/
hutool
代码
Issues
3
Pull Requests
0
统计
流水线
服务
JavaDoc
质量分析
Jenkins for Gitee
腾讯云托管
腾讯云 Serverless
悬镜安全
阿里云 SAE
Codeblitz
SBOM
我知道了,不再自动展开
583
MapUtil提供change函数,EnumUtil提供getBy函数,通过lambda进行枚举字段映射
已合并
阿超:v5-dev
chinabugotech:v5-dev
阿超
创建于 2022-03-23 23:00
克隆/下载
HTTPS
SSH
复制
下载 Email Patch
下载 Diff 文件
## This is a story about pull request ### getFieldBy 我们在使用枚举的过程中,经常会遇到字段相互之间映射的场景: 例如此处我编写一个`GenderEnum` ```java @Getter @AllArgsConstructor public enum GenderEnum { /** * 性别枚举 */ FEMALE("男"), MALE("女"), UNKNOWN("未知"); private final String desc; } ``` 然后对其进行使用,我们前端传入可能是`0/1/2`这样的数字,我们就可以通过`EnumUtil#getFieldBy`,来通过`ordinal`,也就是我们枚举的序号,获取对应的汉字返回 ```java // 获取desc 通过ordinal 值为0 String desc = EnumUtil.getFieldBy(GenderEnum::getDesc, GenderEnum::ordinal, 0); Assert.assertEquals("男", desc); ``` 有木有体会到[声明式编程](https://baike.baidu.com/item/%E5%A3%B0%E6%98%8E%E5%BC%8F%E7%BC%96%E7%A8%8B/9939512)的好处?就像我们写`sql`一样,很流利顺畅的就写出来了这样优雅的代码 如果还有小伙伴不熟悉`lambda`,赶紧[戳这里](https://www.hutool.cn/docs/#/core/JavaBean/%E7%A9%BA%E6%A3%80%E6%9F%A5%E5%B1%9E%E6%80%A7%E8%8E%B7%E5%8F%96-Opt)来学习!开启声明式编程的时代! ### getBy 这时候有朋友就要问了,阿超那你这个`EnumUtil.getBy`不是多余的吗?容我娓娓道来 我们如果遇到了这种场景: 需要根据枚举对应值执行不同的逻辑:此处用一个`switch case`举个栗子: (`jdk8`开始允许枚举作为`switch case`的条件) ```java GenderEnum genderEnum = EnumUtil.getBy(GenderEnum::ordinal, RandomUtil.randomInt(0, 3)); if (genderEnum == null) { return; } switch (genderEnum) { case FEMALE: Console.log("这是一位帅帅的小哥哥"); break; case MALE: Console.log("这是一位美美的小姐姐"); break; case UNKNOWN: Console.log("这位更是重量级,Ta不愿意透露性别"); break; default: break; } ``` > 让我们一起减少遍布在项目各处的魔法值吧! :v: 大家用枚举去管理,也能方便统一修改和厘清逻辑 ### `MapUtil#change` 这里简单介绍一个基本使用和一个复杂场景: ```java // Add test like a foreigner Map<Integer, String> adjectivesMap = MapUtil.<Integer, String>builder() .put(0, "lovely") .put(1, "friendly") .put(2, "happily") .build(); Map<Integer, String> 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)); ``` 复杂场景: ```java // 下单用户,Queue表示正在 .排队. 抢我抢不到的二次元周边! Queue<String> customers = new ArrayDeque<>(Arrays.asList("刑部尚书手工耿", "木瓜大盗大漠叔", "竹鼠发烧找华农", "朴实无华朱一旦")); // 分组 List<Group> groups = Stream.iterate(0L, i -> ++i).limit(4).map(i -> Group.builder().id(i).build()).collect(Collectors.toList()); // 如你所见,它是一个map,key由用户id,value由用户组成 Map<Long, User> 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<Long, List<Long>> 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<Long, List<User>> 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<User> 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()); }); // 能写代码真开心 ``` 用到的一些自定义的类 ```java 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<User> users; } @Data @Builder public static class UserGroup { private Long userId; private Long groupId; } ```
怎样手动合并此 Pull Request
git checkout v5-dev
git pull https://gitee.com/VampireAchao/hutool.git v5-dev
git push origin v5-dev
评论
4
提交
3
文件
6
检查
代码问题
0
批量操作
展开设置
折叠设置
审查
Code Owner
审查人员
eli_chow
eli-chow
chinabugotech
chinabugotech
Looly
loolly_admin
未设置
最少人数
0
测试
eli_chow
eli-chow
chinabugotech
chinabugotech
Looly
loolly_admin
未设置
最少人数
0
优先级
不指定
严重
主要
次要
不重要
标签
标签管理
未设置
关联 Issue
未关联
Pull Request 合并后将关闭上述关联 Issue
里程碑
未关联里程碑
参与者
(2)
Cherry-pick 提交
Cherry-pick 可以将
特定提交(Commit)
从某个分支挑选并应用到另一个分支,实现快速集成特定更改,而无需合并整个分支。
请选择应用 Cherry-pick 提交 (Commit) 的目标分支
新建分支
当前账号不存在 Fork 仓库,建议 cherry-pick 到 Fork 仓库。
Fork 仓库
提交列表
Commit SHA
Commit Message
基于 Cherry-pick 后的分支发起 Pull Request
取消
Cherry-pick
Java
1
https://gitee.com/chinabugotech/hutool.git
git@gitee.com:chinabugotech/hutool.git
chinabugotech
hutool
hutool
点此查找更多帮助
搜索帮助
Git 命令在线学习
如何在 Gitee 导入 GitHub 仓库
Git 仓库基础操作
企业版和社区版功能对比
SSH 公钥设置
如何处理代码冲突
仓库体积过大,如何减小?
如何找回被删除的仓库数据
Gitee 产品配额说明
GitHub仓库快速导入Gitee及同步更新
什么是 Release(发行版)
将 PHP 项目自动发布到 packagist.org
评论
仓库举报
回到顶部
登录提示
该操作需登录 Gitee 帐号,请先登录后再操作。
立即登录
没有帐号,去注册