首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java8采集地图

Java8采集地图
EN

Stack Overflow用户
提问于 2019-03-12 19:53:37
回答 2查看 101关注 0票数 2

我有一个目标:

代码语言:javascript
复制
public class MenuPriceByDay implements Serializable {

    private BigDecimal avgPrice;
    private BigDecimal minPrice;
    private BigDecimal maxPrice;
    private Date updateDate;

..
}

另外一个是:

代码语言:javascript
复制
public class Statistics {

     double min;
     double max;
     double average;

     public Statistics() {
        super();
     }



    public Statistics(double min, double max, double average) {
        super();
        this.min = min;
        this.max = max;
        this.average = average;
    }



}

还有一份价格清单:

代码语言:javascript
复制
List<MenuPriceByDay> prices = new ArrayList<MenuPriceByDay>();

我想转换成一张地图:

代码语言:javascript
复制
Map<LocalDate, Statistics> last30DPerDay =  

        prices
            .stream()
            .collect(Collectors.toMap(MenuPriceByDay::getUpdateDate, p -> new Statistics(   p.getAvgPrice().doubleValue(),
                    p.getMaxPrice().doubleValue(),
                    p.getMinPrice().doubleValue())));

但是我遇到了一个编译问题:

代码语言:javascript
复制
Type mismatch: cannot convert from Map<Date,Object> to 
 Map<LocalDate,Statistics>
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-12 20:00:52

UpdateDate的类型为Date,您尝试以LocalDate的形式进行收集,因此只需将Date转换为LocalDate

代码语言:javascript
复制
Map<LocalDate, Statistics> collect = prices.stream()
        .collect(Collectors.toMap(m -> m.getUpdateDate()
        .toInstant()
        .atZone(ZoneId.systemDefault())
        .toLocalDate(),
                 p -> new Statistics(p.getAvgPrice().doubleValue(),
                        p.getMaxPrice().doubleValue(),
                        p.getMinPrice().doubleValue())
        ));

关于将日期转换为LocalDate或LocalDateTime并返回的更多详细信息

或者您可以创建一个方法,如下所示:

代码语言:javascript
复制
public LocalDate convertToLocalDateViaInstant(Date dateToConvert) {
    return dateToConvert.toInstant()
            .atZone(ZoneId.systemDefault())
            .toLocalDate();
}

你的代码可以是:

代码语言:javascript
复制
  Map<LocalDate, Statistics> collect = prices.stream()
            .collect(Collectors.toMap(
                    m -> this.convertToLocalDateViaInstant(m.getUpdateDate()),
                    p -> new Statistics(p.getAvgPrice().doubleValue(),
                            p.getMaxPrice().doubleValue(),
                            p.getMinPrice().doubleValue())
            ));

更好的解决方案

最好的解决方案就是将updateDate类型更改为LocalDate

代码语言:javascript
复制
private LocalDate updateDate;

你可以用你的代码

票数 2
EN

Stack Overflow用户

发布于 2019-03-12 20:13:09

注意,当您使用Collectors.toMap时,如果您有重复的键,您可以得到IllegalStateException

如果映射的密钥包含重复项(根据Object.equals(对象)),则在执行集合操作时抛出IllegalStateException。

您可以使用toMap(keyMapper, valueMapper, mergeFunction)代替。还有groupingBy的解决方案,在这种情况下,您应该决定在复制键时必须使用哪个统计数据:

代码语言:javascript
复制
Map<LocalDate, Optional<Statistics>> map = prices.stream()
            .collect(groupingBy(p -> p.getUpdateDate()
                            .toInstant()
                            .atZone(ZoneId.systemDefault())
                            .toLocalDate(),
                    mapping(p-> new Statistics(
                            p.getMinPrice().doubleValue(),
                            p.getAvgPrice().doubleValue(),
                            p.getMaxPrice().doubleValue()),
                            reducing((s1, s2) -> ???)      // here
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55129678

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档