OpenSource-Hub

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

FAQ (5)

informational
Guava의 Maps.newHashMapWithExpectedSize와 Sets.newHashSetWithExpectedSize에 해당하는 JDK API는 무엇인가요?

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을 해결하는 방법

이것은 33.5.0-jre를 포함한 버전에서 발생하는 Guava 버그입니다. Lists.transform()은 spliterator()가 백킹 리스트에 위임하지 않는 AbstractList 뷰를 반환하므로, 백킹 spliterator의 CONCURRENT 특성을 잃고 대신 fail-fast spliterator를 사용하게 됩니다.

업스트림 수정은 TransformingRandomAccessList와 TransformingSequentialList에서 spliterator()를 오버라이드하여 CollectSpliterators.map(fromList.spliterator(), ...)를 사용하도록 합니다. issue #8165에 대한 수정이 포함된 Guava 릴리스가 나오면 업그레이드하세요.

그때까지는 원본 CopyOnWriteArrayList를 스트림으로 만들어 스트림에서 매핑을 적용하세요:

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

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

또는 순회가 소스 iterable에 위임되는 Iterables.transform(cow, function)을 사용하거나, for-each 루프로 순회하세요:

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

CopyOnWriteArrayList의 이터레이터와 spliterator는 weakly consistent하므로, 소스 리스트를 직접 순회해도 ConcurrentModificationException이 발생하지 않습니다.

원본 Issue #8165
informational
Guava의 FluentIterable.toSortedList(Comparator) 정렬은 안정적인가요?

네. FluentIterable.toSortedList(Comparator)는 Ordering.from(comparator).immutableSortedCopy(...)에 위임하며, 이 메서드는 다시 ImmutableList.sortedCopyOf(...)에 위임합니다. 이 메서드들은 안정 정렬(stable sort)을 문서화하고 있으므로, 동등하게 비교되는 요소들은 원래의 탐색 순서를 유지합니다. toSortedList에 해당 설명이 누락된 것은 단순한 Javadoc 누락이었을 뿐이므로, 이 보장이 명시적으로 문서화된 최신 Guava 버전을 사용하세요.

원본 Issue #2884
문제 해결
guava-gwt에서 unpack-dependencies 중 발생하는 Guava 빌드 오류 "Artifact has not been packaged yet"을 어떻게 수정하나요?

Guava 프로젝트 루트에서 package 대신 install을 사용하여 Maven을 실행하세요. 예시:

mvn clean install -DskipTests

guava-gwt 모듈은 maven-dependency-plugin:unpack-dependencies를 사용하며, 이를 위해서는 reactor 종속성이 로컬 Maven 저장소에 설치되어 있어야 합니다. mvn package만 실행하면 MDEP-98이 발생합니다. 이전 모듈들이 이미 설치된 경우 다음 명령으로 재개할 수 있습니다:

mvn install -rf :guava-gwt

원본 Issue #2193
문제 해결
Guava 33.7.0-jre로 JDK 9 또는 10.0.1에서 컴파일할 때 jdk.zipfs JarFileSystem에서 발생하는 NullPointerException을 해결하는 방법은 무엇인가요?

Guava 33.7.0-jre는 매니페스트에 Multi-Release: true를 선언하지만 META-INF/versions/ 디렉터리가 포함되어 있지 않아, 구버전 jdk.zipfs의 버그를 유발합니다. 확인된 해결 방법은 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에 예상되는 멀티 릴리스 파일이 포함되어 있는지 확인하세요:

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

수정된 Guava 릴리스가 사용될 때까지 JDK 9.x 또는 JDK 10.0.1로 컴파일할 때는 Guava 33.7.0-jre를 사용하지 마세요.

원본 Issue #8614