| 
 | 
 
精通Google Guava库二维映射表Table,提升编程效率的API利器 
Java开发中常使用Map来存储键值对,其键是唯一的,可快速查找对应的值。但某些场景下需要更复杂的映射结构,其中键由两部分组成,类似于一个二维表格的行和列。Guava库中的Table接口正是为了满足这种需求而设计的。  
一、什么是Guava TableGuava的Table是一种特殊的数据结构,它用两个键(行键和列键)来映射一个值。可将Table视为二维的Map,其中每个单元格都由行键和列键唯一确定,并存储一个值。 二、Guava Table的实现类Guava提供了几种Table的实现类: HashBasedTable:最常用的实现,它基于哈希表来存储数据。HashBasedTable提供了快速的插入、查找和删除操作,并且不保证键顺序。 TreeBasedTable:实现基于红黑树,根据键的自然顺序或者提供的比较器对行键和列键进行排序。TreeBasedTable在按键顺序遍历数据时非常高效,但插入和查找操作可能比哈希表慢。 ImmutableTable:不可变的Table实现,在创建时接收所有数据,之后不允许修改。ImmutableTable对于需要共享或发布不可变数据集的情况非常有用,同时它提供了高效的内存使用。  
 三、如何使用Guava Table来个DEMO创建Table、添加数据、检索数据、修改数据、遍历数据,以及一些其他高级特性的使用。 - import com.google.common.collect.HashBasedTable;  
 
 - import com.google.common.collect.Table;  
 
 -   
 
 - import java.util.Map;  
 
 - import java.util.Set;  
 
 -   
 
 - public class GuavaTableAdvancedExample {  
 
 -   
 
 -     public static void main(String[] args) {  
 
 -         // 创建一个Table实例  
 
 -         Table<String, String, Integer> workHoursTable = HashBasedTable.create();  
 
 -   
 
 -         // 添加数据  
 
 -         workHoursTable.put("Alice", "ProjectA", 40);  
 
 -         workHoursTable.put("Bob", "ProjectA", 30);  
 
 -         workHoursTable.put("Alice", "ProjectB", 20);  
 
 -         workHoursTable.put("Charlie", "ProjectC", 50);  
 
 -   
 
 -         // 检索数据  
 
 -         Integer aliceProjectAHours = workHoursTable.get("Alice", "ProjectA");  
 
 -         System.out.println("Alice worked " + aliceProjectAHours + " hours on ProjectA.");  
 
 -   
 
 -         // 使用row()方法获取特定行的映射  
 
 -         Map<String, Integer> aliceWorkHours = workHoursTable.row("Alice");  
 
 -         System.out.println("Alice's work hours: " + aliceWorkHours);  
 
 -   
 
 -         // 使用column()方法获取特定列的映射  
 
 -         Map<String, Integer> projectAWorkHours = workHoursTable.column("ProjectA");  
 
 -         System.out.println("Work hours on ProjectA: " + projectAWorkHours);  
 
 -   
 
 -         // 遍历表格  
 
 -         for (Table.Cell<String, String, Integer> cell : workHoursTable.cellSet()) {  
 
 -             System.out.println(cell.getRowKey() + " worked " + cell.getValue() + " hours on " + cell.getColumnKey() + ".");  
 
 -         }  
 
 -   
 
 -         // 修改数据  
 
 -         workHoursTable.put("Alice", "ProjectA", aliceProjectAHours + 5); 
 
 -         // Alice在ProjectA上多工作了5小时  
 
 -         System.out.println("After update, Alice worked " + workHoursTable.get("Alice", "ProjectA") + " hours on ProjectA.");  
 
 -   
 
 -         // 检查是否包含某个键值对  
 
 -         boolean hasBobOnProjectB = workHoursTable.contains("Bob", "ProjectB");  
 
 -         System.out.println("Does Bob work on ProjectB? " + hasBobOnProjectB);  
 
 -   
 
 -         // 检查行键或列键是否存在  
 
 -         boolean hasRowKeyCharlie = workHoursTable.containsRow("Charlie");  
 
 -         boolean hasColumnKeyProjectD = workHoursTable.containsColumn("ProjectD");  
 
 -         System.out.println("Does the table have a row for Charlie? " + hasRowKeyCharlie);  
 
 -         System.out.println("Does the table have a column for ProjectD? " + hasColumnKeyProjectD);  
 
 -   
 
 -         // 获取所有的行键、列键或值  
 
 -         Set<String> allRowKeys = workHoursTable.rowKeySet();  
 
 -         Set<String> allColumnKeys = workHoursTable.columnKeySet();  
 
 -         Set<Integer> allValues = workHoursTable.values();  
 
 -   
 
 -         System.out.println("All row keys: " + allRowKeys);  
 
 -         System.out.println("All column keys: " + allColumnKeys);  
 
 -         System.out.println("All values: " + allValues);  
 
 -   
 
 -         // 移除数据  
 
 -         workHoursTable.remove("Alice", "ProjectB"); 
 
 -         // Alice不再在ProjectB上工作  
 
 -         System.out.println("After removal, Alice's work hours on ProjectB: " + workHoursTable.get("Alice", "ProjectB"));  
 
 -     }  
 
 - }
 
 
  复制代码如果不使用table,那就需要用嵌套Map实现 与Guava Table相比,嵌套的Map在处理某些操作时会更繁琐,例如检查列键是否存在,需要遍历所有的内部Map。嵌套的Map也没有Guava Table提供的一些高级功能和优化。 - // 创建嵌套Map来模拟Table  
 
 -         Map<String, Map<String, Integer>> workHoursMap = new HashMap<>();  
 
 -   
 
 -         // 添加数据  
 
 -         addWorkHours(workHoursMap, "Alice", "ProjectA", 40);  
 
 -         addWorkHours(workHoursMap, "Bob", "ProjectA", 30);  
 
 -         addWorkHours(workHoursMap, "Alice", "ProjectB", 20);  
 
 -         addWorkHours(workHoursMap, "Charlie", "ProjectC", 50);  
 
 -   
 
 -         // 检索数据  
 
 -         Integer aliceProjectAHours = getWorkHours(workHoursMap, "Alice", "ProjectA");  
 
 -         System.out.println("Alice worked " + aliceProjectAHours + " hours on ProjectA.");  
 
 -   
 
 -         // 遍历嵌套Map  
 
 -         for (Map.Entry<String, Map<String, Integer>> entry : workHoursMap.entrySet()) {  
 
 -             String employee = entry.getKey();  
 
 -             Map<String, Integer> projects = entry.getValue();  
 
 -             for (Map.Entry<String, Integer> projectEntry : projects.entrySet()) {  
 
 -                 String project = projectEntry.getKey();  
 
 -                 Integer hours = projectEntry.getValue();  
 
 -                 System.out.println(employee + " worked " + hours + " hours on " + project + ".");  
 
 -             }  
 
 -         }  
 
 -   
 
 -         // 修改数据  
 
 -         setWorkHours(workHoursMap, "Alice", "ProjectA", aliceProjectAHours + 5); 
 
 -         
 
 -         // Alice在ProjectA上多工作了5小时  
 
 -         System.out.println("After update, Alice worked " + getWorkHours(workHoursMap, "Alice", "ProjectA") + " hours on ProjectA.");  
 
 -   
 
 -         // 检查是否包含某个键值对  
 
 -         boolean hasBobOnProjectB = containsWorkHours(workHoursMap, "Bob", "ProjectB");  
 
 -         System.out.println("Does Bob work on ProjectB? " + hasBobOnProjectB);  
 
 -   
 
 -         // 检查行键是否存在  
 
 -         boolean hasRowKeyCharlie = workHoursMap.containsKey("Charlie");  
 
 -         System.out.println("Does the nested map have an entry for Charlie? " + hasRowKeyCharlie);  
 
 -   
 
 -         // 检查列键是否存在(需要遍历所有内部Map)  
 
 -         boolean hasColumnKeyProjectD = false;  
 
 -         for (Map<String, Integer> projectMap : workHoursMap.values()) {  
 
 -             if (projectMap.containsKey("ProjectD")) {  
 
 -                 hasColumnKeyProjectD = true;  
 
 -                 break;  
 
 -             }  
 
 -         }  
 
 -         System.out.println("Does any employee work on ProjectD? " + hasColumnKeyProjectD);  
 
 -   
 
 -         // 移除数据  
 
 -         removeWorkHours(workHoursMap, "Alice", "ProjectB"); // Alice不再在ProjectB上工作  
 
 -         System.out.println("After removal, Alice's work hours on ProjectB: " + getWorkHours(workHoursMap, "Alice", "ProjectB"));  
 
 -     }  
 
 -   
 
 -     private static void addWorkHours(Map<String, Map<String, Integer>> workHoursMap, String rowKey, String columnKey, Integer value) {  
 
 -         workHoursMap.putIfAbsent(rowKey, new HashMap<>());  
 
 -         workHoursMap.get(rowKey).put(columnKey, value);  
 
 -     }  
 
 -   
 
 -     private static Integer getWorkHours(Map<String, Map<String, Integer>> workHoursMap, String rowKey, String columnKey) {  
 
 -         Map<String, Integer> projectMap = workHoursMap.get(rowKey);  
 
 -         return projectMap != null ? projectMap.get(columnKey) : null;  
 
 -     }  
 
 -   
 
 -     private static void setWorkHours(Map<String, Map<String, Integer>> workHoursMap, String rowKey, String columnKey, Integer value) {  
 
 -         workHoursMap.putIfAbsent(rowKey, new HashMap<>());  
 
 -         workHoursMap.get(rowKey).put(columnKey, value);  
 
 -     }  
 
 -   
 
 -     private static boolean containsWorkHours(Map<String, Map<String, Integer>> workHoursMap, String rowKey, String columnKey) {  
 
 -         Map<String, Integer> projectMap = workHoursMap.get(rowKey);  
 
 -         return projectMap != null && projectMap.containsKey(columnKey);  
 
 -     }  
 
 -   
 
 -     private static void removeWorkHours(Map<String, Map<String, Integer>> workHoursMap, String rowKey, String columnKey) {  
 
 -         Map<String, Integer> projectMap = workHoursMap.get(rowKey);  
 
 -         if (projectMap != null) {  
 
 -             projectMap.remove(columnKey);  
 
 -             if (projectMap.isEmpty()) {  
 
 -                 workHoursMap.remove(rowKey);  
 
 -             }  
 
 -         }  
 
 -     }  
 
  复制代码 四、Guava Table的优势使用Guava的Table而不是嵌套的Map有几个优势: - 类型安全:Table明确指定了行键、列键和值的类型,减少了类型转换的错误。
 - 更易用:Table提供了直观的API来插入、检索和遍历数据,使代码更易于阅读和维护。
 - 内存效率:Table实现类针对其特定用途进行了优化,以提供高效的内存使用。
 - 不变性:通过ImmutableTable可以创建不可变的表格,对并发编程和不可变对象模式非常有用。
 
 
  
 
 
 |   
 
 
 
 |