"""
Python module generated from Java source file com.google.common.collect.Tables

Java source file obtained from artifact guava version 33.3.1-jre

Because this Python module is automatically generated, it may contain errors
and/or code that cannot be parsed. Please report these issues at
https://github.com/magicmq/docs-translator/issues
"""
from com.google.common.annotations import GwtCompatible
from com.google.common.annotations import J2ktIncompatible
from com.google.common.base import Function
from com.google.common.base import Objects
from com.google.common.base import Supplier
from com.google.common.collect import *
from com.google.common.collect.Table import Cell
from java.io import Serializable
from java.util import Collections
from java.util import Iterator
from java.util import SortedMap
from java.util import SortedSet
from java.util import Spliterator
from java.util.function import BinaryOperator
from java.util.stream import Collector
from javax.annotation import CheckForNull
from org.checkerframework.checker.nullness.qual import Nullable
from typing import Any, Callable, Iterable, Tuple


class Tables:
    """
    Provides static methods that involve a `Table`.
    
    See the Guava User Guide article on <a href=
    "https://github.com/google/guava/wiki/CollectionUtilitiesExplained#tables">`Tables`</a>.

    Author(s)
    - Louis Wasserman

    Since
    - 7.0
    """

    @staticmethod
    def toTable(rowFunction: "java.util.function.Function"["T", "R"], columnFunction: "java.util.function.Function"["T", "C"], valueFunction: "java.util.function.Function"["T", "V"], tableSupplier: "java.util.function.Supplier"["I"]) -> "Collector"["T", Any, "I"]:
        """
        Returns a Collector that accumulates elements into a `Table` created using the
        specified supplier, whose cells are generated by applying the provided mapping functions to the
        input elements. Cells are inserted into the generated `Table` in encounter order.
        
        If multiple input elements map to the same row and column, an `IllegalStateException`
        is thrown when the collection operation is performed.
        
        To collect to an ImmutableTable, use ImmutableTable.toImmutableTable.

        Since
        - 21.0
        """
        ...


    @staticmethod
    def toTable(rowFunction: "java.util.function.Function"["T", "R"], columnFunction: "java.util.function.Function"["T", "C"], valueFunction: "java.util.function.Function"["T", "V"], mergeFunction: "BinaryOperator"["V"], tableSupplier: "java.util.function.Supplier"["I"]) -> "Collector"["T", Any, "I"]:
        """
        Returns a Collector that accumulates elements into a `Table` created using the
        specified supplier, whose cells are generated by applying the provided mapping functions to the
        input elements. Cells are inserted into the generated `Table` in encounter order.
        
        If multiple input elements map to the same row and column, the specified merging function is
        used to combine the values. Like java.util.stream.Collectors.toMap(java.util.function.Function, java.util.function.Function,
        BinaryOperator, java.util.function.Supplier), this Collector throws a `NullPointerException` on null values returned from `valueFunction`, and treats nulls
        returned from `mergeFunction` as removals of that row/column pair.

        Since
        - 21.0
        """
        ...


    @staticmethod
    def immutableCell(rowKey: "R", columnKey: "C", value: "V") -> "Cell"["R", "C", "V"]:
        """
        Returns an immutable cell with the specified row key, column key, and value.
        
        The returned cell is serializable.

        Arguments
        - rowKey: the row key to be associated with the returned cell
        - columnKey: the column key to be associated with the returned cell
        - value: the value to be associated with the returned cell
        """
        ...


    @staticmethod
    def transpose(table: "Table"["R", "C", "V"]) -> "Table"["C", "R", "V"]:
        """
        Creates a transposed view of a given table that flips its row and column keys. In other words,
        calling `get(columnKey, rowKey)` on the generated table always returns the same value as
        calling `get(rowKey, columnKey)` on the original table. Updating the original table
        changes the contents of the transposed table and vice versa.
        
        The returned table supports update operations as long as the input table supports the
        analogous operation with swapped rows and columns. For example, in a HashBasedTable
        instance, `rowKeySet().iterator()` supports `remove()` but `columnKeySet().iterator()` doesn't. With a transposed HashBasedTable, it's the other
        way around.
        """
        ...


    @staticmethod
    def newCustomTable(backingMap: dict["R", dict["C", "V"]], factory: "Supplier"[dict["C", "V"]]) -> "Table"["R", "C", "V"]:
        """
        Creates a table that uses the specified backing map and factory. It can generate a table based
        on arbitrary Map classes.
        
        The `factory`-generated and `backingMap` classes determine the table iteration
        order. However, the table's `row()` method returns instances of a different class than
        `factory.get()` does.
        
        Call this method only when the simpler factory methods in classes like HashBasedTable and TreeBasedTable won't suffice.
        
        The views returned by the `Table` methods Table.column, Table.columnKeySet, and Table.columnMap have iterators that don't support `remove()`. Otherwise, all optional operations are supported. Null row keys, columns keys, and
        values are not supported.
        
        Lookups by row key are often faster than lookups by column key, because the data is stored
        in a `Map<R, Map<C, V>>`. A method call like `column(columnKey).get(rowKey)` still
        runs quickly, since the row key is provided. However, `column(columnKey).size()` takes
        longer, since an iteration across all row keys occurs.
        
        Note that this implementation is not synchronized. If multiple threads access this table
        concurrently and one of the threads modifies the table, it must be synchronized externally.
        
        The table is serializable if `backingMap`, `factory`, the maps generated by
        `factory`, and the table contents are all serializable.
        
        Note: the table assumes complete ownership over of `backingMap` and the maps returned
        by `factory`. Those objects should not be manually updated and they should not use soft,
        weak, or phantom references.

        Arguments
        - backingMap: place to store the mapping from each row key to its corresponding column key
            / value map
        - factory: supplier of new, empty maps that will each hold all column key / value mappings
            for a given row key

        Raises
        - IllegalArgumentException: if `backingMap` is not empty

        Since
        - 10.0
        """
        ...


    @staticmethod
    def transformValues(fromTable: "Table"["R", "C", "V1"], function: "Function"["V1", "V2"]) -> "Table"["R", "C", "V2"]:
        """
        Returns a view of a table where each value is transformed by a function. All other properties
        of the table, such as iteration order, are left intact.
        
        Changes in the underlying table are reflected in this view. Conversely, this view supports
        removal operations, and these are reflected in the underlying table.
        
        It's acceptable for the underlying table to contain null keys, and even null values provided
        that the function is capable of accepting null input. The transformed table might contain null
        values, if the function sometimes gives a null result.
        
        The returned table is not thread-safe or serializable, even if the underlying table is.
        
        The function is applied lazily, invoked when needed. This is necessary for the returned
        table to be a view, but it means that the function will be applied many times for bulk
        operations like Table.containsValue and `Table.toString()`. For this to perform
        well, `function` should be fast. To avoid lazy evaluation when the returned table doesn't
        need to be a view, copy the returned table into a new table of your choosing.

        Since
        - 10.0
        """
        ...


    @staticmethod
    def unmodifiableTable(table: "Table"["R", "C", "V"]) -> "Table"["R", "C", "V"]:
        """
        Returns an unmodifiable view of the specified table. This method allows modules to provide
        users with "read-only" access to internal tables. Query operations on the returned table "read
        through" to the specified table, and attempts to modify the returned table, whether direct or
        via its collection views, result in an `UnsupportedOperationException`.
        
        The returned table will be serializable if the specified table is serializable.
        
        Consider using an ImmutableTable, which is guaranteed never to change.

        Since
        - 11.0
        """
        ...


    @staticmethod
    def unmodifiableRowSortedTable(table: "RowSortedTable"["R", "C", "V"]) -> "RowSortedTable"["R", "C", "V"]:
        """
        Returns an unmodifiable view of the specified row-sorted table. This method allows modules to
        provide users with "read-only" access to internal tables. Query operations on the returned
        table "read through" to the specified table, and attempts to modify the returned table, whether
        direct or via its collection views, result in an `UnsupportedOperationException`.
        
        The returned table will be serializable if the specified table is serializable.

        Arguments
        - table: the row-sorted table for which an unmodifiable view is to be returned

        Returns
        - an unmodifiable view of the specified table

        Since
        - 11.0
        """
        ...


    @staticmethod
    def synchronizedTable(table: "Table"["R", "C", "V"]) -> "Table"["R", "C", "V"]:
        """
        Returns a synchronized (thread-safe) table backed by the specified table. In order to guarantee
        serial access, it is critical that **all** access to the backing table is accomplished
        through the returned table.
        
        It is imperative that the user manually synchronize on the returned table when accessing any
        of its collection views:
        
        ````Table<R, C, V> table = Tables.synchronizedTable(HashBasedTable.<R, C, V>create());
        ...
        Map<C, V> row = table.row(rowKey);  // Needn't be in synchronized block
        ...
        synchronized (table) {  // Synchronizing on table, not row!
          Iterator<Entry<C, V>> i = row.entrySet().iterator(); // Must be in synchronized block
          while (i.hasNext()) {
            foo(i.next());`
        }
        }```
        
        Failure to follow this advice may result in non-deterministic behavior.
        
        The returned table will be serializable if the specified table is serializable.

        Arguments
        - table: the table to be wrapped in a synchronized view

        Returns
        - a synchronized view of the specified table

        Since
        - 22.0
        """
        ...
