Heres what i got to work with:
Map<Faction, List<Resource>>
- Faction is the enum String value of a player faction (e.g "rr" for team red, "bb" for team blue)
- Resources is String enum value of a Resource e.g "Wool", "Lumber"
So the list looks like this right now:
("rr", "wool")
("rr", "wool")
("rr", "lumber")
("bb", "wool")
So my goal is to have a Map<Resource, Integer>
- where Resource is String name of a Resource from an enum
- Integer represents the amount of Resource Cards
Example of target contained values: ("Wool", 4), ("Grain", 3), ("Lumber", 2)
So I'm trying to do this (in pseudocode):
- extract all resources belonging to
Faction
"rr" and put them into a map<Resources, Integer>
where each resource type should be represented once andInteger
represents the sum of the amount ofResource
cards --> repeat this step for 3 more playerFaction
I've played around with streams and foreach loops but have produced no valuable code yet because I struggle yet in the conception phase.
CodePudding user response:
It seems that actual input data in Map<Faction, List<Resource>>
look like:
{rr=[wool, wool, lumber], bb=[lumber, wool, grain]}
Assuming that appropriate enums are used for Resource
and Faction
, the map of resources to their amount can be retrieved using flatMap
for the values in the input map:
Map<Faction, List<Resource>> input; // some input data
Map<Resource, Integer> result = input
.values() // Collection<List<Resource>>
.stream() // Stream<List<Resource>>
.flatMap(List::stream) // Stream<Resource>
.collect(Collectors.groupingBy(
resource -> resource,
LinkedHashMap::new, // optional map supplier to keep insertion order
Collectors.summingInt(resource -> 1)
));
or Collectors.toMap
may be applied:
...
.collect(Collectors.toMap(
resource -> resource,
resource -> 1,
Integer::sum, // merge function to summarize amounts
LinkedHashMap::new // optional map supplier to keep insertion order
));