Guava: Google Core Libraries for Java

repository·master·Indexed 13 days ago

https://github.com/google/guava

A set of core Google libraries for Java providing advanced collection types (multimaps, multisets, immutable collections), graph libraries, and utilities for concurrency, I/O, and hashing. Available in JRE and Android flavors, including version 33.6.0-jre.

Tokens
2.3K
Snippets
3
Records
12
Agent score
100%

What's inside Guava

  1. Understand Guava API stability and @Beta annotations

    master

    Guava uses the @Beta annotation to signal API stability:

    • @Beta APIs: These are subject to change, modification, or removal at any time. If you are developing a library that will be used by others, avoid using @Beta APIs unless you repackage them. It is strongly recommended to use the Guava Beta Checker to prevent accidental usage.
    • Non-@Beta APIs: These are guaranteed to remain binary-compatible for the indefinite future. This includes @Deprecated APIs that are not marked as @Beta.

    Other important stability notes:

    • Serialization: Serialized forms of ALL objects are subject to change. Do not persist them for long-term use.
    • Security: Guava classes are not designed to protect against malicious callers; do not use them for communication between trusted and untrusted code.
  2. Handle @Beta APIs in Guava Testlib

    master

    APIs marked with the @Beta annotation are subject to change, modification, or removal at any time.

    If you are developing a library that will be used on the CLASSPATH of external users, you should avoid using @Beta APIs. If you must use them, you should [repackage] them to prevent leaking Guava's beta surface to your users.

    To ensure your library does not accidentally depend on beta APIs, it is strongly recommended to use the Guava Beta Checker.

  3. Add Guava Testlib to your build

    master

    Guava testlib provides a set of Java classes designed to make unit testing more convenient. You can include it in your project using Maven or Gradle. Ensure you use the correct scope (test) to avoid including testing utilities in your production runtime.

    <!-- Maven -->
    <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava-testlib</artifactId>
      <version>33.6.0-jre</version>
      <scope>test</scope>
    </dependency>
    
    <!-- Gradle -->
    dependencies {
      test 'com.google.guava:guava-testlib:33.6.0-jre'
    }
  4. Add Guava to your build

    master

    Guava is available in two flavors:

    1. JRE flavor: Requires JDK 1.8 or higher.
    2. Android flavor: For Android support or libraries requiring Android compatibility.

    Specify the flavor by appending -jre or -android to the version number in your dependency configuration.

    ### Maven
    <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
      <version>33.6.0-jre</version>
      <!-- or, for Android: -->
      <version>33.6.0-android</version>
    </dependency>
    
    ### Gradle
    dependencies {
      // Use Guava in your implementation only:
      implementation("com.google.guava:guava:33.6.0-jre")
    
      // Use Guava types in your public API:
      api("com.google.guava:guava:33.6.0-jre")
    
      // Android - Use Guava in your implementation only:
      implementation("com.google.guava:guava:33.6.0-android")
    
      // Android - Use Guava types in your public API:
      api("com.google.guava:guava:33.6.0-android")
    }
  5. Behavior of FilteredMultimap when adding invalid keys

    master

    When using a FilteredMultimap (created via Multimaps.filterKeys), the view enforces the key predicate during mutation attempts.

    If you attempt to add a value to a key that does not satisfy the predicate, the implementation throws an IllegalArgumentException.

    • For SetMultimap views, the add and addAll methods throw IllegalArgumentException with the message: "Key does not satisfy predicate: " + key.
    • For ListMultimap views, the add, add(int, E), and addAll methods throw IllegalArgumentException with the message: "Key does not satisfy predicate: " + key.
  6. Use RowSortedTable for row-ordered table iteration

    master

    A RowSortedTable is an implementation of a Table where the iteration order across row keys is sorted by their natural ordering or by a supplied Comparator.

    Key characteristics:

    • Row Ordering: Iteration across row keys is guaranteed to be sorted.
    • Column Ordering: Iteration across column keys for a single row may or may not be ordered. If you require both rows and columns to be sorted, use TreeBasedTable instead.
    • Enhanced Return Types: Unlike the standard Table interface, rowKeySet() returns a SortedSet and rowMap() returns a SortedMap.
    • Constraints: Null keys and null values are not supported.
  7. Understand the StandardTable implementation

    master

    A StandardTable<R, C, V> is a Table implementation backed by a nested map structure: Map<R, Map<C, V>>. It associates row keys (R) with secondary maps that associate column keys (C) with values (V).

    Performance Characteristics

    • Row Lookups: Fast. Accessing data by row key is highly efficient because the data is stored in a primary map keyed by R.
    • Column Lookups: Slower. Accessing data by column key (e.g., via column(columnKey).get(rowKey)) is still relatively fast because the row key is provided, but operations like column(columnKey).size() require iterating across all row keys.
    • Concurrency: This implementation is not synchronized. If multiple threads access the table concurrently and at least one thread modifies it, you must provide external synchronization.

    Constraints

    • Nulls: Null row keys, column keys, and values are not supported and will result in errors or null returns depending on the method.
    • View Limitations: The views returned by column(columnKey), columnKeySet(), and columnMap() return iterators that do not support remove().
  8. Access Table data by row, column, or cell

    master

    The StandardTable provides several ways to view and interact with its data:

    • Direct Access: Use get(rowKey, columnKey) to retrieve a specific value.
    • Row View: row(rowKey) returns a Map<C, V> representing all columns for that specific row. This map supports mutation (e.g., put, remove, clear).
    • Column View: column(columnKey) returns a Map<R, V> representing all rows for that specific column. This view supports mutation, but its iterator does not support remove().
    • Cell Set: cellSet() returns a Set<Cell<R, C, V>> containing all mappings. Each Cell is an immutable snapshot of a row/column/value triplet.
    • Key Sets:
      • rowKeySet() returns the set of all row keys.
      • columnKeySet() returns the set of all column keys.
    • Maps:
      • rowMap() returns a Map<R, Map<C, V>> view.
      • columnMap() returns a Map<C, Map<R, V>> view.
  9. Use Guava snapshots

    master

    If you need to use the latest build from the master branch, you can use the following Maven version strings:

    • JRE flavor: 999.0.0-HEAD-jre-SNAPSHOT
    • Android flavor: 999.0.0-HEAD-android-SNAPSHOT
  10. Access sorted rows using rowKeySet() and rowMap() in RowSortedTable

    master

    When using a RowSortedTable, you can access the row-based views with sorted guarantees:

    • rowKeySet(): Returns a SortedSet<R> containing the row keys in their sorted order.
    • rowMap(): Returns a SortedMap<R, Map<C, V>> where the keys (rows) are sorted. This allows you to perform range operations like headMap, tailMap, and subMap on the rows.
  11. Filter a Multimap by keys using Multimaps.filterKeys

    master

    To create a view of a Multimap that only contains entries where the keys satisfy a specific Predicate, use the Multimaps.filterKeys(Multimap, Predicate) method.

    This returns a FilteredMultimap, which is a view of the original multimap. Changes to the underlying multimap may be reflected in the filtered view, but attempting to add elements to the filtered view using keys that do not satisfy the predicate will result in an IllegalArgumentException.

    // Example usage of Multimaps.filterKeys
    Multimap<String, Integer> unfiltered = ArrayListMultimap.create();
    unfiltered.put("apple", 1);
    unfiltered.put("banana", 2);
    unfiltered.put("cherry", 3);
    
    // Filter to only include keys starting with 'a' or 'b'
    Multimap<String, Integer> filtered = Multimaps.filterKeys(
        unfiltered, 
        key -> key.startsWith("a") || key.startsWith("b")
    );
    
    // filtered contains: {apple=[1], banana=[2]}