List<ManualInfo> manuals = manualRepository.manuals();
manuals.stream()
.collect(
groupingBy( // group 1
ManualInfo::getLargeClass,
groupingBy( // group 2
ManualInfo::getMediumClass,
groupingBy( //group 3
ManualInfo::getSmallClass,
)
)
)
);为了在类别结构(json)中响应手册,从数据库中检索所有手册,然后分组。分类是按照我想要的方式来安排的,但是顺序不对。
经过长时间的研究,我发现分组前的排序不起作用,分组后不能进行排序。
如下所示,我最近学习了如何按顺序分组,这也适用于类别结构吗?
LinkedHashMap<String, List<ManualInfo>> collect = manuals.stream()
.collect(groupingBy(ManualInfo::getLargeClass, // group1
LinkedHashMap::new, // how can i do group2, group3....?
toList()));发布于 2022-10-24 08:05:19
如果您对列表中元素的初始顺序没有意见,那么您需要使用groupingBy()的三个args版本,它允许提供一个Supplier mapFactory来代替代码中的每个两个args分组。
这些收集器中的每一个都应该指定LinkedHashMap作为所需的积累类型:
List<ManualInfo> manuals = manualRepository.manuals();
var resultingMap = manuals.stream()
.collect(Collectors.groupingBy( // group 1
ManualInfo::getLargeClass,
LinkedHashMap::new,
Collectors.groupingBy( // group 2
ManualInfo::getMediumClass,
LinkedHashMap::new,
Collectors.groupingBy( //group 3
ManualInfo::getSmallClass,
LinkedHashMap::new,
Collectors.toList()
)
)
));指出,必须提供一个下游集合作为带有这种风格的groupingBy()的最后一个参数,对于第一个和第二个收集器,下游将是随后的嵌套分组,而对于最后一个集合,我们需要提供作为下游的toList() (在groupingBy()的一个arg版本中隐含地使用它)。
如果数据的排序不符合您的需求,那么您需要在收集数据之前对元素进行排序。
假设ManualInfo看起来是这样的:
public class ManualInfo {
private String largeClass;
private String mediumClass;
private String smallClass;
// getters, constructors, etc.
}假设您希望首先按照largeClass、mediumClass和smallClass对数据进行排序。然后,使用static接口的Java8 Comparator方法,我们可以定义以下比较器(您可以使用所需的任何排序条件,这只是如何构建比较器的一个示例):
Comparator.comparing(ManualInfo::getLargeClass)
.thenComparing(ManualInfo::getMediumClass)
.thenComparing(ManualInfo::getSmallClass)代码看起来可能是这样的:
var resultingMap = manuals.stream()
.sorted( // imposing the required ordering
Comparator.comparing(ManualInfo::getLargeClass)
.thenComparing(ManualInfo::getMediumClass)
.thenComparing(ManualInfo::getSmallClass)
)
.collect(Collectors.groupingBy( // group 1
ManualInfo::getLargeClass,
LinkedHashMap::new,
Collectors.groupingBy( // group 2
ManualInfo::getMediumClass,
LinkedHashMap::new,
Collectors.groupingBy( //group 3
ManualInfo::getSmallClass,
LinkedHashMap::new,
Collectors.toList()
)
)
));还有另一种选择,那就是如何强制命令。您可以使用TreeMap作为累积类型。
但是注意到,它只有在所需的排序与的分组条件完全匹配的情况下才能工作,因为TreeMap维护基于键的排序顺序。
var resultingMap = manuals.stream()
.collect(Collectors.groupingBy( // group 1
ManualInfo::getLargeClass,
TreeMap::new,
Collectors.groupingBy( // group 2
ManualInfo::getMediumClass,
TreeMap::new,
Collectors.groupingBy( //group 3
ManualInfo::getSmallClass,
TreeMap::new,
Collectors.toList()
)
)
));https://stackoverflow.com/questions/74175553
复制相似问题