使用 Guava 的 Tables.toTable

Using Guava's Tables.toTable

我有一个包含两个属性的 Thing 列表:status(枚举)和 owner(另一个对象)。

我想通过遍历 ArrayList 并计算对象数量来获得一个 Guava Table<owner, status, Long>,如果某些状态不在列表中,则包括 0 的计数,就像这样:

[owner1, status1, 2], [owner1, status2, 0], [owner2, status1, 3], [owner2, status2, 2]

在那种情况下如何使用 .collect(Tables.toTable())

下面的代码将创建一个 table 有计数,但 没有零计数

List<Thing> listOfThings = ...;

Table<Owner, Status, Long> table = 
    listOfThings.stream().collect(
        Tables.toTable(
            Thing::getOwner,             // Row key extractor
            Thing::getStatus,            // Column key extractor
            thing -> 1,                  // Value converter (a single value counts '1')
            (count1, count2) -> count1 + count2, // Value merger (counts add up)
            HashBasedTable::create       // Table creator
        )
    );

要将缺失的单元格添加到 table(零值)中,您需要另外遍历所有可能的值(StatusOwner),如果还没有值,则输入 0 值。请注意,如果 Owner 不是枚举,则没有简单的方法来获取其所有可能的值。

或者,不这样做,只需在从 table 检索值时检查 nulls。

您需要为行、列、值、合并函数和 table 供应商提供映射器。所以像这样:

list.stream().collect(Tables.toTable(
               Thing::getStatus,
               Thing::getOwner,
               t -> 1, //that's your counter
               (i, j) -> i + j, //that's the incrementing function
               HashBasedTable::create //a new table
            ));