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>21.0</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.