0

我有一个 List<Map<String, Object>> 输入,如下所示:

[{
    CURRENCY = USD,
    STATUS = NEW,
    PUBLISH_REGION = DEL,
    SOURCE = ALADDIN,
    RECON_STATUS = null,
    JOB_ID_COUNT = 783
}, {
    CURRENCY = USD,
    STATUS = IN_PROGRESS,
    PUBLISH_REGION = DEL,
    SOURCE = ALADDIN,
    RECON_STATUS = null,
    JOB_ID_COUNT = 462
}, {
    CURRENCY = USD,
    STATUS = NEW,
    PUBLISH_REGION = DEL,
    SOURCE = GROUP,
    RECON_STATUS = null,
    JOB_ID_COUNT = 4
}]

我正在尝试通过对 CURRENCY、PUBLISH_REGION、SOURCE 和 RECON_STATUS 列进行分组来创建另一个 List<Map<String, Object>>。并将所有唯一的 STATUS 值作为枢轴添加到输出映射并使用 JOB_ID_COUNT 汇总/聚合计数。

List<String> groups = new ArrayList<>(asList("SOURCE", "RECON_STATUS", "PUBLISH_REGION", "CURRENCY"));
List<Map<String, Object>> = input.stream()
    .collect(groupingBy(row -> row.get(groups.get(0)), mapping(map -> map.get(groups.get(0)), toList())));

我期待以下回应:输出:

 [{
        CURRENCY = USD,
        PUBLISH_REGION = DEL,
        SOURCE = ALADDIN,
        RECON_STATUS = null,
        NEW = 783,
        IN_PROGRESS = 462
    }, {
        CURRENCY = USD,
        PUBLISH_REGION = DEL,
        SOURCE = GROUP,
        RECON_STATUS = null,
        NEW = 4,
        IN_PROGRESS = 0
    }]

尝试按多个地图字段分组时出现编译时错误。单字段 groupingBy 工作正常。非常感谢任何帮助。

4

2 回答 2

1

尝试了这个解决方案,它正在工作

  1. 流式传输源列表
  2. 将列表中 map 的每个值映射到 MapWrapper 类(每个键都是字段的 pojo)
  3. GroupBy 使用 MapWrapper 中定义的 groupByKey(使用 CURRENCY、PUBLISH_REGION、SOURCE 和 RECON_STATUS 列) 3.a 结果是一个Map<String, List<MapWrapper>> 4.Stream 通过条目集
  4. 地图 - 并单独从中获取价值(Map<String, List<MapWrapper>>)
  5. 地图 - 转换List<MapWrapper>Map<String, Object>使用MapWrapper::map
  6. 收集到列表

简而言之,解决方案是

List<Map<String, Object>> value = lst.stream()
                .map(map -> new MapWrapper(map))
                .collect(groupingBy(MapWrapper::groupByKey))
                .entrySet()
                .stream()
                .map(e -> e.getValue())
                .map(MapWrapper::map).collect(toList());

工作代码

public class MultipleFieldSorting {
    private static Map<String, Object> map, map1, map2;
    private static List<Map<String, Object>> lst = new ArrayList<>();
    static {
        map = new HashMap<>();
        map.put("CURRENCY", "USD");
        map.put("STATUS", "NEW");
        map.put("PUBLISH_REGION", "DEL");
        map.put("SOURCE", "ALADDIN");
        map.put("RECON_STATUS", null);
        map.put("JOB_ID_COUNT", "783");

        map1 = new HashMap<>();
        map1.put("CURRENCY", "USD");
        map1.put("STATUS", "IN_PROGRESS");
        map1.put("PUBLISH_REGION", "DEL");
        map1.put("SOURCE", "ALADDIN");
        map1.put("RECON_STATUS", null);
        map1.put("JOB_ID_COUNT", "462");

        map2 = new HashMap<>();
        map2.put("CURRENCY", "USD");
        map2.put("STATUS", "NEW");
        map2.put("PUBLISH_REGION", "DEL");
        map2.put("SOURCE", "GROUP");
        map2.put("RECON_STATUS", null);
        map2.put("JOB_ID_COUNT", "4");

        lst.add(map);
        lst.add(map1);
        lst.add(map2);
    }

    public static void main(String[] args) {
        List<Map<String, Object>> value = lst.stream()
                .map(map -> new MapWrapper(map))
                .collect(groupingBy(MapWrapper::groupByKey))
                .entrySet()
                .stream()
                .map(e -> e.getValue())
                .map(MapWrapper::map).collect(toList());

        System.out.println(value);
    }

}

class MapWrapper {
    private String currency;
    private String status;
    private String publish;
    private String source;
    private String recon_status;
    private String job_id;

