是否有一种功能性方法可以遍历基于最后处理的项目进行累积和过滤的流?

问题描述 投票:0回答:1

我收到了具有相同信用额度的所有客户在一段时间内完成的交易请求的有序列表。 我的目标是生成超过信用限额后所有疯狂交易的列表。

为此,我需要提取每笔交易的金额并从客户的信用额度中提取。

我正在学习并尝试使用 java11 流来解决这个问题,但我找不到一种方法可以在一次遍历中以功能性的方式完成。

最初,我按客户对交易进行分组:

Map<Customer, List<Transaction>> result = transactions.stream()
       .collect(Collectors.groupingBy(Transaction::getCustomer));

但是后来我遍历了结果,累加了交易金额,当交易金额大于限制时将交易添加到所需的列表中:

List<String> toAnalise = new ArrayList<>();
result.entrySet().forEach(entry -> {
    int total = 0;
    for (Transaction transaction : entry.getValue()) {
      if ((total + transaction.amount) <= creditLimit ){
            total += transaction.amount;
        } else {
          toAnalise.add(transaction.transactionId);
        }               
    }
});

我感觉这可以改进:)


我改进了我的解决方案......看起来更好:)

现在我直接返回交易列表:

List<String> toBeAnalised = transactions.stream()
        .map(t -> new Transaction(t, creditLimit))
        .collect(groupingBy(Transaction::getConsumer,
                collectingAndThen(toCollection(TreeSet::new),
                TransactionsVersion2::validateTransactions)))
        .values().stream().flatMap(List<String>::stream)
        .collect(toList());

我还将事务验证移至其自己的方法,允许从流处理中调用它:

private static List<String> validateTransactions(Set<Transaction> transactions) {
    int total = 0;
    List<String> rejected = new ArrayList<>();
    for (Transaction transaction : transactions) {
        if ((total + transaction.amount) <= transaction.consumer.limit)
        {
            total += transaction.amount;
        } else {
            rejected.add(transaction.transactionId);
        }
    }
    return rejected;
}

还能改进吗?

java java-stream java-11
1个回答
1
投票

使用

takeWhile
之类的东西:

List<String> toAnalise = new ArrayList<>();
for (List<Transaction> value : result.values()) {
    AtomicInteger total = new AtomicInteger(0);
    toAnalise.addAll(value.stream()
            .takeWhile(a -> total.addAndGet(a.amount) <= creditLimit)
            .map(t -> t.transactionId).collect(Collectors.toList()));
}
© www.soinside.com 2019 - 2024. All rights reserved.