1. 概述
在这个教程中,我们将展示如何使用Google Guava的Table
接口及其多种实现方式。
Guava的Table
是一个集合,它表示包含行、列和关联的单元格值的表格结构。行和列作为有序的键对。
2. Google Guava的Table
2.1. Maven依赖
首先在pom.xml
中添加Google Guava库的依赖:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.3-jre</version>
</dependency>
最新的依赖版本可以在这里查看。
2.2. 介绍
如果我们使用Java核心库中的Collections
来表示Guava的Table
,那么结构将是一个以行作为键的map,其中每个行包含一个以列为键且带有关联值的map。
Table
表示一个特殊的map,可以同时指定两个键来引用单个值。
它类似于创建一个嵌套map,例如Map<UniversityName, Map<CoursesOffered, SeatAvailable>>
。Table
也是表示战斗舰游戏板的理想方式。
3. 创建
你可以通过多种方式创建Table
实例:
- 使用
HashBasedTable
类的create
方法,它内部使用LinkedHashMap
:Table<String, String, Integer> universityCourseSeatTable = HashBasedTable.create();
- 如果需要
Table
的行键和列键按自然顺序或提供比较器进行排序,可以使用TreeBasedTable
类的create
方法创建实例,它内部使用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. 获取
如果我们知道行键和列键,就可以获取与行和列键关联的值:
@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
中的条目是否存在:
- 行键
- 列键
- 行键和列键
- 值
让我们看看如何检查条目是否存在:
@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. 行键到单元格值的映射
我们可以提供列键,获取一个以行作为键、CellValue
作为值的Map
:
@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. Table
的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. 列键到单元格值的映射
我们可以提供行键,获取一个以列作为键、CellValue
作为值的Map
:
@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的项目,可以直接导入并运行。