好东西 ✨
简介
本文档收集了 Java 开发中常用的工具类和库,帮助开发者提高编码效率和代码质量。
- HashMap:提供了快速的键值对存储和检索功能,是 Java 集合框架中最常用的映射实现之一。
- ObjectMapper:Jackson 库的核心类,用于将 Java 对象与 JSON 之间的相互转换,支持丰富的序列化和反序列化功能。
- Lombok:通过注解自动生成样板代码(如 getter、setter、constructor 等),减少冗余代码,提高开发效率。
- Hibernate Validator:Bean Validation API 的实现,提供强大的对象验证功能,通过简单的注解实现复杂的数据验证逻辑。
这些工具类和库能够显著减少样板代码,提高代码可读性和可维护性,是 Java 开发者的必备工具箱。
HashMap
java
HashMap<String, String> map = new HashMap<>();
map.put("key", "value"); // 添加键值对
String value = map.get("key"); // 获取键对应的值
map.remove("key"); // 删除键值对
boolean containsKey = map.containsKey("key"); // 检查是否包含指定键
int size = map.size(); // 获取键值对的数量
boolean isEmpty = map.isEmpty(); // 检查是否为空
map.clear(); // 清空所有键值对常用方法
put(key, value):添加键值对get(key):获取键对应的值remove(key):删除键值对containsKey(key):检查是否包含指定键containsValue(value):检查是否包含指定值size():获取键值对的数量isEmpty():检查是否为空clear():清空所有键值对
ObjectMapper
java
ObjectMapper objectMapper = new ObjectMapper();
String jsonString = objectMapper.writeValueAsString(object); // 将 Java 对象序列化为 JSON 字符串
Object javaObject = objectMapper.readValue(jsonString, Object.class); // 将 JSON 字符串反序列化为 Java 对象常用方法
writeValueAsString(Object obj):将 Java 对象序列化为 JSON 字符串readValue(String json, Class<T> valueType):将 JSON 字符串反序列化为 Java 对象
lombok
简介
Lombok 是一个 Java 注解库,通过简单的注解自动生成 getter、setter、constructor 等样板代码,大幅提高开发效率和代码可读性,减少代码冗余。
xml
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>annotationProcessor</scope>
</dependency>java
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
private int age;
}java
import lombok.*;
@Getter // 自动生成所有字段的getter方法
@Setter // 自动生成所有字段的setter方法
@ToString // 自动生成toString方法
@EqualsAndHashCode // 自动生成equals和hashCode方法
@NoArgsConstructor // 自动生成无参构造函数
@AllArgsConstructor // 自动生成全参构造函数
public class Employee {
private Long id;
private String name;
private String email;
private Department department;
// 使用@Builder可以链式创建对象
@Builder
public static Employee createEmployee(String name, String email) {
Employee employee = new Employee();
employee.name = name;
employee.email = email;
return employee;
}
}常用注解
@Data:包含@Getter、@Setter、@ToString、@EqualsAndHashCode和@RequiredArgsConstructor的组合注解@Getter:自动生成所有字段的 getter 方法@Setter:自动生成所有字段的 setter 方法@ToString:自动生成 toString 方法@EqualsAndHashCode:自动生成 equals 和 hashCode 方法@NoArgsConstructor:自动生成无参构造函数@AllArgsConstructor:自动生成全参构造函数@RequiredArgsConstructor:自动生成包含必需字段的构造函数(标记为 final 或 @NonNull 的字段)@Builder:实现建造者模式,提供链式调用创建对象@Slf4j:自动生成该类的 Logger 静态字段,用于日志记录
最佳实践
- 使用
@Data注解可以一次性添加多个常用功能,但在复杂场景下考虑分开使用具体注解 - 对于 JPA 实体类,避免在关联关系上使用
@ToString和@EqualsAndHashCode,防止循环引用 - 使用
@Builder创建不可变对象,提高代码的可读性和安全性 - IDE 需要安装 Lombok 插件以支持代码补全和导航功能
Hibernate Validator
简介
Hibernate Validator 是 Bean Validation API 的参考实现,提供了强大的对象验证功能,通过简单的注解即可实现复杂的数据验证逻辑,广泛应用于 Web 表单验证、REST API 参数校验等场景。
xml
<!-- 核心验证器 -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>8.0.0.Final</version>
</dependency>
<!-- 注解处理器 -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
<version>8.0.0.Final</version>
</dependency>
<!-- 表达式语言支持 -->
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>jakarta.el</artifactId>
<version>4.0.2</version>
</dependency>java
import jakarta.validation.constraints.*;
public class User {
@NotBlank(message = "用户名不能为空")
@Size(min = 4, max = 18, message = "用户名长度须在4-18之间")
private String username;
@NotBlank(message = "密码不能为空")
@Pattern(regexp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[a-zA-Z\\d]{6,18}$",
message = "密码必须包含大小写字母和数字,长度在6-18之间")
private String password;
@Email(message = "邮箱格式不正确")
private String email;
@Min(value = 18, message = "年龄必须大于等于18岁")
@Max(value = 120, message = "年龄必须小于等于120岁")
private int age;
@Past(message = "生日必须是过去的日期")
private Date birthDate;
}java
import jakarta.validation.Valid;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/users")
public class UserController {
@PostMapping("/register")
public ResponseEntity<?> register(@Valid @RequestBody User user, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
// 获取错误信息
String errorMessage = bindingResult.getFieldErrors().stream() // 获取错误信息
.map(DefaultMessageSourceResolvable::getDefaultMessage)
.collect(Collectors.joining(", ")); // 拼接错误信息
return ResponseEntity.badRequest().body(errorMessage);
}
// 处理注册逻辑
return ResponseEntity.ok("注册成功");
}
}java
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
import java.util.Set;
public class ValidationExample {
public static void main(String[] args) {
// 创建验证器
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
// 创建对象
User user = new User();
user.setUsername("jo"); // 不符合长度要求
// 验证对象
Set<ConstraintViolation<User>> violations = validator.validate(user);
// 输出验证结果
violations.forEach(violation ->
System.out.println(violation.getPropertyPath() + ": " + violation.getMessage())
);
}
}常用注解
字符串验证
@NotBlank:字符串不能为 null 且必须包含至少一个非空白字符@NotEmpty:集合、数组或字符串不能为 null 且必须包含至少一个元素@Size(min=, max=):字符串、集合或数组的大小必须在指定范围内@Email:必须是有效的电子邮件地址@Pattern:必须匹配指定的正则表达式
数值验证
@Min:数值必须大于或等于指定的最小值@Max:数值必须小于或等于指定的最大值@Positive:数值必须为正数(大于0)@PositiveOrZero:数值必须为正数或零@Negative:数值必须为负数(小于0)@NegativeOrZero:数值必须为负数或零@DecimalMin:数值必须大于或等于指定的最小值(支持小数)@DecimalMax:数值必须小于或等于指定的最大值(支持小数)
日期验证
@Past:日期必须是过去的日期@PastOrPresent:日期必须是过去或当前的日期@Future:日期必须是将来的日期@FutureOrPresent:日期必须是将来或当前的日期
其他验证
@NotNull:值不能为 null@Null:值必须为 null@AssertTrue:布尔值必须为 true@AssertFalse:布尔值必须为 false@Valid:递归验证关联对象
最佳实践
- 使用
message属性提供清晰的错误信息,便于用户理解和修正 - 对于复杂的验证逻辑,考虑使用自定义验证器和组合验证
- 在 Spring Boot 应用中,添加
spring-boot-starter-validation依赖自动配置验证器 - 使用验证组(Groups)对不同场景应用不同的验证规则
- 对于 REST API,结合
@Valid和BindingResult处理验证错误,返回结构化的错误信息
常见问题
- 验证不生效:检查是否添加了
@Valid注解,以及是否正确处理BindingResult - 自定义消息不显示:确保
message属性格式正确,如果使用消息插值,检查参数名称 - 性能问题:对于高频验证场景,考虑缓存
ValidatorFactory实例 - 循环依赖验证:在双向关联的实体中,小心使用
@Valid避免无限递归验证
最佳实践
- 在使用 HashMap 时,选择合适的初始容量和负载因子,以提高性能。
- 使用 ObjectMapper 时,注意处理异常,确保 JSON 格式正确。
常见问题
- HashMap 的线程安全性:HashMap 不是线程安全的,如果在多线程环境中使用,考虑使用 ConcurrentHashMap。
- ObjectMapper 的性能问题:在处理大量数据时,注意内存使用,适当配置 ObjectMapper。