How do you add labels to the result formed by Java 8 groupingby function?

妖精的绣舞 提交于 2019-12-23 04:57:10

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!