视频看了几百小时还迷糊?关注我,几分钟让你秒懂!
在日常开发中,你是不是经常写这些代码?
- 手动判空:
if (obj != null && obj.getList() != null && !obj.getList().isEmpty()) - 日期格式化:每次都要
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") - JSON 转换:到处写
JSON.toJSONString()、parseObject() - 集合操作:遍历、过滤、转 Map 写到手软
- 异常处理:try-catch 套 try-catch,代码又臭又长
今天我就分享5 个生产级工具类封装,全部基于Spring Boot + Java 8+,直接复制就能用,大幅提升开发效率!
一、集合工具类:告别 NPE 和冗余遍历
❌ 反例:原始写法
if (userList != null) { for (User user : userList) { if ("ACTIVE".equals(user.getStatus())) { activeIds.add(user.getId()); } } }✅ 封装:CollectionUtils(增强版)
import java.util.*; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; public class CollectionUtils { /** * 安全判空(兼容 null 和 empty) */ public static boolean isEmpty(Collection<?> collection) { return collection == null || collection.isEmpty(); } public static boolean isNotEmpty(Collection<?> collection) { return !isEmpty(collection); } /** * 安全判空 Map */ public static boolean isEmpty(Map<?, ?> map) { return map == null || map.isEmpty(); } /** * 集合转 ID 列表(支持任意属性) */ public static <T, R> List<R> toList(Collection<T> collection, Function<T, R> mapper) { if (isEmpty(collection)) return Collections.emptyList(); return collection.stream().map(mapper).collect(Collectors.toList()); } /** * 集合转 Map(key 不能重复,否则报错) */ public static <T, K> Map<K, T> toMap(Collection<T> collection, Function<T, K> keyMapper) { if (isEmpty(collection)) return Collections.emptyMap(); return collection.stream().collect(Collectors.toMap(keyMapper, t -> t)); } /** * 按条件过滤 */ public static <T> List<T> filter(Collection<T> collection, Predicate<T> predicate) { if (isEmpty(collection)) return Collections.emptyList(); return collection.stream().filter(predicate).collect(Collectors.toList()); } }🚀 使用示例:
// 获取所有活跃用户ID List<Long> activeIds = CollectionUtils.toList( users, User::getId ); // 转成 Map<userId, User> Map<Long, User> userMap = CollectionUtils.toMap(users, User::getId); // 过滤出 VIP 用户 List<User> vips = CollectionUtils.filter(users, u -> "VIP".equals(u.getType()));💡 搭配 Lombok 的
@Data,代码清爽到飞起!
二、JSON 工具类:统一序列化/反序列化
❌ 反例:到处写 JSON 转换
String json = JSON.toJSONString(obj); User user = JSON.parseObject(json, User.class);✅ 封装:JsonUtils(基于 Jackson,兼容 Spring Boot 默认)
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.io.IOException; @Component public class JsonUtils { private static ObjectMapper objectMapper; @Autowired private ObjectMapper springObjectMapper; @PostConstruct public void init() { // 使用 Spring Boot 自动配置的 ObjectMapper,保留全局配置(如时间格式) objectMapper = springObjectMapper; } public static String toJson(Object obj) { try { return objectMapper.writeValueAsString(obj); } catch (JsonProcessingException e) { throw new RuntimeException("JSON 序列化失败", e); } } public static <T> T fromJson(String json, Class<T> clazz) { try { return objectMapper.readValue(json, clazz); } catch (IOException e) { throw new RuntimeException("JSON 反序列化失败", e); } } // 支持泛型(如 List<User>) public static <T> T fromJson(String json, TypeReference<T> typeRef) { try { return objectMapper.readValue(json, typeRef); } catch (IOException e) { throw new RuntimeException("JSON 反序列化失败", e); } } }🚀 使用示例:
// 序列化 String json = JsonUtils.toJson(user); // 反序列化普通对象 User user = JsonUtils.fromJson(json, User.class); // 反序列化泛型 List<User> users = JsonUtils.fromJson(json, new TypeReference<List<User>>() {});⚠️ 注意:不要自己 new ObjectMapper!要用 Spring 注入的,否则会丢失
@JsonFormat等全局配置。
三、日期时间工具类:告别 SimpleDateFormat 线程安全问题
❌ 反例:线程不安全!
private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 多线程下会出错!✅ 封装:DateUtils(基于 Java 8 Time API)
import java.time.*; import java.time.format.DateTimeFormatter; import java.util.Date; public class DateUtils { public static final String DEFAULT_PATTERN = "yyyy-MM-dd HH:mm:ss"; public static final DateTimeFormatter DEFAULT_FORMATTER = DateTimeFormatter.ofPattern(DEFAULT_PATTERN); /** * Date 转 LocalDateTime */ public static LocalDateTime toLocalDateTime(Date date) { return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); } /** * LocalDateTime 转 Date */ public static Date toDate(LocalDateTime localDateTime) { return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()); } /** * 格式化日期(线程安全!) */ public static String format(LocalDateTime dateTime, String pattern) { return dateTime.format(DateTimeFormatter.ofPattern(pattern)); } public static String format(LocalDateTime dateTime) { return dateTime.format(DEFAULT_FORMATTER); } /** * 解析字符串为 LocalDateTime */ public static LocalDateTime parse(String dateStr, String pattern) { return LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern(pattern)); } public static LocalDateTime parse(String dateStr) { return LocalDateTime.parse(dateStr, DEFAULT_FORMATTER); } /** * 获取当天开始时间 */ public static LocalDateTime startOfDay() { return LocalDate.now().atStartOfDay(); } /** * 获取几天后的时间 */ public static LocalDateTime plusDays(long days) { return LocalDateTime.now().plusDays(days); } }🚀 使用示例:
// 安全格式化 String nowStr = DateUtils.format(LocalDateTime.now()); // 解析字符串 LocalDateTime time = DateUtils.parse("2025-04-05 10:30:00"); // 获取明天此时 LocalDateTime tomorrow = DateUtils.plusDays(1);✅ 优势:线程安全 + 无时区陷阱 + 链式调用
四、响应封装工具:统一返回格式
❌ 反例:每个 Controller 都写 ResponseEntity
return ResponseEntity.ok(new Result(true, data));✅ 封装:Result<T>+Results工具类
// 统一响应体 public class Result<T> { private boolean success; private String message; private T data; private int code = 200; // 构造私有化 private Result() {} public static <T> Result<T> success(T data) { Result<T> result = new Result<>(); result.success = true; result.data = data; return result; } public static <T> Result<T> success() { return success(null); } public static <T> Result<T> fail(String message) { Result<T> result = new Result<>(); result.success = false; result.message = message; result.code = 500; return result; } // getter/setter 略 } // 工具类(可选) public class Results { public static <T> Result<T> ok(T data) { return Result.success(data); } public static Result<Void> ok() { return Result.success(); } public static <T> Result<T> error(String msg) { return Result.fail(msg); } }🚀 Controller 使用:
@RestController public class UserController { @GetMapping("/user/{id}") public Result<User> getUser(@PathVariable Long id) { User user = userService.findById(id); if (user == null) { return Results.error("用户不存在"); } return Results.ok(user); } }💡 配合全局异常处理器,实现异常自动转 Result,Controller 零 try-catch!
五、断言工具类:简化参数校验
❌ 反例:一堆 if 判断
if (userId == null) { throw new IllegalArgumentException("用户ID不能为空"); } if (StringUtils.isBlank(name)) { throw new IllegalArgumentException("姓名不能为空"); }✅ 封装:AssertUtils
public class AssertUtils { public static void notNull(Object obj, String message) { if (obj == null) { throw new IllegalArgumentException(message); } } public static void notEmpty(String str, String message) { if (str == null || str.trim().isEmpty()) { throw new IllegalArgumentException(message); } } public static void isTrue(boolean expression, String message) { if (!expression) { throw new IllegalArgumentException(message); } } public static void notEmpty(Collection<?> collection, String message) { if (collection == null || collection.isEmpty()) { throw new IllegalArgumentException(message); } } }🚀 使用示例:
public void createUser(CreateUserRequest req) { AssertUtils.notNull(req.getUserId(), "用户ID不能为空"); AssertUtils.notEmpty(req.getName(), "姓名不能为空"); AssertUtils.isTrue(req.getAge() > 0, "年龄必须大于0"); // 业务逻辑... }✅ 优势:代码简洁 + 错误信息明确 + 统一异常类型
六、Bonus:如何组织这些工具类?
建议按功能分包:
com.yourcompany.common.utils ├── CollectionUtils.java ├── JsonUtils.java ├── DateUtils.java ├── AssertUtils.java └── web ├── Result.java └── Results.java并在pom.xml中确保依赖:
<!-- Spring Boot Web 已包含 Jackson --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 如果用 Lombok(推荐) --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> </dependency>七、注意事项(避坑指南)
- 工具类方法必须是 static,但内部可依赖 Spring Bean(如 JsonUtils 用
@PostConstruct注入); - 不要过度封装:简单场景直接用
Objects.nonNull()、Collection.isEmpty()也行; - 日期工具优先用 Java 8 Time API,避免 Date/Calendar 的坑;
- JSON 工具务必复用 Spring 的 ObjectMapper,否则全局配置失效;
- 工具类不要有状态(即不要有成员变量),保证线程安全。
视频看了几百小时还迷糊?关注我,几分钟让你秒懂!