如果我有2条流,例如采用如下所示的方法
public Stream<Transaction> getPendingTransaction(Stream<PendingTransaction> pendingTransactionStream,Stream<ProcessedTransaction> processedTransactionStream){ }
,我想根据
这样的条件,找到pendingTransactionStream
中存在的所有对象,而processedTransactionStream
中也存在所有对象
如果
transaction.getId()
与存在于pendingTransactionStream
和processedTransactionStreamthen
对象是相同的,我们可以将它们收集在列表中。
我试图这样做,但是它给出了错误
processedTransactionStream
.filter( (processedTransaction)->
{
pendingTransactionStream.anyMatch(s->s.getTransactionId().equals(processedTransaction.getTransactionId()) );
}
).collect(Collectors.toList());
答案 0 :(得分:7)
好吧,您不能多次消费pendingTransactionStream
Stream
。您可以将其转换为List
方法中使用的Set
(甚至更好的是filter
)交易ID。
Set<String> pending = pendingTransactionStream.map(PendingTransaction::getTransactionId)
.collect(Collectors.toSet());
List<ProcessedTransaction> processed =
processedTransactionStream.filter(pt -> pending.contains(pt.getTransactionId()))
.collect(Collectors.toList());
答案 1 :(得分:4)
您不能多次重复Stream
。因此,您当前的代码无效(您会收到IllegalStateException: Stream already closed
之类的异常。来自java doc:
流应操作(调用中间流或终端流操作)仅一次。
一种可能的解决方案是将pendingTransactionStream
转换为键为id
类型的映射(我使用字符串,因为我不知道keyType):
实际上,
Set
会更好,因为您不需要PendingTransaction
来做其他任何事情,例如看一下@Eran's answer
Map<String, PendingTransaction> pendingTransactionMap = pendingTransactionStream
.collect(PendingTransaction::getId, Function.identity());
然后通过检查ID是否在地图上来filter
您的processedTransactionStream
:
List<ProcessedTransaction> processedTransactionList = processedTransactionStream
.filter(p -> pendingTransactionMap.containsKey(p.getId()))
.collect(Collectors.toList());