Java 填充所有状态值的汇总计数

Java 填充所有状态值的汇总计数,java,java-8,enums,java-stream,Java,Java 8,Enums,Java Stream,对于所有状态,我都有一个枚举,如下所示: enum Status { ACCEPTED("Accepted"), REJECTED("Rejected"), FAILED("Failed"); private final String label; Status(final String label) { this.label = label; } } 映射我从数据库运行的查询结果的模型: public class S

对于所有状态,我都有一个
枚举
,如下所示:

enum Status {    
    ACCEPTED("Accepted"),
    REJECTED("Rejected"),
    FAILED("Failed");

    private final String label;

    Status(final String label) {
        this.label = label;
    }
}
映射我从数据库运行的查询结果的模型:

public class Summary {    
    private LocalDate date;
    private Status status;
    private int count;    
}
假设我的数据库返回以下内容,不包括第24次的
拒绝
计数和第27次的
失败

DATE        | status        | count
20-01-24    | Accepted      | 1     
20-01-24    | Failed        | 40        
20-01-27    | Accepted      | 10        
20-01-27    | Rejected      | 15
我怎样才能将这些日期的
拒绝
失败
的摘要与上述内容一起包括在内

我称db为:

final List<Summary> statuses = this.dbRepo.getSummaries(someCriteria);
public Map<LocalDate, List<Summary>> getSummaries(final SomeCriteria someCriteria) {
    return this.namedParameterJdbcTemplate.query(this.QUERY,
            new MapSqlParameterSource()
                    .addValue("date", someCriteria.getFrom())
            ((rs, rowNum) -> Summary.builder()
                                                    .date(rs.getDate("date").toLocalDate())
                                                    .status(valueOfLabel(rs.getString("status")))
                                                    .count(rs.getInt("count"))
                                                    .build())
    ).stream().collect(groupingBy(Summary::getDate));
}

您可以使用嵌套的
分组
创建初始查找
映射

Map<LocalDate, Map<Status, Summary>> lookup = statuses.stream()
        .collect(Collectors.groupingBy(Summary::getDate,
                Collectors.toMap(Summary::getStatus, Function.identity())));
根据问题中提供的输入,这将导致:


您可以使用嵌套的
分组
创建初始查找
映射

Map<LocalDate, Map<Status, Summary>> lookup = statuses.stream()
        .collect(Collectors.groupingBy(Summary::getDate,
                Collectors.toMap(Summary::getStatus, Function.identity())));
根据问题中提供的输入,这将导致:


这是我将分两步做的事情,在一个穷人版本的笛卡尔自联接(在预先分组的数据上):


这是我将分两步做的事情,在一个穷人版本的笛卡尔自联接(在预先分组的数据上):


一步一个脚印地完成这件事也许是可能的,但我认为它不会那么易读! 分几步来做,让我明白

第一步:按日期和状态属性分组

Map<LocalDate, Set<Status>> groupByDateAndStatus = list.stream()
        .collect(Collectors.groupingBy(Summary::getDate,
               Collectors.mapping(Summary::getStatus, Collectors.toSet())));
和合并方法:

private static List<Summary> merge(List<Summary> l1, List<Summary> l2) {
   l1.addAll(l2);
   return l1; 
}

Map Map=newhashmap();
映射查找=list.stream()
.collect(收集器).groupingBy(摘要::getDate,
Collectors.toMap(Summary::getStatus,Function.identity());
EnumSet.allOf(Status.class)
.forEach(状态->查找
.forEach((键、值)->
map.merge(键,新ArrayList(Collections.singletonList(value.getOrDefault(status,new Summary(键,status,0))),
您的类::合并);

一步到位也许是可能的,但我认为它不会那么易读! 分几步来做,让我明白

第一步:按日期和状态属性分组

Map<LocalDate, Set<Status>> groupByDateAndStatus = list.stream()
        .collect(Collectors.groupingBy(Summary::getDate,
               Collectors.mapping(Summary::getStatus, Collectors.toSet())));
和合并方法:

private static List<Summary> merge(List<Summary> l1, List<Summary> l2) {
   l1.addAll(l2);
   return l1; 
}

Map Map=newhashmap();
映射查找=list.stream()
.collect(收集器).groupingBy(摘要::getDate,
Collectors.toMap(Summary::getStatus,Function.identity());
EnumSet.allOf(Status.class)
.forEach(状态->查找
.forEach((键、值)->
map.merge(键,新ArrayList(Collections.singletonList(value.getOrDefault(status,new Summary(键,status,0))),
您的类::合并);

您能向我们展示的任何SQL?除此之外,还应更正为第27次被拒绝,第24次失败。另外,请向我们展示您迄今为止尝试过的内容。您能向我们展示的任何SQL?除此之外,还应更正为第27次被拒绝,第24次失败。另外,请向我们展示您迄今为止所做的尝试。
 Map<LocalDate, List<Summary>> map = list.stream()
            .collect(Collectors.toMap(Summary::getDate,
                summary -> new ArrayList<>(Collections.singletonList(summary)), YOURCLASS::merge));
EnumSet.allOf(Status.class)
        .forEach(status -> groupByDateAndStatus.entrySet()
        .stream()
        .filter(entry -> !entry.getValue().contains(status))
        .forEach(entry -> map.merge(entry.getKey(), 
 new ArrayList<Summary>(Collections.singletonList(new Summary(entry.getKey(), status, 0))),
                                                                           YOURCLASS::merge)));
private static List<Summary> merge(List<Summary> l1, List<Summary> l2) {
   l1.addAll(l2);
   return l1; 
}
{
  2020-01-27=[
      Summary{date=2020-01-27, status=ACCEPTED, count=10}, 
      Summary{date=2020-01-27, status=REJECTED, count=15}, 
      Summary{date=2020-01-27, status=FAILED, count=0}], 
  2020-01-24=[ 
      Summary{date=2020-01-24, status=ACCEPTED, count=1}, 
      Summary{date=2020-01-24, status=FAILED, count=40}, 
      Summary{date=2020-01-24, status=REJECTED, count=0}
    ]
}
Map<LocalDate, List<Summary>> map = new HashMap<>();
Map<LocalDate, Map<Status, Summary>> lookup = list.stream()
        .collect(Collectors.groupingBy(Summary::getDate,
            Collectors.toMap(Summary::getStatus, Function.identity())));

EnumSet.allOf(Status.class)
        .forEach(status -> lookup
            .forEach((key, value) ->
               map.merge(key, new ArrayList<>(Collections.singletonList(value.getOrDefault(status, new Summary(key, status, 0)))),
                                    YOURCLASS::merge)));