按映射的java列表中的动态列数分组
我有以下按映射的java列表中的动态列数分组,java,group-by,java-stream,Java,Group By,Java Stream,我有以下aList对象: List<Map<String,String>> aList = new ArrayList<>(); Map<String,String> mapOne= new HashMap<>(); Map<String,String> mapTwo= new HashMap<>(); mapOne.put("Name","John"); mapOne.p
aList
对象:
List<Map<String,String>> aList = new ArrayList<>();
Map<String,String> mapOne= new HashMap<>();
Map<String,String> mapTwo= new HashMap<>();
mapOne.put("Name","John");
mapOne.put("Age","30");
mapOne.put("City","Kolkata");
mapTwo.put("Name","Jack");
mapTwo.put("Age","31");
mapTwo.put("City","Kolkata");
aList.add(mapOne);
aList.add(mapTwo);
但正如您所注意到的,这里我只能按
城市
分组,但用户应该可以选择按其他属性分组,如姓名
,年龄
等。因此,当我不知道用户将根据哪些属性和多少属性进行分组时,如何返回结果?当存在多个条件时,您似乎希望返回一个映射
您可以使用groupingBy
分类器返回带有所需字段值的映射,然后根据该列表进行分组
Map<List<String>, List<Collection<String>>> city = aList.stream()
.collect(Collectors.groupingBy(map -> List.of(map.get("City"), map.get("Age")),
Collectors.mapping(Map::values, Collectors.toList())));
System.out.println(city);
如果您使用的是Java<9,请将(..)列表替换为Arrays.asList(..)
为了使其动态化,您可以将构建分类器函数的逻辑移动到一个方法中,并为每个映射调用它
private static List<String> buildClassificationFunction(Map<String,String> map, List<String> fields) {
return fields.stream()
.map(map::get)
.collect(Collectors.toList());
}
List<String> fields = List.of("City", "Age"); //This will be constructed as per user's wish
Map<List<String>, List<Collection<String>>> city = aList.stream()
.collect(Collectors.groupingBy(map ->
buildClassificationFunction(map, fields), //Call the function to build the list
Collectors.mapping(Map::values, Collectors.toList())));
私有静态列表buildClassificationFunction(映射、列表字段){
返回字段。stream()
.map(map::get)
.collect(Collectors.toList());
}
列表字段=列表(“城市”、“年龄”)//这将根据用户的意愿进行构建
Map city=aList.stream()
.collect(收集器)。分组方式(地图->
buildClassificationFunction(映射,字段),//调用该函数以生成列表
Collectors.mapping(Map::values,Collectors.toList());
当存在多个条件时,似乎要返回一个映射
您可以使用groupingBy
分类器返回带有所需字段值的映射,然后根据该列表进行分组
Map<List<String>, List<Collection<String>>> city = aList.stream()
.collect(Collectors.groupingBy(map -> List.of(map.get("City"), map.get("Age")),
Collectors.mapping(Map::values, Collectors.toList())));
System.out.println(city);
如果您使用的是Java<9,请将(..)列表替换为Arrays.asList(..)
为了使其动态化,您可以将构建分类器函数的逻辑移动到一个方法中,并为每个映射调用它
private static List<String> buildClassificationFunction(Map<String,String> map, List<String> fields) {
return fields.stream()
.map(map::get)
.collect(Collectors.toList());
}
List<String> fields = List.of("City", "Age"); //This will be constructed as per user's wish
Map<List<String>, List<Collection<String>>> city = aList.stream()
.collect(Collectors.groupingBy(map ->
buildClassificationFunction(map, fields), //Call the function to build the list
Collectors.mapping(Map::values, Collectors.toList())));
私有静态列表buildClassificationFunction(映射、列表字段){
返回字段。stream()
.map(map::get)
.collect(Collectors.toList());
}
列表字段=列表(“城市”、“年龄”)//这将根据用户的意愿进行构建
Map city=aList.stream()
.collect(收集器)。分组方式(地图->
buildClassificationFunction(映射,字段),//调用该函数以生成列表
Collectors.mapping(Map::values,Collectors.toList());
@user7,是的,我理解,但问题是它可能只是城市
,或者是城市
和名称
的组合……这怎么可能是组合呢?在这种情况下,是否要返回两个Map
?@user7我只需要Map,我将在前端为用户打印值。关键可以是用户选择的组合,因此它当然应该更改为Map
您可以展示一个例子,说明多个标准的结果是什么样子吗?@user7所以现在它的打印方式是{Kolkata=[[Kolkata,30,John],[Kolkata,31,Jack]}
我在想象多个组,例如城市和年龄,它应该看起来像{[Kolkata,30]=[[Kolkata,30,John]]}{[Kolkata,31]=[[Kolkata,31,Jack]]}
所以我很抱歉,结果可能会像列表`@user7,是的,我理解,但问题是它可能只是城市
,或者是城市
和名称
的组合……这怎么可能是组合呢?在这种情况下,是否要返回两个Map
?@user7我只需要Map,我将在前端为用户打印值。关键可以是用户选择的组合,因此它当然应该更改为Map
您可以展示一个例子,说明多个标准的结果是什么样子吗?@user7所以现在它的打印方式是{Kolkata=[[Kolkata,30,John],[Kolkata,31,Jack]}
我在想象多个组,例如城市和年龄,它应该看起来像{[Kolkata,30]=[[Kolkata,30,John]]}{[Kolkata,31]=[[Kolkata,31,Jack]]}
所以我很抱歉,结果可能会像列表` buildClassificationFunction是我要问的,但你添加了它,完美的答案!buildClassificationFunction是我要问的,但你添加了它,完美的答案!