# Guava中的类型增强
Map - Table、BiMap、Multimap、RangeMap、ClassToInstanceMap
#### 1. 简介[#](https://www.cnblogs.com/cao-lei/p/17806222.html#3979976375)
日常开发中使用Map时经常会遇到很多复杂的处理场景,例如:多个键的Map、不仅可以根据键获取值也可以根据值获取键且不用遍历、重复键的Map、数字等范围内映射相同的值、内存中缓存对象等,Guava提供了以上场景的解决方案。
| 场景 | 解决方案 | 具体实现 |
| ------------------------------------------------ | ------------------ | ------------------------------------------------------------ |
| 多个键的Map | Table | HashBasedTable、TreeBasedTable、ImmutableTable |
| 不仅可以根据键获取值也可以根据值获取键且不用遍历 | BiMap | HashBiMap、ImmutableBiMap |
| 重复键的Map | Multimap | ArrayListMultimap、LinkedListMultimap、LinkedHashMultimap、ImmutableListMultimap、ImmutableSetMultimap |
| 数字等范围内映射相同的值 | RangeMap | TreeRangeMap、ImmutableRangeMap |
| 内存中缓存对象 | ClassToInstanceMap | MutableClassToInstanceMap、ImmutableClassToInstanceMap |
本博客将详细描述具体的示例代码。
#### 2. 添加依赖[#](https://www.cnblogs.com/cao-lei/p/17806222.html#1443701749)
Maven项目pom.xml中添加依赖:
```xml
Copy
com.google.guava
guava
32.0.0-jre
```
#### 3. Tbale - 表结构数据[#](https://www.cnblogs.com/cao-lei/p/17806222.html#848306248)
官方注释翻译:将一对有序键(称为行键和列键)与单个值相关联的集合。
示例代码(需求: 记录各个公司每个部门的人数):
```swift
Copy// HashMap
Map deptMap = new HashMap<>();
deptMap.put("A部门", 10);
deptMap.put("B部门", 20);
Map> companyMap = new HashMap<>();
companyMap.put("xx公司", deptMap);
// HashMap 获取值
Integer val = companyMap.get("xx公司").get("A部门");
System.out.println("HashMap 获取值: " + val);
// 创建Hash类型Table, 基于Hash表实现
// Table中三个泛型: R-行, C-列, V-值
Table hashTable = HashBasedTable.create();
hashTable.put("xx公司", "A部门", 10);
hashTable.put("xx公司", "B部门", 20);
hashTable.put("xx公司", "C部门", 30);
System.out.println("\nHash Table: " + hashTable);
// 创建Tree类型Table, 基于红黑树实现
Table treeTable = TreeBasedTable.create();
treeTable.put("xx公司", "C部门", 30);
treeTable.put("xx公司", "B部门", 20);
treeTable.put("xx公司", "A部门", 10);
System.out.println("\nTree Table: " + treeTable);
// 创建不可变Table, 无法新增、更新或删除
Table immutableTable = ImmutableTable.builder()
.put("xx公司", "C部门", 30)
.put("xx公司", "B部门", 20)
.put("xx公司", "A部门", 10)
.build();
System.out.println("\nImmutable Table: " + immutableTable);
// Table 获取值
Integer val2 = hashTable.get("xx公司", "A部门");
System.out.println("\nTable 获取值: " + val2);
// Table 删除值
Integer remove = hashTable.remove("xx公司", "C部门");
System.out.println("\nTable 删除值: " + remove);
// 根据行获取列和值映射
Map columnvalueMap = hashTable.row("xx公司");
System.out.println("\nTable 列和值 映射: " + columnvalueMap);
// 根据列获取行和值映射
Map rowvalueMap = hashTable.column("A部门");
System.out.println("\nTable 行和值 映射: " + rowvalueMap);
// 获取key集合
Set rowKeySet = hashTable.rowKeySet();
System.out.println("\nTable Row key 集合: " + rowKeySet);
Set columnKeySet = hashTable.columnKeySet();
System.out.println("\nTable Column key 集合: " + columnKeySet);
// 获取值集合
Collection values = hashTable.values();
System.out.println("\nTable 值集合: " + values);
// 判断包含行
boolean containsRow = hashTable.containsRow("xx公司");
System.out.println("\nTable 包含行: " + containsRow);
// 判断包含列
boolean containsColumn = hashTable.containsColumn("A部门");
System.out.println("\nTable 包含列: " + containsColumn);
// 判断包含行和列
boolean contains = hashTable.contains("xx公司", "A部门");
System.out.println("\nTable 包含行和列: " + contains);
// 判断包含值
boolean containsValue = hashTable.containsValue(10);
System.out.println("\nTable 包含值: " + containsValue);
// 行和列转置 - 行 转 列
Table transposeTable = Tables.transpose(hashTable);
// 获取所有的行
Set> cells = transposeTable.cellSet();
// 遍历输出
System.out.println("\n遍历输出开始----------------------------");
cells.forEach(cell -> System.out.println(cell.getRowKey() + ", " + cell.getColumnKey() + ", " + cell.getValue()));
System.out.println("\n遍历输出结束----------------------------");
// 转换为嵌套的Map
Map> rowMap = hashTable.rowMap();
System.out.println("\nTable RowMap: " + rowMap);
Map> columnMap = hashTable.columnMap();
System.out.println("\nTable ColumnMap: " + columnMap);
```
执行结果:
```yaml
CopyHashMap 获取值: 10
Hash Table: {xx公司={A部门=10, B部门=20, C部门=30}}
Tree Table: {xx公司={A部门=10, B部门=20, C部门=30}}
Immutable Table: {xx公司={C部门=30, B部门=20, A部门=10}}
Table 获取值: 10
Table 删除值: 30
Table 列和值 映射: {A部门=10, B部门=20}
Table 行和值 映射: {xx公司=10}
Table Row key 集合: [xx公司]
Table Column key 集合: [A部门, B部门]
Table 值集合: [10, 20]
Table 包含行: true
Table 包含列: true
Table 包含行和列: true
Table 包含值: true
遍历输出开始----------------------------
A部门, xx公司, 10
B部门, xx公司, 20
遍历输出结束----------------------------
Table RowMap: {xx公司={A部门=10, B部门=20}}
Table ColumnMap: {A部门={xx公司=10}, B部门={xx公司=20}}
```
#### 4. BiMap - 双向映射Map[#](https://www.cnblogs.com/cao-lei/p/17806222.html#2347438548)
官方注释翻译:双映射(或“双向映射”)是一种保留其值及其键的唯一性的映射。此约束使双映射能够支持“反向视图”,即另一个双映射,其中包含与此双映射相同的条目,但具有相反的键和值。
示例代码(需求: 数组和英文翻译):
```csharp
Copy// 创建BiMap, 底层为两个Hash表的Map
BiMap biMap = HashBiMap.create();
biMap.put(1, "one");
biMap.put(2, "two");
biMap.put(3, "three");
biMap.put(4, "four");
biMap.put(5, "five");
System.out.println("BiMap: " + biMap);
// 创建不可变BiMap, 无法新增、更新或删除
BiMap