Guava不仅仅是一个工具库,更是Google工程师多年经验的结晶。它让Java代码变得优雅、简洁、高效。
Spring、MyBatis等顶级框架使用的工具库

-
配置管理 → ImmutableMap
-
错误码映射 → BiMap
-
文章标签 → Multimap
-
批量处理 → Lists.partition
-
字符串操作 → Splitter + Joiner
添加Maven依赖
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.3-jre</version>
</dependency>
Multimap不是线程安全的
// 多线程环境直接使用
Multimap<String, String> map = ArrayListMultimap.create();
// 需要同步包装
Multimap<String, String> syncMap =
Multimaps.synchronizedMultimap(ArrayListMultimap.create());
BiMap值必须唯一
BiMap<String, Integer> map = HashBiMap.create();
map.put("A", 1);
map.put("B", 1); // 抛出IllegalArgumentException
// 使用forcePut强制替换
map.forcePut("B", 1); // A被移除,B映射到1
代码量对比
|----------|---------|-----------|---------|
| 场景 | JDK代码行数 | Guava代码行数 | 减少比例 |
| 不可变Map创建 | 7行 | 3行 | 57% |
| 字符串分割处理 | 7行 | 1行 | 86% |
| 双向映射查找 | 15行 | 2行 | 87% |
| 列表批量分割 | 10行 | 1行 | 90% |

