guava

Library

google/guava

Google core Java libraries with collections, concurrency, and utilities.

Overview

Guava is a set of core Java libraries from Google, including new collection types, immutable collections, a graph library, and utilities for concurrency, I/O, hashing, primitives, strings, and more. It is widely used in Java projects and supports both JRE and Android environments.

README Preview

# 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")\

FAQ (5)

informational
What is the JDK equivalent of Guava's Maps.newHashMapWithExpectedSize and Sets.newHashSetWithExpectedSize?

Use Java 19 or later and call the standard static factory methods:

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

These replace:

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

The argument is the expected number of entries, unlike new HashMap<>(capacity), which accepts the underlying table capacity. On Java 18 or older, keep using the Guava methods or manually calculate the initial capacity.

GitHub Issue #8715
Troubleshooting
How to fix ConcurrentModificationException when streaming a Guava Lists.transform view of CopyOnWriteArrayList?

This is a Guava bug in versions including 33.5.0-jre. Lists.transform() returns an AbstractList view whose spliterator() does not delegate to the backing list, so it loses the backing spliterator's CONCURRENT characteristic and uses a fail-fast spliterator instead.

The upstream fix overrides spliterator() in TransformingRandomAccessList and TransformingSequentialList to use CollectSpliterators.map(fromList.spliterator(), ...). Upgrade to a Guava release containing the fix for issue #8165 when available.

Until then, stream the original CopyOnWriteArrayList and apply the mapping on the stream:

// Instead of:
Lists.transform(cow, function).stream().forEach(...);

// Use:
cow.stream().map(function).forEach(...);

Alternatively, use Iterables.transform(cow, function), whose traversal delegates to the source iterable, or iterate it with a for-each loop:

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

CopyOnWriteArrayList iterators and spliterators are weakly consistent, so direct traversal of the source list should not throw ConcurrentModificationException.

GitHub Issue #8165
informational
Is Guava's FluentIterable.toSortedList(Comparator) sort stable?

Yes. FluentIterable.toSortedList(Comparator) delegates to Ordering.from(comparator).immutableSortedCopy(...), which delegates to ImmutableList.sortedCopyOf(...). Those methods document a stable sort, so elements that compare equal retain their original encounter order. The missing statement on toSortedList was only a Javadoc gap; use a current Guava version where this guarantee is explicitly documented.

GitHub Issue #2884
Troubleshooting
How do I fix the Guava build error "Artifact has not been packaged yet" in guava-gwt during unpack-dependencies?

Run Maven with install instead of package from the Guava project root, for example:

mvn clean install -DskipTests

The guava-gwt module uses maven-dependency-plugin:unpack-dependencies, which requires reactor dependencies to be installed in the local Maven repository. Running only mvn package triggers MDEP-98. If the earlier modules have already been installed, you can resume with:

mvn install -rf :guava-gwt

GitHub Issue #2193
Troubleshooting
How to fix the NullPointerException in jdk.zipfs JarFileSystem when compiling with Guava 33.7.0-jre on JDK 9 or 10.0.1?

Guava 33.7.0-jre declares Multi-Release: true in its manifest but does not contain META-INF/versions/, triggering a bug in old jdk.zipfs versions. The confirmed workaround is to downgrade to 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'

Verify the older JAR contains the expected multi-release files:

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

Avoid Guava 33.7.0-jre when compiling with JDK 9.x or JDK 10.0.1 until a fixed Guava release is used.

GitHub Issue #8614