问题
I currently have a class,
public class Person {
private String country;
private String age;
private String name;
}
Taking a List of this Person class as a argument,
List<Person>
I managed to group them in the following data structure using Java 8 group by (collection) function :
Map<String, Map<String, Set<String>>>
Example:
USA={
21=
[
John,
Peter.
Andrew
],
22=
[
Eric,
Mark
]
]
},
France = {
etc....
Below is my function :
public static Map<String, Map<String, Set<String>>> getNestedMap(List<Person> persons) {
return persons.stream().collect(
groupingBy(Person::getCountry,
groupingBy(Person::getAge,
mapping(Person::getName, toSet())
)));
}
However, I wanted my data structure to look like this, with labels for each level. Is there a way Java 8 group by (collection) can help achieve this? or is there better way?
Country = USA,
AgeList = {
Age = 21,
People =
[
[Name = John],
[Name = Peter],
[Name = Andrew]
],
Age = 22,
People =
[
[Name = Eric],
[Name = Mark]
]
]
},
Country = France,
AgeList = {
etc....
回答1:
You've started with an input (a series of Person
instances) and a tool (.groupingBy()
), rather than an input and a desired output. Identify that first, then determine which tool(s) are the most appropriate way to transform the input into the desired output.
For example, you might want to end up with a Country
object, that contains a name and a list of Age
objects, each of which contains an age and a set of People
objects. With that resulting structure in mind you could you could do a single .groupingBy()
pass to group by country, and pass the resulting lists into a Country(String name, List<Person> people)
constructor, which then in turn does another .groupingBy()
pass to group by age, and invokes an Age(int age, List<Person>)
constructor.
If your goal is to then serialize this structure into a JSON-ish string, you can easily do so in Country.toString()
, now that you have the data in the structure you need.
It's always a good idea to separate structural concerns (like transforming from a List<Foo>
to something complex like a Map<Bar, Map<Baz, Set<Foo>>>
) from representational concerns (like then rendering a string representation of that complex structure). You'll find solving the two steps separately is often significantly easier - and easier to maintain - than doing it all in one fell swoop.
来源:https://stackoverflow.com/questions/45557205/how-do-you-add-labels-to-the-result-formed-by-java-8-groupingby-function