guava

库

google/guava

Google 核心 Java 库,提供集合、并发等工具。

项目简介

Guava 是 Google 的核心 Java 库,包含新集合类型、不可变集合、图库以及并发、IO、哈希、基础类型、字符串等工具,广泛应用于 Java 项目,同时支持 JRE 与 Android 环境。

README 预览

# Guava: Google Core Libraries for Java\n\n[](https://github.com/google/guava/releases/latest)\n[](https://github.com/google/guava/actions/workflows/ci.yml)\n[](https://www.bestpractices.dev/projects/7197)\n\n\n\nGuava is a set of core Java libraries from Google that includes new collection\ntypes (such as multimap and multiset), immutable collections, a graph library,\nand utilities for concurrency, I/O, hashing, primitives, strings, and more! It\nis widely used on most Java projects within Google, and widely used by many\nother companies as well.\n\n\n\nGuava comes in two flavors:\n\n*   The JRE flavor requires JDK 1.8 or higher.\n*   If you need support for Android, use\n    [the Android flavor](https://github.com/google/guava/wiki/Android). You can\n    find the Android Guava source in the [`android` directory].\n\n[`android` directory]: https://github.com/google/guava/tree/master/android\n\n## Adding Guava to your build\n\nGuava's Maven group ID is `com.google.guava`, and its artifact ID is `guava`.\nGuava provides two different "flavors": one for use on a (Java 8+) JRE and one\nfor use on Android or by any library that wants to be compatible with Android.\nThese flavors are specified in the Maven version field as either `33.6.0-jre` or\n`33.6.0-android`. For more about depending on Guava, see\n[using Guava in your build].\n\nTo add a dependency on Guava using Maven, use the following:\n\n```xml\n\n  com.google.guava\n  guava\n  33.6.0-jre\n  \n  33.6.0-android\n\n```\n\nTo add a dependency using Gradle:\n\n```gradle\ndependencies {\n  // Pick one:\n\n  // 1. Use Guava in your implementation only:\n  implementation("com.google.guava:guava:33.6.0-jre")\n\n  // 2. Use Guava types in your public API:\n  api("com.google.guava:guava:33.6.0-jre")\n\n  // 3. Android - Use Guava in your implementation only:\n  implementation("com.google.guava:guava:33.6.0-android")\n\n  // 4. Android - Use Guava types in your public API:\n  api("com.google.guava:guava:33.6.0-android")\

常见问题 (5)

informational
Guava 的 Maps.newHashMapWithExpectedSize 和 Sets.newHashSetWithExpectedSize 在 JDK 中的等价方法是什么?

使用 Java 19 或更高版本,并调用标准的静态工厂方法:

HashMap<K, V> map = HashMap.newHashMap(expectedSize);
HashSet<E> set = HashSet.newHashSet(expectedSize);

它们替代了:

Maps.newHashMapWithExpectedSize(expectedSize);
Sets.newHashSetWithExpectedSize(expectedSize);

该参数是预期的条目数量,这与 new HashMap<>(capacity) 不同,后者接受的是底层表的容量。在 Java 18 或更早版本中,请继续使用 Guava 方法,或者手动计算初始容量。

来源 Issue #8715
故障排除
如何修复在流式处理 CopyOnWriteArrayList 的 Guava Lists.transform 视图时出现的 ConcurrentModificationException?

这是 Guava 在包括 33.5.0-jre 在内的版本中的一个 bug。Lists.transform() 返回一个 AbstractList 视图,其 spliterator() 不会委托给底层列表,因此会丢失底层 spliterator 的 CONCURRENT 特性,转而使用 fail-fast 的 spliterator。

上游的修复是在 TransformingRandomAccessList 和 TransformingSequentialList 中重写 spliterator(),改用 CollectSpliterators.map(fromList.spliterator(), ...)。请在包含 issue #8165 修复的 Guava 版本发布后及时升级。

在此之前,请直接对原始的 CopyOnWriteArrayList 进行流式操作,并在流上应用映射:

// 不要这样写:
Lists.transform(cow, function).stream().forEach(...);

// 应改为:
cow.stream().map(function).forEach(...);

或者,使用 Iterables.transform(cow, function),它的遍历会委托给源 iterable;也可以用 for-each 循环对其进行迭代:

for (Integer value : Iterables.transform(cow, function)) {
    // ...
}

CopyOnWriteArrayList 的迭代器和 spliterator 是弱一致性的,因此直接遍历源列表不会抛出 ConcurrentModificationException。

来源 Issue #8165
informational
Guava 的 FluentIterable.toSortedList(Comparator) 排序是稳定的吗?

是的。FluentIterable.toSortedList(Comparator) 委托给 Ordering.from(comparator).immutableSortedCopy(...),而后者又委托给 ImmutableList.sortedCopyOf(...)。这些方法的文档中声明了使用稳定排序,因此比较结果相等的元素会保留其原始的遇到顺序。toSortedList 上缺失的说明只是 Javadoc 的疏漏;请使用当前版本的 Guava,该版本中已明确记录了这一保证。

来源 Issue #2884
故障排除
如何修复 guava-gwt 在执行 unpack-dependencies 期间出现的 Guava 构建错误 "Artifact has not been packaged yet"?

从 Guava 项目根目录运行 Maven 时,使用 install 而不是 package,例如:

mvn clean install -DskipTests

guava-gwt 模块使用了 maven-dependency-plugin:unpack-dependencies,这要求 reactor 依赖已安装到本地 Maven 仓库中。仅运行 mvn package 会触发 MDEP-98。如果之前的模块已经安装完成,可以使用以下命令继续构建:

mvn install -rf :guava-gwt

来源 Issue #2193
故障排除
如何修复在 JDK 9 或 10.0.1 上使用 Guava 33.7.0-jre 编译时 jdk.zipfs JarFileSystem 中出现的 NullPointerException?

Guava 33.7.0-jre 在其清单文件(manifest)中声明了 Multi-Release: true,但并未包含 META-INF/versions/,这触发了旧版本 jdk.zipfs 中的一个 bug。已确认的临时解决方案是降级到 Guava 33.6.0-jre。

Maven:

<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>33.6.0-jre</version>
</dependency>

Gradle:

implementation 'com.google.guava:guava:33.6.0-jre'

验证旧版 JAR 是否包含预期的 multi-release 文件:

unzip -l guava-33.6.0-jre.jar | grep META-INF/versions

在使用 JDK 9.x 或 JDK 10.0.1 进行编译时,请避免使用 Guava 33.7.0-jre,直到改用已修复的 Guava 版本。

来源 Issue #8614