On the follow data structure Nation as below:
public class Nation {
String country;
List<String> States;
For the given sets of nations, intent here is to create a Table with R key country name, C key with state name and value as sum of same state with in the set as show below. Was able to achieve desire results with Map of Map now is it possible to do same with Guava Table ?
public void someMethod() {
String name1 = "US";
String name2 = "Canada";
List<String> states1 = Arrays.asList("CA", "WA");
List<String> state2 = Arrays.asList("BC");
List<String> state3 = Arrays.asList("OR", "CA");
Nation nation1 = new Nation(name1, states1);
Nation nation2 = new Nation(name2, state2);
Nation nation3 = new Nation(name1, state3);
Nation nation4 = new Nation(name2, state2);
Set<Nation> nations = new HashSet<>();
nations.add(nation1);
nations.add(nation2);
nations.add(nation3);
nations.add(nation4);
final Map<String, Map<String, Integer>> nationToStateCount = new HashMap<>();
nations.stream().forEach(nation -> {
nationToStateCount.putIfAbsent(nation.getName(), new HashMap<>());
nation.getState().forEach(state ->{
nationToStateCount.get(nation.getName()).merge(state, 1, Integer::sum);
});
});
// Expected Result
System.out.println(nationToStateCount); // {Canada={BC=2}, US={OR=1, WA=1, CA=2}}
Update: If there is better solution than having if loop and removing and updating values, would be happy to accept that answer.
final Table<String, String, Integer> table = HashBasedTable.create();
nations.stream().forEach(nation -> {
nation.getState().stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.forEach((state, count) -> {
int value = count.intValue();
if(table.contains(nation.getName(), state)) {
value += table.get(nation.getName(), state).intValue();
table.remove(nation.getName(),state);
}
table.put(nation.getName(), state, value);
});
});
Try something like this:
LINK: Guava maven dependency