Guide to Guava Table

1. Overview

In this tutorial, we’ll show how to use the Google Guava’s Table interface and its multiple implementations.

Guava’s Table is a collection that represents a table like structure containing rows, columns and the associated cell values. The row and the column act as an ordered pair of keys.

2. Google Guava’s Table

Let’s have a look at how to use the Table class.

2.1. Maven Dependency

Let’s start by adding Google’s Guava library dependency in the pom.xml:

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

The latest version of the dependency can be checked here.

2.2. About

If we were to represent Guava’s Table using Collections present in core Java, then the structure would be a map of rows where each row contains a map of columns with associated cell values.

Table represents a special map where two keys can be specified in combined fashion to refer to a single value.

It’s similar to creating a map of maps, for example, Map<UniversityName, Map<CoursesOffered, SeatAvailable>>Table would be also a perfect way of representing the Battleships game board.

3. Creating

You can create an instance of Table in multiple ways:

  • Using the create method from the class HashBasedTable which uses LinkedHashMap internally:
Table<String, String, Integer> universityCourseSeatTable 
  = HashBasedTable.create();
  • If we need a Table whose row keys and the column keys need to be ordered by their natural ordering or by supplying comparators, you can create an instance of a Table using the create method from a class called TreeBasedTable, which uses TreeMap internally:
Table<String, String, Integer> universityCourseSeatTable
  = TreeBasedTable.create();
  • If we know the row keys and the column keys beforehand and the table size is fixed, use the create method from the class ArrayTable:
List<String> universityRowTable 
  = Lists.newArrayList("Mumbai", "Harvard");
List<String> courseColumnTables 
  = Lists.newArrayList("Chemical", "IT", "Electrical");
Table<String, String, Integer> universityCourseSeatTable
  = ArrayTable.create(universityRowTable, courseColumnTables);
  • If we intend to create an immutable instance of Table whose internal data are never going to change, use the ImmutableTable class (creating which follows a builder pattern):
Table<String, String, Integer> universityCourseSeatTable
  = ImmutableTable.<String, String, Integer> builder()
  .put("Mumbai", "Chemical", 120).build();

4. Using

Let’s start with a simple example showing the usage of Table.

4.1. Retrieval

If we know the row key and the column key then we can get the value associated with the row and the column key:

@Test
public void givenTable_whenGet_returnsSuccessfully() {
    Table<String, String, Integer> universityCourseSeatTable 
      = HashBasedTable.create();
    universityCourseSeatTable.put("Mumbai", "Chemical", 120);
    universityCourseSeatTable.put("Mumbai", "IT", 60);
    universityCourseSeatTable.put("Harvard", "Electrical", 60);
    universityCourseSeatTable.put("Harvard", "IT", 120);

    int seatCount 
      = universityCourseSeatTable.get("Mumbai", "IT");
    Integer seatCountForNoEntry 
      = universityCourseSeatTable.get("Oxford", "IT");

    assertThat(seatCount).isEqualTo(60);
    assertThat(seatCountForNoEntry).isEqualTo(null);
}

4.2. Checking for an Entry

We can check the presence of an entry in a Table based on:

  • Row key
  • Column key
  • Both row key and column key
  • Value

Let’s see how to check for the presence of an entry:

@Test
public void givenTable_whenContains_returnsSuccessfully() {
    Table<String, String, Integer> universityCourseSeatTable 
      = HashBasedTable.create();
    universityCourseSeatTable.put("Mumbai", "Chemical", 120);
    universityCourseSeatTable.put("Mumbai", "IT", 60);
    universityCourseSeatTable.put("Harvard", "Electrical", 60);
    universityCourseSeatTable.put("Harvard", "IT", 120);

    boolean entryIsPresent
      = universityCourseSeatTable.contains("Mumbai", "IT");
    boolean courseIsPresent 
      = universityCourseSeatTable.containsColumn("IT");
    boolean universityIsPresent 
      = universityCourseSeatTable.containsRow("Mumbai");
    boolean seatCountIsPresent 
      = universityCourseSeatTable.containsValue(60);

    assertThat(entryIsPresent).isEqualTo(true);
    assertThat(courseIsPresent).isEqualTo(true);
    assertThat(universityIsPresent).isEqualTo(true);
    assertThat(seatCountIsPresent).isEqualTo(true);
}

4.3. Removal

We can remove an entry from the Table by supplying both the row key and column key:

@Test
public void givenTable_whenRemove_returnsSuccessfully() {
    Table<String, String, Integer> universityCourseSeatTable
      = HashBasedTable.create();
    universityCourseSeatTable.put("Mumbai", "Chemical", 120);
    universityCourseSeatTable.put("Mumbai", "IT", 60);

    int seatCount 
      = universityCourseSeatTable.remove("Mumbai", "IT");

    assertThat(seatCount).isEqualTo(60);
    assertThat(universityCourseSeatTable.remove("Mumbai", "IT")).
      isEqualTo(null);
}

4.4. Row Key to Cell Value Map

We can get a Map representation with the key as a row and the value as a CellValue by providing the column key:

@Test
public void givenTable_whenColumn_returnsSuccessfully() {
    Table<String, String, Integer> universityCourseSeatTable 
      = HashBasedTable.create();
    universityCourseSeatTable.put("Mumbai", "Chemical", 120);
    universityCourseSeatTable.put("Mumbai", "IT", 60);
    universityCourseSeatTable.put("Harvard", "Electrical", 60);
    universityCourseSeatTable.put("Harvard", "IT", 120);

    Map<String, Integer> universitySeatMap 
      = universityCourseSeatTable.column("IT");

    assertThat(universitySeatMap).hasSize(2);
    assertThat(universitySeatMap.get("Mumbai")).isEqualTo(60);
    assertThat(universitySeatMap.get("Harvard")).isEqualTo(120);
}