    public MapWrapper(Map<String, Object> map) {
        this.currency = (String) map.get("CURRENCY");
        this.status = (String) map.get("STATUS");
        this.publish = (String) map.get("PUBLISH_REGION");
        this.source = (String) map.get("SOURCE");
        this.recon_status = (String) map.get("RECON_STATUS");
        this.job_id = (String) map.get("JOB_ID_COUNT");
    }

    String groupByKey() {
        return new StringBuilder().append(this.getCurrency()).append("-").append(this.publish).append("-")
                .append(this.source).append("-").append(this.recon_status).toString();
    }

    public static Map<String, Object> map(List<MapWrapper> lst){
            Map<String, Object> res = new HashMap<>();
            res.put("CURRENCY",lst.get(0).getCurrency());
            res.put("PUBLISH_REGION",lst.get(0).getPublish());
            res.put("SOURCE",lst.get(0).getSource());
            res.put("RECON_STATUS",lst.get(0).getRecon_status());
            for(MapWrapper m : lst){
                res.put(m.getStatus(), m.getJob_id());
            }
            if(res.get("NEW")==null){
                res.put("NEW", 0);
            }
            if(res.get("IN_PROGRESS")==null){
                res.put("IN_PROGRESS", 0);
            }
            return res;
            
        }

    String getCurrency() {
        return currency;
    }

    void setCurrency(String currency) {
        this.currency = currency;
    }

    String getStatus() {
        return status;
    }

    void setStatus(String status) {
        this.status = status;
    }

    String getPublish() {
        return publish;
    }

    void setPublish(String publish) {
        this.publish = publish;
    }

    String getSource() {
        return source;
    }

    void setSource(String source) {
        this.source = source;
    }

    String getJob_id() {
        return job_id;
    }

    void setJob_id(String job_id) {
        this.job_id = job_id;
    }

    String getRecon_status() {
        return recon_status;
    }

    void setRecon_status(String recon_status) {
        this.recon_status = recon_status;
    }

}
于 2020-09-17T17:20:10.687 回答
1

不使用自定义类

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MultipleFieldSorting2 {
    private static Map<String, Object> map, map1, map2;
    private static List<Map<String, Object>> lst = new ArrayList<>();
    static {
        map = new HashMap<>();
        map.put("CURRENCY", "USD");
        map.put("STATUS", "NEW");
        map.put("PUBLISH_REGION", "DEL");
        map.put("SOURCE", "ALADDIN");
        map.put("RECON_STATUS", null);
        map.put("JOB_ID_COUNT", "783");

        map1 = new HashMap<>();
        map1.put("CURRENCY", "USD");
        map1.put("STATUS", "IN_PROGRESS");
        map1.put("PUBLISH_REGION", "DEL");
        map1.put("SOURCE", "ALADDIN");
        map1.put("RECON_STATUS", null);
        map1.put("JOB_ID_COUNT", "462");

        map2 = new HashMap<>();
        map2.put("CURRENCY", "USD");
        map2.put("STATUS", "NEW");
        map2.put("PUBLISH_REGION", "DEL");
        map2.put("SOURCE", "GROUP");
        map2.put("RECON_STATUS", null);
        map2.put("JOB_ID_COUNT", "4");

        lst.add(map);
        lst.add(map1);
        lst.add(map2);
    }
    
    public static Map<String, Object> mapper(Map<String, Object> e){

        String key = e.get("CURRENCY") + "-" + e.get("PUBLISH_REGION") + "-" + e.get("SOURCE") + "-" + e.get("RECON_STATUS");
        Map<String, Object> groupedValue = res.get(key);
        if(groupedValue!=null){
            groupedValue.put((String) e.get("STATUS"), groupedValue.get("STATUS")!=null ? groupedValue.get("STATUS")+","+e.get("JOB_ID_COUNT") : e.get("JOB_ID_COUNT"));
            if(groupedValue.get("NEW")==null){
                groupedValue.put("NEW", 0);
            }
            if(groupedValue.get("IN_PROGRESS")==null){
                groupedValue.put("IN_PROGRESS", 0);
            }
        }else{
            groupedValue = new HashMap<>();
            res.put(key, groupedValue);
            groupedValue.put("CURRENCY", e.get("CURRENCY"));
            groupedValue.put("PUBLISH_REGION", e.get("PUBLISH_REGION"));
            groupedValue.put("SOURCE", e.get("SOURCE"));
            groupedValue.put("RECON_STATUS", e.get("RECON_STATUS"));
            groupedValue.put((String) e.get("STATUS"), e.get("JOB_ID_COUNT"));
        }
        return groupedValue;
    
    }
    static Map<String, Map<String, Object>> res = new HashMap<>();
    
    public static void main(String[] args) {
        List<Map<String, Object>> finalResult = new ArrayList<>();
        lst.stream()
        .map(MultipleFieldSorting2::mapper)
        .forEach(result -> {
            if(!finalResult.contains(result))
                finalResult.add(result);
        });

        System.out.println(finalResult);
    }

}
于 2020-09-18T09:08:47.287 回答