我有一个Map对象。 key
是ID,值是Transaction
的列表。下面是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} ]
它有两个键012345
和678900
,每个键都有三个事务。密钥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)));
});
,但是没有返回正确的值。我不知道该怎么做。谁能指出我这样做的正确方法?
答案 0 :(得分:0)
如果您愿意使用第三方库,则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-collection使用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)));