sau*_*m22 10 java java-8 java-stream
如果我有2个Streams,如下面所示的方法
public Stream<Transaction> getPendingTransaction(Stream<PendingTransaction> pendingTransactionStream,Stream<ProcessedTransaction> processedTransactionStream){ }
Run Code Online (Sandbox Code Playgroud)
我想找到其中存在的所有对象中pendingTransactionStream同样存在于processedTransactionStream基于像一些标准
if
transaction.getId()对于存在的Transaction对象是相同的,pendingTransactionStream并且processedTransactionStreamthen该对象是相同的,我们可以在列表中收集它们.
我尝试这样做,但它给出了错误
processedTransactionStream
.filter( (processedTransaction)->
{
pendingTransactionStream.anyMatch(s->s.getTransactionId().equals(processedTransaction.getTransactionId()) );
}
).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
好吧,你不能pendingTransactionStream Stream多次消费.您可以将其转换为要在方法中使用的List(或甚至更好的Set)a 事务ID filter.
Set<String> pending = pendingTransactionStream.map(PendingTransaction::getTransactionId)
.collect(Collectors.toSet());
List<ProcessedTransaction> processed =
processedTransactionStream.filter(pt -> pending.contains(pt.getTransactionId()))
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
您不能Stream多次迭代 s 。所以你当前的代码不起作用(你会得到一个异常,如IllegalStateException: Stream already closed. 来自java doc:
流只能被操作(调用中间或终端流操作)一次。
一个可能的解决方案是将 转换pendingTransactionStream为一个映射,其中键是 的类型id(我使用字符串,因为我不知道 keyType):
实际上 a
Set会更好,因为你不需要PendingTransaction其他任何东西,例如看看@Eran的答案
Map<String, PendingTransaction> pendingTransactionMap = pendingTransactionStream
.collect(PendingTransaction::getId, Function.identity());
Run Code Online (Sandbox Code Playgroud)
然后filter你的processedTransactionStream,通过检查 id 是否在地图中:
List<ProcessedTransaction> processedTransactionList = processedTransactionStream
.filter(p -> pendingTransactionMap.containsKey(p.getId()))
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)