Reputation: 53
I have a List of Thing
holding two atrributes : status
(an Enum) and owner
(another object).
I want to obtain a Guava Table<owner, status, Long>
by traversing the ArrayList
and counting the objects, including a count of 0
if some status isn't in the List, like that:
[owner1, status1, 2], [owner1, status2, 0], [owner2, status1, 3], [owner2, status2, 2]
how to use .collect(Tables.toTable())
in that case?
Upvotes: 4
Views: 1059
Reputation: 328598
You need to provide mappers for the rows, columns, values, a merging function and a table supplier. So something like this:
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
));
Upvotes: 2
Reputation: 27525
The below code would create a table with counts, but without zero-counts.
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
)
);
To add the missing cells into the table (with zero-values), you would need to additionally iterate though all the possible values (of Status
and Owner
), and put the 0-value if there's no value yet. Note that, if Owner
isn't an enum, there's no trivial way to get all of its possible values.
Or alternatively, instead of doing this, just check for null
s when retrieving values from the table.
Upvotes: 4