HuToolAPI · Redis详解
Hutool 常用 API 及应用实例
适合 Java 后端开发日常使用的 Hutool 高频工具速查。 侧重:会用、常用、能快速落地。
1. 先说结论:最值得优先掌握的 12 组 API
- StrUtil:字符串判空、格式化、截取、前后缀处理
- ObjectUtil / ObjUtil:对象判空、默认值、相等判断
- CollUtil / ListUtil / MapUtil:集合判空、构建、拆分、工具操作
- Convert:万能类型转换
- DateUtil:日期解析、格式化、偏移、区间判断
- BeanUtil:Bean 拷贝、Bean 转 Map、Map 转 Bean
- JSONUtil:对象转 JSON、JSON 转对象、取值
- IdUtil:UUID、雪花 ID
- RandomUtil:随机字符串、随机数字
- NumberUtil:金额计算、BigDecimal 运算、格式化
- FileUtil:文件读写、目录操作、后缀名获取
- HttpUtil:快速发 GET/POST 请求
2. Maven 依赖
代码块收起展开
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.44</version>
</dependency>实际项目里,也可以按模块细拆;但学习阶段先用
hutool-all最省心。
3. StrUtil —— 字符串处理高频王者
3.1 判空 / 判空白
代码块收起展开
String name = " ";
boolean r1 = StrUtil.isEmpty(name); // false,只有 null 或 "" 才算 empty
boolean r2 = StrUtil.isBlank(name); // true,空格也算 blank3.2 提供默认值
代码块收起展开
String nickname = null;
String result = StrUtil.blankToDefault(nickname, "游客");
System.out.println(result); // 游客3.3 字符串格式化
代码块收起展开
String sql = StrUtil.format("select * from user where id = {} and status = {}", 1, 0);
System.out.println(sql);输出:
代码块收起展开
select * from user where id = 1 and status = 03.4 去前后缀
代码块收起展开
String fileName = "test.java";
System.out.println(StrUtil.removeSuffix(fileName, ".java")); // test
System.out.println(StrUtil.addPrefixIfNot(fileName, "src/")); // src/test.java3.5 常见使用场景
- controller 参数判空
- DTO 字段兜底
- 日志 / SQL 模板拼接
- 文件名、URL、前后缀处理
4. ObjUtil / ObjectUtil —— 对象工具
新版本文档里已经明确提到:6.x 开始更推荐
ObjUtil,ObjectUtil将移除。
4.1 判空与默认值
代码块收起展开
Integer age = null;
Integer result = ObjUtil.defaultIfNull(age, 18);
System.out.println(result); // 184.2 相等判断
代码块收起展开
String a = null;
String b = null;
System.out.println(ObjUtil.equals(a, b)); // true4.3 是否为空
代码块收起展开
System.out.println(ObjUtil.isNull(null)); // true
System.out.println(ObjUtil.isNotNull("ok")); // true4.4 适用场景
- 避免手写
obj == null ? defaultValue : obj - 空指针兜底
- 安全比较对象
5. CollUtil / ListUtil / MapUtil —— 集合工具
5.1 集合判空
代码块收起展开
List<String> list = new ArrayList<>();
System.out.println(CollUtil.isEmpty(list)); // true5.2 快速创建 List / Map
代码块收起展开
List<String> roles = ListUtil.of("admin", "user", "guest");
Map<String, Object> map = MapUtil.of("id", 1, "name", "Gilbert");5.3 List 分片
代码块收起展开
List<Integer> nums = ListUtil.of(1,2,3,4,5,6,7);
List<List<Integer>> parts = ListUtil.partition(nums, 3);
System.out.println(parts);输出:
代码块收起展开
[[1, 2, 3], [4, 5, 6], [7]]5.4 去重 / 过滤
代码块收起展开
List<Integer> nums = ListUtil.of(1, 2, 2, 3, 3, 3);
List<Integer> distinct = CollUtil.distinct(nums);
System.out.println(distinct); // [1, 2, 3]5.5 场景
- 分页前拆批处理
- 批量插入前切分
- 判空替代
list == null || list.isEmpty()
6. Convert —— 万能类型转换
6.1 基础转换
代码块收起展开
int n = Convert.toInt("123");
long l = Convert.toLong("999999");
boolean b = Convert.toBool("true");6.2 转集合
代码块收起展开
List<Integer> list = Convert.toList(Integer.class, "1", "2", "3");
System.out.println(list); // [1, 2, 3]6.3 指定目标类型
代码块收起展开
User user = Convert.convert(User.class, someMapOrBean);6.4 带默认值
代码块收起展开
int score = Convert.toInt("abc", 0);
System.out.println(score); // 06.5 场景
- 前端参数转数字
- 配置项读取后转目标类型
- Map / Bean / JSON 中间态转换
7. DateUtil —— 日期处理非常顺手
7.1 当前时间
代码块收起展开
Date now = DateUtil.date();
String nowStr = DateUtil.now();
System.out.println(now);
System.out.println(nowStr);7.2 字符串转日期
代码块收起展开
DateTime dt = DateUtil.parse("2026-03-29 20:30:00");
System.out.println(dt);7.3 日期格式化
代码块收起展开
String format = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss");
System.out.println(format);7.4 偏移时间
代码块收起展开
Date tomorrow = DateUtil.tomorrow();
Date nextWeek = DateUtil.offsetDay(new Date(), 7);
Date lastMonth = DateUtil.offsetMonth(new Date(), -1);7.5 计算间隔
代码块收起展开
Date begin = DateUtil.parse("2026-03-01 00:00:00");
Date end = DateUtil.parse("2026-03-29 00:00:00");
long days = DateUtil.betweenDay(begin, end, true);
System.out.println(days); // 287.6 场景
- 登录 token 过期时间计算
- 活动开始 / 结束时间判断
- 报表按天、周、月偏移统计
8. BeanUtil —— Bean 拷贝极高频
假设有两个类:
代码块收起展开
@Data
class User {
private Long id;
private String username;
private String password;
private String nickname;
}
@Data
class UserDTO {
private Long id;
private String username;
private String nickname;
}8.1 Bean 拷贝
代码块收起展开
User user = new User();
user.setId(1L);
user.setUsername("aschenbath");
user.setPassword("123456");
user.setNickname("Gilbert");
UserDTO dto = BeanUtil.copyProperties(user, UserDTO.class);
System.out.println(dto);8.2 拷贝到已有对象
代码块收起展开
UserDTO dto = new UserDTO();
BeanUtil.copyProperties(user, dto);8.3 Bean 转 Map
代码块收起展开
Map<String, Object> map = BeanUtil.beanToMap(user);
System.out.println(map);8.4 Map 转 Bean
代码块收起展开
Map<String, Object> map = new HashMap<>();
map.put("id", 2L);
map.put("username", "leo");
map.put("nickname", "Arwen");
UserDTO dto = BeanUtil.toBean(map, UserDTO.class);
System.out.println(dto);8.5 忽略 null 字段覆盖
代码块收起展开
CopyOptions options = CopyOptions.create().setIgnoreNullValue(true);
BeanUtil.copyProperties(source, target, options);8.6 场景
User -> UserDTO- VO / DTO / DO 相互转换
- 更新对象时忽略 null
9. JSONUtil —— JSON 读写够直接
9.1 对象转 JSON 字符串
代码块收起展开
UserDTO dto = new UserDTO();
dto.setId(1L);
dto.setUsername("aschenbath");
String json = JSONUtil.toJsonStr(dto);
System.out.println(json);9.2 JSON 字符串转对象
代码块收起展开
String json = "{\"id\":1,\"username\":\"aschenbath\",\"nickname\":\"Gilbert\"}";
UserDTO dto = JSONUtil.toBean(json, UserDTO.class);
System.out.println(dto);9.3 JSON 字符串转 JSONObject 取值
代码块收起展开
JSONObject jsonObject = JSONUtil.parseObj(json);
System.out.println(jsonObject.getStr("username")); // aschenbath9.4 场景
- Redis 存对象
- 接口日志打印
- 第三方返回结果解析
10. IdUtil —— ID 生成
10.1 UUID
代码块收起展开
String uuid = IdUtil.randomUUID();
System.out.println(uuid);10.2 简化 UUID
代码块收起展开
String simpleUuid = IdUtil.simpleUUID();
System.out.println(simpleUuid);10.3 雪花算法 ID
代码块收起展开
long id = IdUtil.getSnowflakeNextId();
String strId = IdUtil.getSnowflakeNextIdStr();
System.out.println(id);
System.out.println(strId);10.4 场景
- 订单号
- 业务主键
- 分布式唯一 ID
但要注意:真正生产环境里,ID 方案要和系统架构统一设计,不要只是“能生成”就直接上。
11. RandomUtil —— 随机值生成
11.1 随机整数
代码块收起展开
int n = RandomUtil.randomInt(1, 10);
System.out.println(n);11.2 随机字符串
代码块收起展开
String code = RandomUtil.randomString(6);
System.out.println(code);11.3 随机数字验证码
代码块收起展开
String verifyCode = RandomUtil.randomNumbers(6);
System.out.println(verifyCode);11.4 场景
- 短信 / 邮箱验证码
- 测试数据构造
- 随机文件名 / token 片段
12. NumberUtil —— 金额和数值计算很好用
12.1 避免浮点误差
代码块收起展开
BigDecimal result = NumberUtil.add(0.1, 0.2);
System.out.println(result); // 0.312.2 金额计算
代码块收起展开
BigDecimal total = NumberUtil.mul(199.9, 3);
BigDecimal discount = NumberUtil.sub(total, 50);
System.out.println(discount);12.3 保留小数
代码块收起展开
String s = NumberUtil.decimalFormat("0.00", 12.3456);
System.out.println(s); // 12.3512.4 判断数字
代码块收起展开
System.out.println(NumberUtil.isNumber("123")); // true
System.out.println(NumberUtil.isNumber("12a")); // false12.5 场景
- 电商金额计算
- 财务统计
- 价格格式化
13. FileUtil —— 文件操作省很多事
13.1 读取文件内容
代码块收起展开
String content = FileUtil.readUtf8String("D:/test/a.txt");
System.out.println(content);13.2 写入文件
代码块收起展开
FileUtil.writeUtf8String("hello hutool", "D:/test/b.txt");13.3 判断文件是否存在
代码块收起展开
boolean exists = FileUtil.exist("D:/test/b.txt");
System.out.println(exists);13.4 获取文件后缀
代码块收起展开
String ext = FileUtil.extName("demo.java");
System.out.println(ext); // java13.5 场景
- 导出文本
- 读取配置文件
- 本地缓存数据
14. HttpUtil —— 快速发 HTTP 请求
14.1 GET 请求
代码块收起展开
String result = HttpUtil.get("https://httpbin.org/get");
System.out.println(result);14.2 POST 表单
代码块收起展开
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("username", "aschenbath");
paramMap.put("password", "123456");
String result = HttpUtil.post("https://httpbin.org/post", paramMap);
System.out.println(result);14.3 自定义请求
代码块收起展开
String body = HttpRequest.post("https://httpbin.org/post")
.header("token", "abc123")
.body("hello")
.timeout(5000)
.execute()
.body();14.4 场景
- 调第三方接口
- 内部服务联调
- 快速写脚本式 HTTP 调用
真实项目里,如果请求复杂、连接池要求更高,通常还是会配合
OkHttp、HttpClient、OpenFeign等方案。
15. SecureUtil —— 加密散列也很常见
15.1 MD5
代码块收起展开
String md5 = SecureUtil.md5("123456");
System.out.println(md5);15.2 SHA-256
代码块收起展开
String sha256 = SecureUtil.sha256("hello");
System.out.println(sha256);15.3 场景
- 文件摘要
- 数据签名预处理
- 简单散列
密码存储别直接裸用 MD5 / SHA;生产里要上带盐和专门密码算法。
16. Assert —— 参数校验很干脆
16.1 非空断言
代码块收起展开
Assert.notNull(user, "用户不能为空");
Assert.notBlank(username, "用户名不能为空");16.2 条件断言
代码块收起展开
Assert.isTrue(age >= 18, "年龄必须大于等于18岁");16.3 场景
- service 入参校验
- 防御式编程
- 替代部分重复 if 判断
17. Console —— 调试打印很爽
代码块收起展开
Console.log("用户名:{}", "aschenbath");
Console.error("出错了:{}", "参数非法");
Console.table(ListUtil.of(
MapUtil.of("id", 1, "name", "A"),
MapUtil.of("id", 2, "name", "B")
));场景
- 本地小工具调试
- demo 演示输出
- 快速观察中间结果
18. 一个后端项目里的典型组合拳
例子:注册接口
代码块收起展开
public UserDTO register(UserRegisterRequest request) {
Assert.notNull(request, "请求体不能为空");
Assert.notBlank(request.getUsername(), "用户名不能为空");
Assert.notBlank(request.getPassword(), "密码不能为空");
String username = StrUtil.trim(request.getUsername());
String password = request.getPassword();
User user = new User();
user.setId(IdUtil.getSnowflakeNextId());
user.setUsername(username);
user.setPassword(SecureUtil.sha256(password));
user.setCreateTime(DateUtil.date());
// 假设这里执行 save(user)
return BeanUtil.copyProperties(user, UserDTO.class);
}这个例子里同时用了:
Assert:参数校验StrUtil:字符串处理IdUtil:生成主键SecureUtil:密码摘要DateUtil:创建时间BeanUtil:对象转换
这就是 Hutool 最舒服的点:把很多零散小动作收得很顺。
19. 实战建议:哪些该用,哪些别滥用
建议优先用
StrUtilBeanUtilDateUtilConvertCollUtilIdUtilNumberUtil
谨慎使用
HttpUtil:复杂项目里未必是最终方案BeanUtil:字段很多、性能敏感场景别无脑 copyJSONUtil:团队如果统一 Jackson,就别混太多风格
最佳实践
- 把 Hutool 当效率工具,不要当架构核心
- 统一团队风格,避免有人写 JDK 原生、有人全 Hutool、有人又混 Apache Commons
- 核心业务代码要保持可读性,别为了“炫技”把简单逻辑包成很花的工具调用
20. 一页速查表
| 模块 | 高频方法 | 典型用途 |
|---|---|---|
| StrUtil | isBlank / format / removeSuffix | 判空、模板字符串、前后缀处理 |
| ObjUtil | defaultIfNull / equals | 空值兜底、对象比较 |
| CollUtil | isEmpty / distinct | 集合判空、去重 |
| ListUtil | of / partition | 创建 List、分片 |
| MapUtil | of | 快速创建 Map |
| Convert | toInt / toLong / convert | 类型转换 |
| DateUtil | parse / format / offsetDay / betweenDay | 日期解析与计算 |
| BeanUtil | copyProperties / beanToMap / toBean | 对象转换 |
| JSONUtil | toJsonStr / toBean / parseObj | JSON 处理 |
| IdUtil | randomUUID / getSnowflakeNextId | 唯一 ID |
| RandomUtil | randomInt / randomString / randomNumbers | 随机值 |
| NumberUtil | add / sub / mul / decimalFormat | 金额计算 |
| FileUtil | readUtf8String / writeUtf8String / extName | 文件读写 |
| HttpUtil | get / post | HTTP 调用 |
| SecureUtil | md5 / sha256 | 摘要散列 |
| Assert | notNull / notBlank / isTrue | 断言校验 |
21. 适合你当前阶段的学习顺序
如果你是 Java 后端学习中期,建议这个顺序:
StrUtilCollUtil / ListUtil / MapUtilConvertDateUtilBeanUtilJSONUtilIdUtilNumberUtilFileUtilHttpUtilSecureUtil
这个顺序很 practical:
- 前 5 个几乎天天写业务都会碰到
- 后面是接口、工具、项目整合阶段高频出现
22. 最后一句
Hutool 的定位不是“高深框架”,而是:
把 Java 里那些又碎又烦的基础操作,收拾成一把顺手的小刀。
你真正该做的,不是背 API, 而是知道:
- 什么时候该用它提效
- 什么时候应该保持原生和清晰
- 什么时候不能让工具掩盖业务本身
23. 可继续扩展的专题
后续你还可以单独整理成 4 篇笔记:
Hutool 字符串 / 集合 / 转换工具速查Hutool 日期、ID、随机数工具实战Hutool Bean / JSON / 文件操作总结Hutool 在 SpringBoot 项目中的常见用法