Guava Google核心库入门教程
你是否曾经在Java开发中为一些基础操作写了大量重复代码?或者被Java原生API的局限性困扰?如果是,那么Google Guava库可能就是你一直在寻找的解决方案!
什么是Guava?
Guava是由Google开发并维护的一套开源Java工具库,它包含了一系列核心库,可以帮助Java开发者编写更清晰、更简洁、更高效的代码。它弥补了Java标准库的不足,提供了许多实用的工具类和方法,从集合处理到I/O操作,从缓存实现到并发工具,应有尽有。
许多大型项目都在使用Guava,比如Hadoop、Spark等。一旦你开始使用它,你会发现自己的代码质量和开发效率都会有显著提升!
为什么要使用Guava?
在深入了解Guava的具体功能之前,我们先来看看为什么要使用它:
- 减少样板代码 - Guava提供了许多便捷方法,可以大大减少你需要编写的重复代码
- 提高代码可读性 - 使用Guava的方法通常比原生Java更直观、更易于理解
避免常见错误 - Guava中的许多方法都经过精心设计,可以帮助你避免一些常见的编程错误
- 性能优化 - Guava中的很多实现都经过了性能优化,比自己实现更高效
- 与时俱进 - Guava不断吸收Java社区的最佳实践,并随着Java版本的更新而更新
如何引入Guava
在Maven项目中添加Guava依赖非常简单:
xml
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version> <!-- 请使用最新版本 -->
</dependency>
对于Gradle项目:
groovy
implementation 'com.google.guava:guava:31.1-jre' // 请使用最新版本
引入后,就可以开始使用Guava的强大功能了!
Guava核心功能概览
Guava库包含了很多模块,下面我们先对主要模块做一个简单介绍,然后再详细讲解一些常用的功能。
- 基础工具(Basic Utilities):提供了处理字符串、数字、对象等的基础工具类
- 集合(Collections):扩展了Java集合框架,提供了新的集合类型和工具方法
- 缓存(Caching):提供了内存缓存的实现
- 函数式编程(Functional Programming):支持Java中的函数式编程
- 并发(Concurrency):简化了并发编程
- I/O:简化了I/O操作
- 数学运算(Math):提供了一些数学相关的工具
- 反射(Reflection):简化了反射操作
下面,我们将深入探讨这些模块中的一些常用功能。
基础工具(Basic Utilities)
Preconditions(前置条件检查)
在编写方法时,我们经常需要检查参数是否满足某些条件。Guava的Preconditions类提供了一系列静态方法,可以帮助我们简化这些检查。
```java
import static com.google.common.base.Preconditions.*;
public void processTask(Task task, int priority) {
// 检查task不为null
checkNotNull(task, "Task cannot be null");
}
```
使用Preconditions相比直接使用if语句和抛出异常,代码更加简洁、可读性更强。而且,错误消息可以使用printf风格的格式化。
Strings(字符串处理)
Guava提供了Strings类,包含了一系列实用的字符串处理方法。
```java
import static com.google.common.base.Strings.*;
// 判断字符串是否为空或null
boolean isEmpty = isNullOrEmpty(str);
// 如果字符串为null,返回默认值
String result = nullToEmpty(str);
// 重复字符串
String repeated = repeat("hello", 3); // "hellohellohello"
// 填充字符串到指定长度
String padded = padEnd("hello", 10, ' '); // "hello "
```
Objects(对象工具)
对象比较、哈希码计算、toString生成等常见操作,Guava都提供了便捷方法。
```java
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
// 判断两个对象是否相等(处理null情况)
boolean isEqual = Objects.equal(obj1, obj2);
// 计算对象的哈希码
int hashCode = Objects.hashCode(field1, field2, field3);
// 生成toString
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("name", name)
.add("age", age)
.add("email", email)
.toString();
}
```
集合(Collections)
Guava大大扩展了Java的集合框架,提供了很多实用的集合类型和工具方法。
不可变集合(Immutable Collections)
不可变集合在创建后不能被修改,这有助于防止意外修改,特别是在多线程环境下。
```java
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
// 创建不可变列表
ImmutableList list = ImmutableList.of("a", "b", "c");
// 创建不可变集合
ImmutableSet set = ImmutableSet.of("red", "green", "blue");
// 创建不可变映射
ImmutableMap map = ImmutableMap.of(
"apple", 1,
"banana", 2,
"cherry", 3
);
// 使用构建器创建更复杂的不可变集合
ImmutableList moreItems = ImmutableList.builder()
.add("first")
.add("second")
.addAll(otherList)
.build();
```
新集合类型
Guava引入了一些Java标准库中没有的集合类型:
Multimap(多值映射)
在Java中,如果我们想创建一个键到多个值的映射(例如,一个人的多个电话号码),通常会使用Map<K, List<V>>或Map<K, Set<V>>。Guava的Multimap简化了这一操作。
```java
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
Multimap phoneBook = ArrayListMultimap.create();
// 添加条目
phoneBook.put("John", "123-456-7890");
phoneBook.put("John", "098-765-4321");
phoneBook.put("Mary", "555-123-4567");
// 获取所有与键关联的值
Collection johnsPhones = phoneBook.get("John"); // 包含两个电话号码
// 检查特定的键值对是否存在
boolean hasPhone = phoneBook.containsEntry("John", "123-456-7890"); // true
```
BiMap(双向映射)
BiMap允许你不仅可以从键查找值,还可以从值查找键。
```java
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
BiMap userId = HashBiMap.create();
userId.put("John", 1234);
userId.put("Mary", 5678);
// 从键获取值
int id = userId.get("John"); // 1234
// 从值获取键
String name = userId.inverse().get(1234); // "John"
// 确保值的唯一性
try {
userId.put("Bob", 1234); // 抛出IllegalArgumentException,因为1234已经映射到John
} catch (IllegalArgumentException e) {
// 处理异常
}
// 强制替换现有值
userId.forcePut("Bob", 1234); // 现在1234映射到Bob,John不再在映射中
```
Table(表格)
Table提供了一个类似于Excel表格的数据结构,可以通过行和列来访问单元格。
```java
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
Table grades = HashBasedTable.create();
// 添加值
grades.put("Alice", "Math", 95.5);
grades.put("Alice", "Science", 90.0);
grades.put("Bob", "Math", 85.0);
grades.put("Bob", "Science", 92.5);
// 获取特定单元格的值
Double aliceMathGrade = grades.get("Alice", "Math"); // 95.5
// 获取一行中的所有列
Map allAliceGrades = grades.row("Alice");
// 获取一列中的所有行
Map allMathGrades = grades.column("Math");
```
集合工具
Guava提供了大量处理集合的实用工具方法。
Lists, Sets, Maps
这些类提供了创建和操作列表、集合和映射的便捷方法。
```java
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.collect.Maps;
// 创建ArrayList
List list = Lists.newArrayList("a", "b", "c");
// 创建LinkedList
List linkedList = Lists.newLinkedList();
// 创建HashSet
Set set = Sets.newHashSet("red", "green", "blue");
// 创建HashMap
Map map = Maps.newHashMap();
// 计算集合的笛卡尔积
Set> product = Sets.cartesianProduct(
Sets.newHashSet("a", "b"),
Sets.newHashSet("1", "2")
);
// 结果: [a, 1], [a, 2], [b, 1], [b, 2]
```
Collections2, Iterables, Iterators
这些类提供了过滤、转换集合的方法。
```java
import com.google.common.base.Predicate;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
List names = Lists.newArrayList("John", "Jane", "Adam", "Tom");
// 过滤集合
Collection filteredNames = Collections2.filter(names,
new Predicate() {
public boolean apply(String name) {
return name.startsWith("J");
}
});
// 结果: "John", "Jane"
// 使用Java 8 lambda表达式(如果你的项目支持)
Collection filteredWithLambda = Collections2.filter(names, name -> name.startsWith("J"));
// 转换集合
Collection nameLengths = Collections2.transform(names,
new Function() {
public Integer apply(String name) {
return name.length();
}
});
// 结果: 4, 4, 4, 3
// 使用Java 8 lambda
Collection lengthsWithLambda = Collections2.transform(names, name -> name.length());
// 连接多个集合
Iterable combined = Iterables.concat(
Lists.newArrayList("a", "b"),
Lists.newArrayList("c", "d")
);
// 结果: "a", "b", "c", "d"
// 获取集合中的第一个元素
String first = Iterables.getFirst(names, "default"); // "John"
```
缓存(Caching)
Guava提供了一个强大的内存缓存实现,可以帮助你避免重复计算或重复访问昂贵的资源。
```java
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import java.util.concurrent.TimeUnit;
// 创建一个简单的缓存
Cache cache = CacheBuilder.newBuilder()
.maximumSize(1000) // 最大缓存1000个条目
.expireAfterWrite(10, TimeUnit.MINUTES) // 写入后10分钟过期
.build();
// 手动加载值到缓存
try {
cache.get("userId", () -> userDao.loadUserById("userId"));
} catch (ExecutionException e) {
// 处理异常
}
// 创建自动加载值的缓存
LoadingCache loadingCache = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(
new CacheLoader() {
@Override
public User load(String userId) throws Exception {
return userDao.loadUserById(userId);
}
});
// 使用自动加载缓存
try {
User user = loadingCache.get("userId"); // 如果不存在,会自动调用load方法
} catch (ExecutionException e) {
// 处理异常
}
```
I/O操作
Guava简化了很多常见的I/O操作,使代码更加简洁。
```java
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import com.google.common.io.Resources;
import java.io.File;
import java.net.URL;
import java.util.List;
// 读取文件所有行
List lines = Files.readLines(new File("file.txt"), Charsets.UTF_8);
// 写入字符串到文件
Files.write("content", new File("output.txt"), Charsets.UTF_8);
// 复制文件
Files.copy(new File("source.txt"), new File("destination.txt"));
// 从URL读取内容
URL url = new URL("http://www.example.com");
String content = Resources.toString(url, Charsets.UTF_8);
```
EventBus(事件总线)
EventBus是Guava提供的一个发布-订阅模式的实现,可以大大简化组件之间的通信。
```java
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
// 创建事件类
public class MessageEvent {
private final String message;
}
// 创建事件监听器
public class MessageListener {
@Subscribe
public void handleMessage(MessageEvent event) {
System.out.println("Received message: " + event.getMessage());
}
}
// 使用EventBus
EventBus eventBus = new EventBus();
eventBus.register(new MessageListener());
eventBus.post(new MessageEvent("Hello, EventBus!"));
```
实际应用示例
让我们通过一个实际的例子来展示Guava如何简化代码。假设我们要编写一个简单的用户管理系统,处理用户数据。
没有使用Guava的版本:
```java
public class UserService {
private Map> usersByRole = new HashMap<>();
}
```
使用Guava后的版本:
```java
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
public class UserService {
private Multimap usersByRole = ArrayListMultimap.create();
}
```
可以看到,使用Guava后的代码更加简洁,可读性更强,而且功能更强大。
总结
Guava是一个非常强大的Java工具库,它可以帮助你编写更清晰、更简洁、更高效的代码。本文只是介绍了Guava的一部分功能,它还有很多其他实用的工具和方法等待你去探索。
主要优点:
- 减少样板代码
- 提高代码可读性
- 提供了许多实用的集合类型和工具方法
- 性能优化
- 持续更新和维护
如何开始使用:
1. 添加Guava依赖到你的项目
2. 浏览Guava的文档,了解它提供的功能
3. 从简单的功能开始,逐步扩展到更复杂的用法
4. 持续学习和探索新功能
最后,我建议你查看Guava的官方文档和GitHub仓库,以获取最新的信息和更详细的说明。希望这篇教程能帮助你更好地使用Guava,提高你的Java开发效率!
记住,好的工具能让编程更加愉快,而Guava绝对是Java开发者工具箱中不可或缺的一部分!(试试看,你会爱上它的!)
更多推荐

所有评论(0)