繁体   English   中英

按值对地图列表进行分组并通过排序合并为分组列表

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM