[英]Java 8, Lambda: Sorting within grouped Lists and merging all groups to a list
[英]group a list of map by value and merge as grouped lists by sorting
我想按值对地图列表进行分组,并在某些条件下插入(合并)作为分组列表。 按值“yr”分组并按相同的“类别”合并“标签”,然后将“价格”加在一起,然后按“价格”降序排列
List<Grocery> groceryList = new ArrayList<>();
Grocery grocery = new Grocery();
List<HahsMap<String, Object>> tagList = new ArrayList<>();
HashMap<String, Object> tagMap = new HashMap<>();
## feeding data example
tagMap.put("category", "A");
tagMap.put("name", "Apple");
tagMap.put("price", 10);
tagList.add(tagMap);
grocery.setYr(String yr);
grocery.setTag(List<Hashmap<String, Object>> tagList);
groceryList.add(grocery);
这是地图列表的示例。
List<Grocery> groceryList =
[
{
"yr": "2021",
"tag": [
{
"Category": "A",
"Name": "Apple",
"Price": 10
}
]
},
{
"yr": "2021",
"tag": [
{
"Category": "A",
"Name": "Apple",
"Price": 10
}
]
},
{
"yr": "2021",
"tag": [
{
"Category": "B",
"Name": "Banana",
"Price": 5
}
]
},
{
"yr": "2020",
"tag": [
{
"Category": "A",
"Name": "Apple",
"Price": 10
}
]
},
{
"yr": "2020",
"tag": [
{
"Category": "B",
"Name": "Banana",
"Price": 30
}
]
},
{
"yr": "2020",
"tag": [
{
"Category": "C",
"Name": "Candy",
"Price": 10
}
]
},
{
"yr": "2020",
"tag": [
{
"Category": "C",
"Name": "Candy",
"Price": 30
}
]
},
{
"yr": "2020",
"tag": [
{
"Category": "A",
"Name": "Apple",
"Price": 10
}
]
}
]
这是我想要获得的示例输出
List<Grocery> result =
[
{
"yr": "2021",
"tag": [
{
"Category": "A",
"Name": "Apple",
"Price": 20
},
{
"Category": "B",
"Name": "Banada",
"Price": 5
}
]
},
{
"yr": "2020",
"tag": [
{
"Category": "C",
"Name": "Candy",
"Price": 40
},
{
"Category": "B",
"Name": "Banada",
"Price": 30
},
{
"Category": "A",
"Name": "Apple",
"Price": 20
}
]
}
]
我知道将所有条件合并为一个很棘手,有人可以帮我吗? 如果至少我能对此有一些想法,我将不胜感激..
我尝试首先将它们分组为“年”,然后尝试找到要绘制的值,然后使用相同的“类别”将它们排序,然后总结……但我不知道如何对它们进行排序并将它们与 summed 合并涨价了..
提前致谢!!
请检查这是否是您要查找的内容。
String inputJson = "[{\"yr\":\"2021\",\"tag\":[{\"Category\":\"A\",\"Name\":\"Apple\",\"Price\":10}]},{\"yr\":\"2021\",\"tag\":[{\"Category\":\"A\",\"Name\":\"Apple\",\"Price\":10}]},{\"yr\":\"2021\",\"tag\":[{\"Category\":\"B\",\"Name\":\"Banana\",\"Price\":5}]},{\"yr\":\"2020\",\"tag\":[{\"Category\":\"A\",\"Name\":\"Apple\",\"Price\":10}]},{\"yr\":\"2020\",\"tag\":[{\"Category\":\"B\",\"Name\":\"Banana\",\"Price\":30}]},{\"yr\":\"2020\",\"tag\":[{\"Category\":\"C\",\"Name\":\"Candy\",\"Price\":10}]},{\"yr\":\"2020\",\"tag\":[{\"Category\":\"C\",\"Name\":\"Candy\",\"Price\":30}]},{\"yr\":\"2020\",\"tag\":[{\"Category\":\"A\",\"Name\":\"Apple\",\"Price\":10}]}]";
ObjectMapper objectMapper = new ObjectMapper();
//convert json to input Grocery List using jackson object mapper
List<Grocery> groceries = objectMapper.readValue(inputJson, new TypeReference<List<Grocery>>() {
});
List<Grocery> output = new ArrayList<>();
//group all groceries by year
Map<String, List<Grocery>> groceriesByYear = groceries.stream().collect(Collectors.groupingBy(grocery -> grocery.getYr()));
groceriesByYear.keySet().forEach(year -> {
//for each year, get the grocery list
List<Grocery> groceryList = groceriesByYear.get(year);
//merge tags which have same category
Map<String, Tag> tagsPerCategory = groceryList.stream().flatMap(grocery -> grocery.getTag().stream()).collect(Collectors.toMap(Tag::getCategory, Function.identity(),
(tag1, tag2) -> {
//merge function, sum up the price of tag which has same category
tag1.setPrice(tag1.getPrice() + tag2.getPrice());
return tag1;
}));
//create new grocery object with required data
Grocery grocery = new Grocery();
grocery.setYr(year);
grocery.setTag(new ArrayList<>(tagsPerCategory.values()));
output.add(grocery);
});
//output list will have groceries grouped by year and tag with summed up price
编辑
您可以对标签流进行过滤以避免空标签对象,如果您认为价格可以为空,则添加非空检查,或者您可以定义一个方法来提供默认值,如果价格尚未设置如下
public static <T> T getValueOrDefault(T value, T defaultValue) {
return value != null ? value : defaultValue;
}
并且您的 tagsPerCategory 如下所示
Map<String, Tag> tagsPerCategory = groceryList.stream().flatMap(grocery -> grocery.getTag().stream()).filter(tag -> tag != null && tag.getPrice() != null)
.collect(Collectors.toMap(Tag::getCategory, Function.identity(),
(tag1, tag2) -> {
//sum up the price of tag which has same category
tag1.setPrice(getValueOrDefault(tag1.getPrice(), 0) + getValueOrDefault(tag2.getPrice(), 0));
return tag1;
}));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.