java - 有没有更好的方法使用流重构此代码

标签 java java-stream

我正在计算 3 个值,它们是列表对象的总计。为了得到这些,我写了 3 个语句,每个语句用于计算 3 个值。我想知道有什么方法可以用一个流(功能 block )之类的东西做得更好

尝试使用 3 个语句来计算同一列表或流中的每个总计

BigDecimal totalMkt = subAccounts.parallelStream()
        .flatMap(ts -> ts.getAssets().parallelStream())
        .filter(ast -> !ast.getAssetTypeCode().equals(AssetType.CURRENCY))
         .map(ast -> ast.getPostMktVal())
        .reduce(BigDecimal::add).orElse(BigDecimal.ZERO);

BigDecimal totalTradeVal = subAccounts.parallelStream()
        .flatMap(ts -> ts.getAssets().parallelStream())
        .filter(ast -> !ast.getAssetTypeCode().equals(AssetType.CURRENCY))
        .map(ast -> ast.getTradeVal())
        .reduce(BigDecimal::add).orElse(BigDecimal.ZERO);

BigDecimal totalValue = totalMkt.add(totalTradeVal).add(totalWrk);

logger.debug("totalMkt "+totalMkt+ 
            " totalTradeVal "+totalTradeVal +
            " totalWrk "+totalWrk +
            " totalValue "+totalValue);

subAccounts.stream()
        .flatMap(subAccount -> subAccount.getAssets().stream()
            .filter(asset->!asset.getAssetTypeCode().equals(AssetType.CURRENCY)))
        .forEach(asset -> {
            logger.debug("assetCode "+asset.getAssetCode());
            BigDecimal weightPct = asset.getPostMktVal()
                .multiply(new BigDecimal(100))
                .divide(totalValue, 5,RoundingMode.HALF_UP);
            asset.setWeightPct(weightPct);
            logger.debug(" weightPct " + weightPct);
        });

按照 @Tarlog 的建议新创建的 Pair 类。当多个请求传入时这是否会产生任何影响或问题

    static class Pair<L,R> {
          final L left;
          final R right;

          public L getLeft() {
            return left;
        }

        public R getRight() {
            return right;
        }

        public Pair(L left, R right) {
            this.left = left;
            this.right = right;
          }

          static <L,R> Pair<L,R> of(L left, R right){
              return new Pair<L,R>(left, right);
          }
    }

最佳答案

您也许可以将前两个语句合并为一个:

Pair<BigDecimal, BigDecimal> totalMktTrade = subAccounts.parallelStream()
        .flatMap(ts -> ts.getAssets().parallelStream())
        .filter(ast -> !ast.getAssetTypeCode().equals(AssetType.CURRENCY))
         .map(ast -> Pair.of(ast.getPostMktVal(), ast.getTradeVal()))
        .reduce((a,b) -> Pair.of(a.getLeft().add(b.getLeft(), a.getRight().add(b.getRight());
BigDecimal totalMkt = totalMktTrade.getLeft();
BigDecimal totalTradeVal = totalMktTrade.getRight();

我不知道如何组合第三个流,因为它使用了先前计算的结果,包括来自外部的 totalWrk

关于java - 有没有更好的方法使用流重构此代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55423689/

相关文章:

java - 如何使用 cucumber-jvm 将场景输出线数据作为步骤方法中的对象传递

java - 传递一个非关联函数来减少

java - 从 Stream<String> 创建 Map<Integer, Set<String>>

java - 列表中的映射 - 如何使用 Stream 进行迭代

java - 尽管代码执行成功,但回滚不适用于 GAE 中使用 Jdo 的事务

java - 无法在GAE应用程序中导入jar文件

java - 使用条件从另一个列表中删除嵌套列表中的元素 - Java 8

java - 使用 Java Streams 的笛卡尔积

Java 优化了读/写共享资源/内存位置而无需 Atomic API,例如原子整数

java - 如何使用父类(super class)调用方法