Guava常见特性操作
1. 简介
Guava 是 Google 开发的一个 Java 核心库,它包含了许多 Google 工程师在 Java 编程中常用的实用工具。Guava 库旨在提供新的集合类型(如多集合和双端队列)、缓存、原生类型支持、并发库、常见注解、字符串处理等实用工具。
一些关键特性:
集合框架增强
-
不可变集合:如
ImmutableList
、ImmutableSet
、ImmutableMap
,创建后无法修改,提高线程安全性。 -
Multimap:支持一个键映射多个值的结构,例如
ListMultimap
和SetMultimap
。 -
BiMap:双向映射,键和值都必须唯一,可以通过值反向查找键。
-
Table:支持二维表结构的数据存储,类似于矩阵。
缓存机制
-
提供强大的内存缓存工具,例如
Cache
和LoadingCache
。 -
支持自动过期、最大容量和数据刷新等策略。
字符串处理
-
Splitter 和 Joiner:轻松进行字符串拆分和拼接操作。
-
Optional:更优雅地处理
null
值,避免空指针异常。
函数式编程支持
-
提供 Predicate 和 Function,用于逻辑判断和数据转换操作。
-
流式 API 支持过滤、映射等功能。
并发工具
-
ListenableFuture:支持异步任务的链式执行和组合操作。
-
RateLimiter:实现请求速率控制,适合流量限制场景。
I/O 操作
-
简化文件和流的处理,支持按字节或字符操作。
-
提供 ByteSource 和 CharSource 处理输入和输出流。
数学工具
-
提供整数、长整型和浮点型数学计算工具。
-
支持哈希计算和校验功能。
其他工具
-
EventBus:基于发布-订阅模式的事件总线。
-
Range:定义数学区间范围,并支持区间操作。
2. 示例
添加依赖
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
不可变集合
import com.google.common.collect.ImmutableList;
ImmutableList<String> colors = ImmutableList.of("红色", "绿色", "蓝色");
System.out.println(colors);
Multimap
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
Multimap<String, String> multimap = ArrayListMultimap.create();
multimap.put("水果", "苹果");
multimap.put("水果", "香蕉");
multimap.put("蔬菜", "胡萝卜");
System.out.println(multimap.get("水果")); // [苹果, 香蕉]
缓存:分为cache和loadingCache
import com.google.common.cache.*;
Cache<String, String> cache = CacheBuilder.newBuilder()
.maximumSize(100) // 设置最大缓存条数
.expireAfterWrite(10, TimeUnit.MINUTES) // 写入10分钟后过期
.build();
cache.put("key", "value");
System.out.println(cache.getIfPresent("key")); // 输出: "value"
项目实例:
@Configuration
public class GoogleGuavaCacheConfig {
private final IOrderService orderService;
public GoogleGuavaCacheConfig(IOrderService orderService) {
this.orderService = orderService;
}
@Bean(name = "loadingCacheOrder")
public LoadingCache<String, List<CacheOrderDetail>> loadingCacheOrder() {
return CacheBuilder.newBuilder()
.build(
new CacheLoader<String, List<CacheOrderDetail>>() {
@Override
public List<CacheOrderDetail> load(String key) throws Exception {
return orderService.queryAllOrderByStatus(key);
}
}
);
}
}
3. 缓存特解
3.1 Cache:手动缓存
Cache
是一种 手动缓存(Manual Cache),需要程序员手动处理缓存的存储和加载。
特点:
-
需要显式将数据放入缓存 (
put
) 和获取数据 (getIfPresent
)。 -
不会自动加载数据,需要在访问时判断缓存中是否存在数据。
-
适合数据源不确定或需自定义加载逻辑的场景。
示例代码:
import com.google.common.cache.*;
import java.util.concurrent.TimeUnit;
Cache<String, String> cache = CacheBuilder.newBuilder()
.maximumSize(100) // 最大缓存条目数
.expireAfterWrite(10, TimeUnit.MINUTES) // 数据写入 10 分钟后过期
.build();
// 手动存储数据
cache.put("key1", "value1");
// 获取缓存数据String value = cache.getIfPresent("key1");
System.out.println(value); // 输出: value1// 删除缓存数据
cache.invalidate("key1");
适用场景:
-
缓存内容需要手动控制加载和更新。
-
缓存逻辑较为复杂,无法直接确定加载逻辑。
3.2 LoadingCache:自动加载缓存
LoadingCache
是 自动加载缓存,提供了数据加载逻辑,当缓存中没有数据时会自动计算或加载所需数据。
特点:
-
提供 CacheLoader,在缓存缺失时自动加载数据,无需手动填充。
-
支持批量加载数据。
-
适合依赖于数据库、文件或服务等外部资源的数据缓存场景。
示例代码:
import com.google.common.cache.*;
import java.util.concurrent.TimeUnit;
LoadingCache<String, String> loadingCache = CacheBuilder.newBuilder()
.maximumSize(100) // 最大缓存条目数
.expireAfterWrite(10, TimeUnit.MINUTES) // 数据写入 10 分钟后过期
.build(new CacheLoader<String, String>() {
@Override
public String load(String key) throws Exception {
// 模拟从外部数据源加载数据
return "value-for-" + key;
}
});
// 获取缓存数据,如果不存在则自动加载
String value1 = loadingCache.getUnchecked("key1");
System.out.println(value1); // 输出: value-for-key1
String value2 = loadingCache.getUnchecked("key2");
System.out.println(value2); // 输出: value-for-key2
适用场景:
-
缓存内容可以通过固定逻辑计算或加载。
-
需要根据键动态加载数据的场景,例如数据库查询或文件读取。
3.3 对比总结
特性 | Cache | LoadingCache |
加载方式 | 手动存取 (put / getIfPresent) | 自动加载 (通过 CacheLoader) |
缺失处理 | 手动判断不存在时添加 | 缓存缺失时自动计算或加载 |
适用场景 | 数据加载逻辑复杂或动态性较高 | 数据加载逻辑确定,可依赖固定加载规则 |
批量加载支持 | 不支持 | 支持批量加载 (通过 loadAll) |
性能和易用性 | 需要开发者自行维护存取逻辑,较灵活但复杂 | 自动加载更方便,适合标准化场景 |
3.4 选择建议
-
如果缓存数据不需要自动加载,或需要复杂的加载逻辑,选择
Cache
。 -
如果缓存数据来源明确,可以通过固定逻辑加载,选择
LoadingCache
。