You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Stream优化:键已存在时累加值的Map构建方案

优化方案说明

首先得提个关键前提:你的PositionKey类必须正确重写equals()和hashCode()方法,否则Map会把内容相同的PositionKey当成不同的键,累加逻辑完全失效。正确实现示例如下:

private class PositionKey {
    String assetId;
    String currencyId;

    public PositionKey(String assetId, String currencyId) {
        this.assetId = assetId;
        this.currencyId = currencyId;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        PositionKey that = (PositionKey) o;
        return Objects.equals(assetId, that.assetId) && Objects.equals(currencyId, that.currencyId);
    }

    @Override
    public int hashCode() {
        return Objects.hash(assetId, currencyId);
    }
}

回到你的问题,提前创建map变量属于冗余操作,以下两种实现更简洁高效:


方式一:优化Collectors.toMap用法

直接在toMap的第四个参数中指定HashMap::new作为Map的提供者,无需提前声明变量,代码更紧凑:

public Map<PositionKey, BigDecimal> getMap(final Long portfolioId) {
    return getPositions(portfolioId).stream()
        .collect(Collectors.toMap(
            position -> new PositionKey(position.getAssetId(), position.getCurrencyId()),
            Position::getValue,
            BigDecimal::add,
            HashMap::new
        ));
}

注:修正了你原代码中的笔误,比如geCurrencyId()改为getCurrencyId(),geValue()改为getValue()


方式二:用groupingBy结合reducing

这种方式语义更清晰,分组逻辑与累加逻辑分离,可读性更强:

public Map<PositionKey, BigDecimal> getMap(final Long portfolioId) {
    return getPositions(portfolioId).stream()
        .collect(Collectors.groupingBy(
            position -> new PositionKey(position.getAssetId(), position.getCurrencyId()),
            HashMap::new,
            Collectors.reducing(BigDecimal.ZERO, Position::getValue, BigDecimal::add)
        ));
}

两种方式都避免了冗余的Map提前创建,符合流式编程的风格,可根据个人习惯选择。

内容的提问来源于stack exchange,提问作者j3d

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 18:40:26