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
相关产品推荐
相关产品推荐