实战案例二:动态SQL生成
public classSqlBuilder{
private static final Joiner COMMA_JOINER = Joiner.on(", ");
public String buildInsert(String table, Map<String, Object> data) {
List<String> columns = new ArrayList<>(data.keySet());
List<String> placeholders = Collections.nCopies(columns.size(), "?");
returnString.format(
"INSERT INTO %s (%s) VALUES (%s)",
table,
COMMA_JOINER.join(columns),
COMMA_JOINER.join(placeholders)
);
}
}
// 使用
Map<String, Object> data = new LinkedHashMap<>();
data.put("name", "Alice");
data.put("age", 25);
data.put("email", "alice@example.com");
String sql = builder.buildInsert("users", data);
// INSERT INTO users (name, age, email) VALUES (?, ?, ?)
实战案例三:构建URL
publicclassUrlBuilder {
privatestatic final Joiner.MapJoiner QUERY_JOINER =Joiner.on('&').withKeyValueSeparator('=');
private String baseUrl;
private Map<String, String> params = new LinkedHashMap<>();
publicUrlBuilder(String baseUrl) {
this.baseUrl = baseUrl;
}
public UrlBuilder addParam(String key, String value) {
if (value != null) {
params.put(key, value);
}
returnthis;
}
public String build() {
if (params.isEmpty()) return baseUrl;
return baseUrl + "?" + QUERY_JOINER.join(params);
}
}
// 使用
String url = new UrlBuilder("https://api.example.com/search")
.addParam("q", "guava")
.addParam("page", "1")
.addParam("size", "20")
.build();
// https://api.example.com/search?q=guava&page=1&size=20
案例一:CSV文件处理
publicclassCsvProcessor {
privatestatic final Splitter CSV_SPLITTER = Splitter.on(',').trimResults().omitEmptyStrings();
privatestatic final Joiner CSV_JOINER = Joiner.on(',').useForNull("");
// 解析CSV行
public List<String> parseLine(String line) {
return CSV_SPLITTER.splitToList(line);
}
// 生成CSV行
public String buildLine(List<String> fields) {
return CSV_JOINER.join(fields);
}
}
案例二:配置文件管理
publicclassConfigManager {
privatestatic final Splitter.MapSplitter CONFIG_SPLITTER =
Splitter.on('\n').trimResults() .omitEmptyStrings()
.withKeyValueSeparator('=');
public ImmutableMap<String, String> loadConfig(String content) {
// 过滤注释行
String cleaned = Splitter.on('\n')
.splitToStream(content)
.filter(line -> !line.trim().startsWith("#"))
.collect(Collectors.joining("\n"));
return ImmutableMap.copyOf(CONFIG_SPLITTER.split(cleaned));
}
}
案例三:批量任务处理
publicclassTaskProcessor {
privatestatic final int BATCH_SIZE =100;
publicvoidprocessTasks(List<Task> tasks) {
// 分批处理
Lists.partition(tasks, BATCH_SIZE).forEach(batch -> {
// 生成批次ID
String batchId = Joiner.on("-").join(
"batch",
System.currentTimeMillis(),
batch.size()
);
// 处理每批任务
processBatch(batchId, batch);
});
}
}
限制分割次数:
Stringstr = "key:value:extra:data";
List<String> parts = Splitter.on(':').limit(2).splitToList(str);
// 结果:["key", "value:extra:data"]
固定长度分割:
String str = "123456789012";
List<String> parts = Splitter.fixedLength(3).splitToList(str);
// 结果:["123", "456", "789", "012"]
正则表达式分割:
String log = "2024-01-15 10:30:45 ERROR";
List<String> parts = Splitter.onPattern("\\s+").splitToList(log);
// 结果:["2024-01-15", "10:30:45", "ERROR"]
问题一:无法处理空字符串
"a,,b".split(",") // 结果:["a", "", "b"] - 包含空字符串
问题二:无法去除空格
"a, b , c".split(",") // 结果:["a", " b ", " c "] - 保留空格
Guava的完美解决:
Splitter.on(',')
.trimResults() // 自动去除空格
.omitEmptyStrings() // 自动忽略空字符串
.splitToList("a, ,b,,c");
// 结果:["a", "b", "c"] - 完美!
实战案例一:URL参数解析
public classUrlParamParser{
private static final Splitter.MapSplitter PARSER = Splitter.on('&') .trimResults().withKeyValueSeparator('=');
public Map<String, String> parse(String url) {
int index = url.indexOf('?');
if (index == -1) return Collections.emptyMap();
String query = url.substring(index + 1);
return PARSER.split(query);
}
}
// 使用
String url = "https://api.com/search?keyword=guava&page=1&size=20";
Map<String, String> params = parser.parse(url);
// 结果:{keyword=guava, page=1, size=20}
实战案例二:日志解析
publicclassLogParser {
privatestatic final Splitter SPLITTER =
Splitter.onPattern("\\s+").limit(4);
public LogEntry parse(String log) {
// "2025-11-15 12:33:17 ERROR User not found"
List<String> parts = SPLITTER.splitToList(log);
returnnew LogEntry(
parts.get(0), // 日期
parts.get(1), // 时间
parts.get(2), // 级别
parts.get(3) // 消息(剩余部分)
);
}
}
Lists.partition:批量处理的利器
场景:需要将10000条数据分批插入数据库,每批100条
publicclassBatchProcessor{
privatestaticfinal int BATCH_SIZE = 100;
public void batchInsert(List<User> users) {
// 自动分割为每批100条
List<List<User>> batches = Lists.partition(users, BATCH_SIZE);
for (List<User> batch : batches) {
userDao.batchInsert(batch);
// 控制插入速度,避免数据库压力
sleep(100);
}
}
}
Lists.partition:批量处理的利器
场景:需要将10000条数据分批插入数据库,每批100条
publicclassBatchProcessor{
privatestaticfinal int BATCH_SIZE = 100;
public void batchInsert(List<User> users) {
// 自动分割为每批100条
List<List<User>> batches = Lists.partition(users, BATCH_SIZE);
for (List<User> batch : batches) {
userDao.batchInsert(batch);
// 控制插入速度,避免数据库压力
sleep(100);
}
}
}
BiMap:双向查找的神器
痛点:你是否经常需要根据value反查key?传统Map需要遍历,效率低下。
BiMap的魔法:
BiMap<String, Integer> userMap = HashBiMap.create();
userMap.put("Alice", 10001);
userMap.put("Bob", 10002);
// 正向查找
Integer id = userMap.get("Alice"); // 10001
// 反向查找(重点来了!)
String name = userMap.inverse().get(10002); // "Bob"
生产案例:错误码双向映射
publicclassErrorCodeManager {
privatestatic final BiMap<String, Integer> ERROR_CODES = HashBiMap.create();
static {
ERROR_CODES.put("USER_NOT_FOUND", 2000);
ERROR_CODES.put("INVALID_PASSWORD", 2001);
ERROR_CODES.put("PERMISSION_DENIED", 2002);
}
// 根据错误名获取错误码
publicstatic Integer getCode(String errorName) {
return ERROR_CODES.get(errorName);
}
// 根据错误码获取错误名(传统Map做不到!)
publicstatic String getName(Integer errorCode) {
return ERROR_CODES.inverse().get(errorCode);
}
}
实战案例:HTTP状态码管理
publicclassHttpStatusManager {
// 线程安全的状态码映射
privatestaticfinal ImmutableMap<Integer, String> STATUS_MAP =
ImmutableMap.<Integer, String>builder()
.put(200, "OK")
.put(201, "Created")
.put(400, "Bad Request")
.put(401, "Unauthorized")
.put(404, "Not Found")
.put(500, "Internal Server Error")
.build();
publicstatic String getMessage(int code){
return STATUS_MAP.getOrDefault(code, "Unknown Status");
}
}
