Java 8 List<Map<String, Object>> 到 List<Map<String, Object>> 按键分组并按值计数

标签 java lambda collections java-8 java-stream

我有以下 map 列表

List<Map<String, Object>> listBeforeGroup = new ArrayList<Map<String, Object>>();

    Map<String, Object> m1 = new HashMap<String, Object>();
    m1.put("company", "LG");
    m1.put("billType", "A");
    m1.put("billPeriod", "09-2018");

    Map<String, Object> m2 = new HashMap<String, Object>();
    m2.put("company", "LG");
    m2.put("billType", "A");
    m2.put("billPeriod", "09-2018");

    Map<String, Object> m3 = new HashMap<String, Object>();
    m3.put("company", "LG");
    m3.put("billType", "A");
    m3.put("billPeriod", "09-2018");

    Map<String, Object> m4 = new HashMap<String, Object>();
    m4.put("company", "LG");
    m4.put("billType", "B");
    m4.put("billPeriod", "01-2019");

    Map<String, Object> m5 = new HashMap<String, Object>();
    m5.put("company", "LG");
    m5.put("billType", "B");
    m5.put("billPeriod", "01-2019");

    Map<String, Object> m6 = new HashMap<String, Object>();
    m6.put("company", "Samsung");
    m6.put("billType", "A");
    m6.put("billPeriod", "10-2018");

    Map<String, Object> m7 = new HashMap<String, Object>();
    m7.put("company", "Samsung");
    m7.put("billType", "A");
    m7.put("billPeriod", "10-2018");

    Map<String, Object> m8 = new HashMap<String, Object>();
    m8.put("company", "Samsung");
    m8.put("billType", "B");
    m8.put("billPeriod", "11-2018");

    listBeforeGroup.add(m1);listBeforeGroup.add(m2);
    listBeforeGroup.add(m3);listBeforeGroup.add(m4);
    listBeforeGroup.add(m5);listBeforeGroup.add(m6);

我如何获得此输出?

    //Desired Output - List<Map<String, Object>>
    //{company=LG, billType=A, billPeriod=09-2018, count=3}
    //{company=LG, billType=B, billPeriod=01-2019, count=2}
    //{company=Samsung, billType=A, billPeriod=10-2018, count=2}
    //{company=Samsung, billType=B, billPeriod=11-2018, count=1}

我试过这个,使用 java 8 流,但我无法获得所需的输出

List<Map<String, Object>> listAfterGroup = listBeforeGroup.stream().map(m -> m.entrySet().stream().collect(Collectors.toMap(p -> p.getKey(), p - >  p.getValue()))).collect(Collectors.toList());

并尝试了这个,顺便说一句,这个解决方案提供了一张 map ,但我不想要这个

Map<Object, Long> listAfterGroup = listBeforeGroup.stream().flatMap(m -> m.entrySet().stream()).collect(Collectors.groupingBy(Map.Entry::getKey,Collectors.counting()));

例如,我想按键“billPeriod”对 map 进行分组,并按值对项目进行计数,然后生成一个新的 map 列表。

最佳答案

你可以创建一个Company类,之后的操作就简单多了。

class Company {
    String company;
    String billType;
    String billPeriod;

    public Company(String company, String billType, String billPeriod) {
        this.company = company;
        this.billType = billType;
        this.billPeriod = billPeriod;
    }

    // getters, setters, toString, etc
}

初始化列表:

List<Company> list = new ArrayList<>();
list.add(new Company("LG", "A", "09-2018"));
list.add(new Company("LG", "A", "09-2018"));
list.add(new Company("LG", "A", "09-2018"));
list.add(new Company("LG", "B", "01-2019"));
list.add(new Company("LG", "B", "01-2019"));
list.add(new Company("Samsung", "A", "10-2018"));
list.add(new Company("Samsung", "A", "10-2018"));
list.add(new Company("Samsung", "B", "11-2018"));

举个例子,你可以按公司名称分组:

Map<String, Long> map = list.stream().collect(
        Collectors.groupingBy(Company::getCompany, 
                              Collectors.mapping((Company c) -> c, Collectors.counting())));

现在,您可以更轻松地执行其他所需的操作。此外,在这里您最终只处理了1 个列表,而不是创建8 个 map

关于Java 8 List<Map<String, Object>> 到 List<Map<String, Object>> 按键分组并按值计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54299562/

相关文章:

javascript - 如何创建一个 javascript 类并使用索引/名称查找访问内部集合?

java - 如何在 Neo4J Java 中搜索处于一种关系而不是另一种关系的 endNode

java - 混淆 mySql 转储文件中的关键字段以保护隐私

java - 加载使用 native 代码的多个Java类版本

Java工具Notarize流程

java - 通过 lambda java8 转换 xml 字符串

Java 流 API 过滤器

python - 默认字典的默认字典?

c# - 如何编写 linq 语句来获取一组记录中的最后一条记录

c# - 为什么这段代码抛出 'Collection was modified' ,但是当我在它之前迭代一些东西时,它却没有?