If I have 2 Streams like coming in a method as shown below
public Stream<Transaction> getPendingTransaction(Stream<PendingTransaction> pendingTransactionStream,Stream<ProcessedTransaction> processedTransactionStream){ }
and I want to find all objects which are present in pendingTransactionStream
which are also present in processedTransactionStream
based upon some criteria like
if
transaction.getId()
is same for an Transaction object present inpendingTransactionStream
andprocessedTransactionStreamthen
that object is same and we can collect them in a list.
I tried doing like this but its giving error
processedTransactionStream
.filter( (processedTransaction)->
{
pendingTransactionStream.anyMatch(s->s.getTransactionId().equals(processedTransaction.getTransactionId()) );
}
).collect(Collectors.toList());
You can't iterate Stream
s more than once. So your current code doesn't work (you get an exception like IllegalStateException: Stream already closed
. From the java doc:
A stream should be operated on (invoking an intermediate or terminal stream operation) only once.
A possible solution would be to convert the pendingTransactionStream
into a map where the key is the type of the id
(I use string, because I don't know the keyType):
Actually a
Set
would be better as you don't need thePendingTransaction
for anything else, for an example have a look at @Eran's answer
Map<String, PendingTransaction> pendingTransactionMap = pendingTransactionStream
.collect(PendingTransaction::getId, Function.identity());
And then filter
your processedTransactionStream
, by checking if the id is in the map:
List<ProcessedTransaction> processedTransactionList = processedTransactionStream
.filter(p -> pendingTransactionMap.containsKey(p.getId()))
.collect(Collectors.toList());