1. 概述
在本教程中,我们将展示如何使用 Google Guava 的 Table
接口及其多个实现。
Guava 的 Table
是一种集合,表示包含行、列和相关单元格值的表结构,行和列充当有序的键对。
2. Google Guava的 Table
让我们看看如何使用 Table 类。
2.1. Maven依赖
首先,在 pom.xml 中添加 Google Guava 库的依赖项:
代码语言:javascript复制<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>
最新版本的依赖项可以在这里查看。
2.2. 核心库中的等价表示
如果我们用 Java 核心库中的 Collections 来表示 Guava 的 Table,那么结构将是一个行的映射,其中每一行包含一个列的映射以及相关的单元格值。
Table 表示一种特殊的映射,其中可以以组合的方式指定两个键来引用单个值。
这类似于创建一个映射的映射,例如 Map<UniversityName, Map<CoursesOffered, SeatAvailable>>
。Table 也是表示战舰游戏棋盘的完美方式。
3. 创建
您可以以多种方式创建 Table
的实例:
- 使用类
HashBasedTable
中的create
方法,它在内部使用LinkedHashMap
:
Table<String, String, Integer> universityCourseSeatTable
= HashBasedTable.create();
- 如果我们需要一个行键和列键按照它们的自然排序或提供比较器进行排序的
Table
,可以使用名为TreeBasedTable
的类中的create
方法创建Table
的实例,它在内部使用TreeMap
:
Table<String, String, Integer> universityCourseSeatTable
= TreeBasedTable.create();
- 如果我们事先知道行键和列键,并且表的大小是固定的,请使用类ArrayTable中的create方法:
List<String> universityRowTable
= Lists.newArrayList("Mumbai", "Harvard");
List<String> courseColumnTables
= Lists.newArrayList("Chemical", "IT", "Electrical");
Table<String, String, Integer> universityCourseSeatTable
= ArrayTable.create(universityRowTable, courseColumnTables);
- 如果我们打算创建
Table
的不可变实例,其内部数据永远不会改变,请使用ImmutableTable
类(创建方式采用构建器模式):
Table<String, String, Integer> universityCourseSeatTable
= ImmutableTable.<String, String, Integer> builder()
.put("Mumbai", "Chemical", 120).build();
4. 使用
让我们从一个简单的示例开始,展示如何使用 Table。
4.1. 检索
如果我们知道行键和列键,那么我们可以获取与行键和列键关联的值:
代码语言:javascript复制@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. 检查元素是否存在
我们可以根据以下方式检查Table中的元素是否存在:
- 行键
- 列键
- 行键和列键都存在
- 值
让我们看看如何检查元素是否存在:
代码语言:javascript复制@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. 删除
我们可以通过提供行键和列键来从Table
中删除元素:
@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. 行键到单元格值的映射
通过提供列键,就可以获取以行键为键、单元格值的 Map 映射。
代码语言:javascript复制@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_表示
我们可以使用 columnMap
方法来获得一个Map<UniversityName, Map<CoursesOffered, SeatAvailable>>
的表示:
@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. 列键到单元格值的映射
我们可以通过提供行键来获取以列键为键,单元格值的 Map 映射:
代码语言:javascript复制@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. 获取不重复的行键
我们可以使用 rowKeySet
方法从表中获取所有的行键:
@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. 获取不重复的列键
我们可以使用 columnKeySet
方法从表中获取所有的列键:
@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. 结论
在本教程中,我们介绍了 Guava 库中 Table 类的方法。Table 类提供了一种集合,表示包含行、列和相关单元格值的表结构。
以上示例的代码可以在GitHub项目中找到,这是一个基于 Maven 的项目,因此可以轻松导入和运行。