4.5. Map Representation of a Table

We can get a Map<UniversityName, Map<CoursesOffered, SeatAvailable>> representation by using the columnMap method:

@Test
public void givenTable_whenColumnMap_returnsSuccessfully() {
    Table<String, String, Integer> universityCourseSeatTable 
      = HashBasedTable.create();
    universityCourseSeatTable.put("Mumbai", "Chemical", 120);
    universityCourseSeatTable.put("Mumbai", "IT", 60);
    universityCourseSeatTable.put("Harvard", "Electrical", 60);
    universityCourseSeatTable.put("Harvard", "IT", 120);

    Map<String, Map<String, Integer>> courseKeyUniversitySeatMap 
      = universityCourseSeatTable.columnMap();

    assertThat(courseKeyUniversitySeatMap).hasSize(3);
    assertThat(courseKeyUniversitySeatMap.get("IT")).hasSize(2);
    assertThat(courseKeyUniversitySeatMap.get("Electrical")).hasSize(1);
    assertThat(courseKeyUniversitySeatMap.get("Chemical")).hasSize(1);
}

4.6. Column Key to Cell Value Map

We can get a Map representation with the key as a column and the value as a CellValue by providing row key:

@Test
public void givenTable_whenRow_returnsSuccessfully() {
    Table<String, String, Integer> universityCourseSeatTable 
      = HashBasedTable.create();
    universityCourseSeatTable.put("Mumbai", "Chemical", 120);
    universityCourseSeatTable.put("Mumbai", "IT", 60);
    universityCourseSeatTable.put("Harvard", "Electrical", 60);
    universityCourseSeatTable.put("Harvard", "IT", 120);

    Map<String, Integer> courseSeatMap 
      = universityCourseSeatTable.row("Mumbai");

    assertThat(courseSeatMap).hasSize(2);
    assertThat(courseSeatMap.get("IT")).isEqualTo(60);
    assertThat(courseSeatMap.get("Chemical")).isEqualTo(120);
}

4.7. Get Distinct Row Key

We can get all the row keys from a table using the rowKeySet method:

@Test
public void givenTable_whenRowKeySet_returnsSuccessfully() {
    Table<String, String, Integer> universityCourseSeatTable
      = HashBasedTable.create();
    universityCourseSeatTable.put("Mumbai", "Chemical", 120);
    universityCourseSeatTable.put("Mumbai", "IT", 60);
    universityCourseSeatTable.put("Harvard", "Electrical", 60);
    universityCourseSeatTable.put("Harvard", "IT", 120);

    Set<String> universitySet = universityCourseSeatTable.rowKeySet();

    assertThat(universitySet).hasSize(2);
}

4.8. Get Distinct Column Key

We can get all column keys from a table using the columnKeySet method:

@Test
public void givenTable_whenColKeySet_returnsSuccessfully() {
    Table<String, String, Integer> universityCourseSeatTable
      = HashBasedTable.create();
    universityCourseSeatTable.put("Mumbai", "Chemical", 120);
    universityCourseSeatTable.put("Mumbai", "IT", 60);
    universityCourseSeatTable.put("Harvard", "Electrical", 60);
    universityCourseSeatTable.put("Harvard", "IT", 120);

    Set<String> courseSet = universityCourseSeatTable.columnKeySet();

    assertThat(courseSet).hasSize(3);
}

5. Conclusion

In this tutorial, we illustrated the methods of the Table class from the Guava library. The Table class provides a collection that represents a table like structure containing rows, columns and associated cell values.

The code belonging to the above examples can be found in the GitHub project – this is a Maven-based project, so it should be easy to import and run as is.

Related posts:

Java Program to Find MST (Minimum Spanning Tree) using Kruskal’s Algorithm
Giới thiệu JDBC Connection Pool
Java Program to Implement SimpeBindings API
Java Program to Implement ScapeGoat Tree
Java – Convert File to InputStream
Biểu thức Lambda trong Java 8 – Lambda Expressions
Serverless Functions with Spring Cloud Function
Java Program to Check Whether a Given Point is in a Given Polygon
Giới thiệu Google Guice – Aspect Oriented Programming (AOP)
Java Program to Implement Sorted Circular Doubly Linked List
Get and Post Lists of Objects with RestTemplate
Jackson – Decide What Fields Get Serialized/Deserialized
Login For a Spring Web App – Error Handling and Localization
Java Program to Solve the Fractional Knapsack Problem
Hướng dẫn Java Design Pattern – Null Object
Java Program to Implement Rolling Hash
Giới thiệu về Stream API trong Java 8
Spring Boot - Tomcat Deployment
A Custom Media Type for a Spring REST API
Java Program to Implement Efficient O(log n) Fibonacci generator
Java Program to Implement Triply Linked List
Collect a Java Stream to an Immutable Collection
Java Program to Give an Implementation of the Traditional Chinese Postman Problem
Spring Cloud – Securing Services
Spring Boot - Google OAuth2 Sign-In
Java Program to Implement Sorted Vector
Java Program to Implement Cartesian Tree
Java Program to Implement LinkedBlockingDeque API
Collect a Java Stream to an Immutable Collection
Java Program to Find Minimum Number of Edges to Cut to make the Graph Disconnected
Hướng dẫn Java Design Pattern – Singleton
Spring Cloud – Adding Angular