有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在Java8中按流对映射对象按时间段求和?

我有一个地图对象。key是ID,值是Transaction的列表。以下是交易类别代码:

public class Transaction {
    private double amount;
    private LocalDateTime timestamp;
...
}

Map transactions = new HashMap<String, List<Transaction>>();

// how to stream transactions here?

我正在尝试获取每个key在24小时内发生的事务的总数。首先,我需要为每个键循环事务列表。然后根据时间戳对事务进行分组。然后对每个分组事务的值求和

例如,贴图对象具有以下值:

'012345': [ {'05-05-2019:10.00.00', 100}, {'05-05-2019:11.00.00', 100},{'05-05-2019:12.00.00', 100} ]
`678900`: [ {'05-06-2019:10.00.00', 100}, {'05-06-2019:11.00.00', 100},{'05-07-2019:10.30.00', 100} ]

它有两个键012345678900,每个键有三个事务。键012345下的事务在24小时内发生,而678900下的事务在2天内发生。输出应为24小时窗口期的金额总和。所以它看起来像:

'012345': [300],
'678900': [200, 200]

678900下的三项交易有两个24小时窗口期。所以它给出了两个200的数值。中间事务计算两次,因为它被两个24小时窗口周期覆盖

以下是我的想法:

transactions.values().forEach(txnList -> {
            Map<Integer, DoubleSummaryStatistics> collect = txnList.stream().collect(Collectors.groupingBy(txn -> txn.getTimestamp().getHour() / 24, Collectors.summarizingDouble(Transaction::getAmount)));
        });

但是它没有返回正确的值。我不知道我该如何处理这个逻辑。有人能告诉我怎么做吗


共 (1) 个答案

  1. # 1 楼答案

    如果您愿意使用第三方库,那么Eclipse-Collections中提供了一些API,这些API可以很好地完成您的工作。这适用于任何Java java.lang.Iterable。代码如下所示:

        Map<String, List<Transaction>> transactionsMap = getMapOfTransactionalData(...);
        final long currentTime = Instant.now().getEpochSecond();
        Map<String, Double> idTransactionSumMap = MapIterate.collect(transactionsMap, (id, transList) -> {
            Collection<Transaction> transactionsForTimeRange = Iterate.select(transList, transaction -> {
                // Implement your condition to compare time, below is just an example, you can define your range as well
                long transactionTime = transaction.getTimestamp().toEpochSecond(ZoneOffset.UTC);
                return transactionTime > currentTime - TimeUnit.HOURS.toMillis(24);
            });
            return Tuples.pair(id, Iterate.sumOfDouble(transactionsForTimeRange, Transaction::getAmount));
        });
    

    如果使用eclipse集合中的MutableMap和MutableList,代码如下:

    MutableMap<String, MutableList<Transaction>> transactionsMap = getMapOfTransactionalData(...);
    long currentTime = Instant.now().getEpochSecond();
    MutableMap<String, Double> idTransactionSumMap = transactionsMap.collect((id, transList) -> Tuples.pair(id, transList.select(transaction -> {
        // your condition to compare time
        long transactionTime = transaction.getTimestamp().toEpochSecond(ZoneOffset.UTC);
        return transactionTime > currentTime - TimeUnit.HOURS.toMillis(24);
    }).sumOfDouble(Transaction::getAmount)));