【Java】Java 开发利器:Guava 工具类全方位使用总结
日常 Java 开发过程中,原生 JDK 提供的工具类多多少少存在短板:空指针泛滥、集合创建繁琐、字符串拼接拆分代码冗余、本地缓存需要自己手动实现等问题层出不穷。Google 开源的Guava工具库就是为了解决这类痛点而生,封装了大量实用 API,覆盖参数校验、空值处理、增强集合、字符串操作、本地缓存等高频开发场景。今天结合日常项目实战,梳理 Guava 常用功能与落地代码。
一、Maven 快速引入依赖
使用 Guava 第一步在pom.xml引入坐标,选用稳定版:
<!-- Guava依赖 -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.3-jre</version>
</dependency>
二、基础工具类:规避 NPE 与参数校验
1. Optional 空值处理
原生代码直接使用null极易引发空指针异常,Guava 的Optional强制开发者主动处理空值,杜绝隐性 NPE。
import com.google.common.base.Optional;
public class OptionalDemo {
public static void main(String[] args) {
// 1. 创建非空对象
Optional<String> opt1 = Optional.of("Java-Guava");
// 2. 允许传入null
Optional<String> opt2 = Optional.fromNullable(null);
// 判断是否有值
System.out.println(opt1.isPresent()); // true
// 空值时设置默认返回
String res = opt2.or("默认字符串");
System.out.println(res); // 默认字符串
}
}
2. Preconditions 参数前置校验
项目入参校验是刚需,原生 if 判断代码臃肿,Preconditions一行代码完成参数合法性校验,不满足直接抛出异常。
import com.google.common.base.Preconditions;
public class PreconditionsDemo {
public static void getUserInfo(Integer userId){
// 校验参数不能为null
Preconditions.checkNotNull(userId,"用户ID不能为空");
// 校验数值范围
Preconditions.checkArgument(userId>0,"用户ID必须大于0");
System.out.println("合法用户ID:"+userId);
}
public static void main(String[] args) {
getUserInfo(10);
// getUserInfo(-1); // 抛出IllegalArgumentException
}
}
3. 便捷 Object 工具方法
JDK7 的java.util.Objects设计大量参考 Guava,在低版本 JDK 环境中可直接使用 Guava 自带的对象比较、哈希方法。
三、Guava 增强集合(开发高频使用)
Guava 拓展了 JDK 没有的特殊集合:不可变集合、Multiset、Multimap、BiMap,同时提供 Lists/Sets 便捷创建集合。
1. 不可变集合 Immutable
原生Collections.unmodifiableList只是视图包装,原集合修改后视图同步变化;Guava 不可变集合是真正副本,原集合改动不影响自身,天生线程安全,可作为常量使用。
import com.google.common.collect.ImmutableList;
public class ImmutableDemo {
public static void main(String[] args) {
// 快速创建不可变集合
ImmutableList<String> list = ImmutableList.of("MySQL","Java","Linux");
// list.add("C++"); // 调用add直接抛异常,不允许修改
}
}
2. Lists 工具:简化集合操作
import com.google.common.collect.Lists;
import java.util.List;
public class ListsDemo {
public static void main(String[] args) {
// 1.快速初始化集合
List<Integer> list = Lists.newArrayList(1,2,3,4,5);
// 2.集合分页,每2个元素分为一组
List<List<Integer>> pageList = Lists.partition(list,2);
System.out.println(pageList); // [[1,2],[3,4],[5]]
// 3.集合反转
List<Integer> reverse = Lists.reverse(list);
System.out.println(reverse); // [5,4,3,2,1]
}
}
3. Multiset:可重复元素集合,快速统计频次
普通 Set 不允许重复元素,统计元素出现次数需要 Map 手动计数,Multiset 原生支持重复存储 + 计数。
import com.google.common.collect.Multiset;
import com.google.common.collect.HashMultiset;
public class MultisetDemo {
public static void main(String[] args) {
Multiset<String> multiSet = HashMultiset.create();
multiSet.add("Java");
multiSet.add("Java");
multiSet.add("MySQL");
// 获取指定元素出现次数
System.out.println(multiSet.count("Java")); // 2
}
}
4. Multimap:一键实现一个 key 对应多个 value
原生 Map<K,List<V>> 代码繁琐,Multimap 天然支持一键多值映射。
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
public class MultimapDemo {
public static void main(String[] args) {
Multimap<String,String> map = ArrayListMultimap.create();
map.put("后端","Java");
map.put("后端","Go");
map.put("前端","Vue");
System.out.println(map.get("后端")); // [Java, Go]
}
}
5. BiMap 双向映射:键值互相查询
普通 Map 只能 key 查 value,BiMap 可通过inverse()反转映射,用 value 反向查 key。
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
public class BiMapDemo {
public static void main(String[] args) {
BiMap<Integer,String> biMap = HashBiMap.create();
biMap.put(1,"admin");
// value反向获取key
BiMap<String,Integer> inverseMap = biMap.inverse();
System.out.println(inverseMap.get("admin")); //1
}
}
四、字符串处理:Joiner 与 Splitter 告别冗余代码
1. Joiner:字符串拼接
原生循环拼接、处理 null 空值代码繁杂,Joiner 链式配置,轻松处理空元素。
import com.google.common.base.Joiner;
public class JoinerDemo {
public static void main(String[] args) {
String[] arr = {"Java",null,"MySQL","Linux"};
// 忽略null元素拼接
String s1 = Joiner.on(",").skipNulls().join(arr);
System.out.println(s1); // Java,MySQL,Linux
// null替换为指定字符
String s2 = Joiner.on(",").useForNull("空").join(arr);
System.out.println(s2); // Java,空,MySQL,Linux
}
}
2. Splitter:灵活字符串拆分
原生 String.split 存在正则坑点,Splitter 拆分规则可控。
import com.google.common.base.Splitter;
import java.util.List;
public class SplitterDemo {
public static void main(String[] args) {
String str = "Java,,MySQL, Linux ";
// 按逗号拆分+忽略空串+去除首尾空格
List<String> list = Splitter.on(",")
.omitEmptyStrings()
.trimResults()
.splitToList(str);
System.out.println(list); // [Java, MySQL, Linux]
}
}
五、Guava 本地缓存 Cache
开发中高频查询、查询耗时高的数据,可使用 Guava Cache 实现轻量级本地缓存,无需引入 Redis 等中间件。
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.util.concurrent.TimeUnit;
public class CacheDemo {
public static void main(String[] args) throws Exception {
// 构建缓存:最大容量100,写入后5分钟过期
Cache<String,Integer> cache = CacheBuilder.newBuilder()
.maximumSize(100)
.expireAfterWrite(5, TimeUnit.MINUTES)
.build();
// 存入缓存
cache.put("user:1001",1001);
// 获取缓存
Integer userId = cache.getIfPresent("user:1001");
System.out.println(userId);
}
}
六、总结
Guava 几乎覆盖后端日常开发的各类小工具场景,合理引入项目可以大量精简重复代码、减少空指针、优化集合与字符串处理逻辑。后续我会持续更新 Guava 高级用法,包含事件总线、范围工具、异步工具等内容,感兴趣可以持续关注博客更新。


