【译】Google Guava 的 Table 接口介绍

2023-06-09 11:07:52 浏览数 (2)

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
代码语言:javascript复制
Table<String, String, Integer> universityCourseSeatTable 
    = HashBasedTable.create();
  • 如果我们需要一个行键和列键按照它们的自然排序或提供比较器进行排序的 Table,可以使用名为TreeBasedTable 的类中的 create 方法创建 Table 的实例,它在内部使用TreeMap
代码语言:javascript复制
Table<String, String, Integer> universityCourseSeatTable
    = TreeBasedTable.create();
  • 如果我们事先知道行键和列键,并且表的大小是固定的,请使用类ArrayTable中的create方法:
代码语言:javascript复制
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类(创建方式采用构建器模式):
代码语言:javascript复制
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中删除元素:

代码语言:javascript复制
@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>>的表示:

代码语言:javascript复制
@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方法从表中获取所有的行键:

代码语言:javascript复制
@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 方法从表中获取所有的列键:

代码语言:javascript复制
@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 的项目,因此可以轻松导入和运行。


0 人点赞