【发布时间】:2021-08-19 16:17:23
【问题描述】:
在Java 8中分组后,我需要按计数和对响应数据进行降序排序。
我有一个视图表查询结果,如:
| count(bigint) | category(varchar) | myEnum(int) |
|---|---|---|
| 10 | A | 0 |
| 35 | B | 0 |
| 30 | A | 1 |
| 25 | C | 1 |
我有一个视图表的投影界面,用于自定义 JPA 查询的结果。
public interface MyView {
Long getCount();
String getCategory();
MyEnum getMyEnum();
}
这个是我的响应 DTO:
public class MyResponse {
private List<Long> count = new ArrayList<>();
private List<String> categories = new ArrayList<>();
private List<List<MyEnum>> myEnums = new ArrayList<>();
// ctors, getters and setters
}
我需要按类别对数据进行分组并对总计数求和,然后将 Enum 类型收集到每个类别的列表中。据此,类别 A 的计数应为 40,并且具有 0,1 个枚举类型。 因此,客户端需要在获取请求后得到如下结果:
{
"count": [
40,
35,
25
],
"categories": [
"A",
"B",
"C"
],
"myEnums": [
[
"ENUM_A",
"ENUM_B"
],
[
"ENUM_A",
],
[
"ENUM_B",
]
]
}
这是我服务中的相关功能:
public MyResponse foo() {
// This list have the list of MyView.
List<MyView> myList = myRepository.getCountView());
Map<String, List<MyView>> myMap = myList.stream().collect(Collectors.groupingBy(MyView::getCategory));
MyResponse response = new MyResponse();
myMap.forEach((key, value) -> {
response.getCategories().add(key);
response.getCount().add(value.stream().mapToLong(MyView::getCount).sum());
response.getMyEnums().add(value.stream().flatMap(v -> Stream.of(v.getMyEnum())).collect(Collectors.toList()));
}
);
return response;
}
好的,我已完成按类别分组并对计数求和,但无法对它们进行排序。结果是正确的,但我需要按总计数降序排列数据。 如果您有任何建议,我将不胜感激。谢谢!
【问题讨论】:
-
写一个
Function<List<MyView>, MyResponse> mapView为单个视图列表创建响应,以及一个BinaryOperator<MyResponse> merge添加两个响应。然后,您可以使用它们来减少原始分组列表:myList.stream().collect(groupingBy(MyView::getCategory, reducing(MyResponse::new, mapView, merge))。 -
您可以使用
.map(v -> v.getMyEnum())或.map(MyView::getMyEnum)而不是.flatMap(v -> Stream.of(v.getMyEnum()))。然后,将myMap.forEach((key, value) -> …替换为myMap.entrySet().stream().sorted(Comparator.comparingLong(e -> e.getValue().getCount())).forEach(e -> …之类的东西,不幸的是,这意味着您必须手动在消费者中提取e.getKey()任何e.getValue()。 -
感谢您的建议。根据@Most Needed Rabbit 的回答,我解决了这个问题。另外,我申请了
.map(v -> v.getMyEnum()) or .map(MyView::getMyEnum),而不是.flatMap(v -> Stream.of(v.getMyEnum()))。
标签: sorting group-by java-8 java-stream flatmap