跳转至

e. Guava工具类库

e. Guava工具类库

更新日期:2021-01-16


1. 概述

Guava原本是Google内部员工觉得Java的类库很难使用,而自己编写的一组工具类的集合。现在Google把它开放了出来,提供给大家使用。

使用Guava可以让我们用简洁的代码,轻松的编写Java中的常见逻辑功能。而使用原生Java编写这些功能是耗时费力的。

Guava有一个用户手册 Guava用户手册 ,这篇文章中的大部分示例代码也将直接照搬这些例子。

2. Guava特性

到底Guava能帮助我们做哪些事情。我将列出来最最简单易用的特性,对比较复杂的地方进行详细说明。

Guava提供了很多特性,其中大部分看起来太陌生,不是Java程序中常见的内容,可读性不好。也有的特性在JDK的后续版本中已经加入进去了。这样的特性我选择不使用。经过一番筛选之后,就剩下了下面这几个???

3. 基础工具

首先要说明的是,要避免使用null。null的含义很模糊,不同的代码段中常常代表不同的含义,很容易出问题。Guava的大多数工具函数在接收到null时,会立即返回错误。

3.1 条件检查

提供一些函数来检查目标值是否满足指定的条件,如果不满足则抛出指定的异常。

条件检查

1
2
checkArgument(i >= 0, "Argument was %s but expected nonnegative", i);
checkArgument(i < j, "Expected i < j, but %s >= %s", i, j);

类似的函数还有

1
2
3
4
5
6
checkArgument(boolean)
checkNotNull(T)
checkState(boolean)
checkElementIndex(int index, int size)
checkPositionIndex(int index, int size)
checkPositionIndexes(int start, int end, int size)

3.2 实现比较接口

提供了ComparisonChain类来更简单的实现比较接口,写起来很愉快。

比如下面的例子。

ComparisonChain

通常的写法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class Person implements Comparable<Person> {
private String lastName;
private String firstName;
private int zipCode;

public int compareTo(Person other) {
    int cmp = lastName.compareTo(other.lastName);
    if (cmp != 0) {
    return cmp;
    }
    cmp = firstName.compareTo(other.firstName);
    if (cmp != 0) {
    return cmp;
    }
    return Integer.compare(zipCode, other.zipCode);
}
}

Guava中的写法

1
2
3
4
5
6
7
public int compareTo(Foo that) {
    return ComparisonChain.start()
        .compare(this.aString, that.aString)
        .compare(this.anInt, that.anInt)
        .compare(this.anEnum, that.anEnum, Ordering.natural().nullsLast())
        .result();
}

可以看到,Java中通常的写法写起来又臭又长,还容易写错。Guava的写法很简短,而且语义非常清楚,容易阅读。

4. 集合工具类

4.1 使用值初始化集合类

创建集合类时指定值是很常见的一个操作。通常写起来会比较烦人。Guava简化了这个过程。

使用值初始化集合类

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// 用元素初始化List
List<String> theseElements = Lists.newArrayList("alpha", "beta", "gamma");
// 初始化Set时指定大小
Set<Type> approx100Set = Sets.newHashSetWithExpectedSize(100);
// 初始化Map
Map<String, Integer> map = ImmutableMap.<String, Integer>builder()
        .put("东", 1)
        .put("南", 2)
        .put("西", 3)
        .put("北", 4)
        .build();

4.2 新的包装类型

可以使用新的包装类型,对数值类型,求多个值的最大值或最小值。 新的包装类型的名字是在Java原生包装类型后面加上一个s

求最大值最小值

1
Longs.max(1, 2, 3, 4, 5, 6, 7, 8);

从此再也不用嵌套max了。

5. 字符串操作

5.1 连接字符串

Java中已经提供了连接字符串的函数,但是只能用于String

连接字符串

1
2
3
4
5
// 可以设定跳过空的对象
Joiner joiner = Joiner.on("; ").skipNulls();
return joiner.join("Harry", null, "Ron", "Hermione");
// 连接数值
Joiner.on(",").join(Arrays.asList(1, 5, 7)); // returns "1,5,7"

5.2 分割字符串

分割字符串的结果通常模糊不清。Guava提供了一个写法清晰,轻松预测结果的工具类。

分割字符串

1
2
3
4
Splitter.on(',')
    .trimResults()
    .omitEmptyStrings()
    .split("foo,bar,,   qux");