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