In java 8 the idea of grouping objects in a collection based on the values of one or more of their properties is simplified by using a Collector.
First, I suggest you add a new class as follow
class Info {
private String country;
private String city;
private String name;
private int age;
public Info(String country,String city,String name,int age){
this.country=country;
this.city=city;
this.name=name;
this.age=age;
}
public String toString() {
return "("+country+","+city+","+name+","+age+")";
}
// getters and setters
}
Setting up infos
ArrayList<Info> infos =new ArrayList();
infos.add(new Info("USA", "Florida", "John", 26));
infos.add(new Info("USA", "Florida", "James", 18));
infos.add(new Info("USA", "California", "Alan", 30));
Group by Country+City:
Map<String, Map<String, List<Info>>>
groupByCountryAndCity = infos.
stream().
collect(
Collectors.
groupingBy(
Info::getCountry,
Collectors.
groupingBy(
Info::getCity
)
)
);
System.out.println(groupByCountryAndCity.get("USA").get("California"));
Output
[(USA,California,James,18), (USA,California,Alan,30)]
The average Age of the people for each Country+City:
Map<String, Map<String, Double>>
averageAgeByCountryAndCity = infos.
stream().
collect(
Collectors.
groupingBy(
Info::getCountry,
Collectors.
groupingBy(
Info::getCity,
Collectors.averagingDouble(Info::getAge)
)
)
);
System.out.println(averageAgeByCountryAndCity.get("USA").get("Florida"));
Output:
22.0