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());
With Java 8, Collection interface has two methods to generate a Stream. stream() − Returns a sequential stream considering collection as its source. parallelStream() − Returns a parallel Stream considering collection as its source.
Introduced in Java 8, the Stream API is used to process collections of objects. A stream is a sequence of objects that supports various methods which can be pipelined to produce the desired result. A stream is not a data structure instead it takes input from the Collections, Arrays or I/O channels.
Java 8 offers the possibility to create streams out of three primitive types: int, long and double. As Stream<T> is a generic interface, and there is no way to use primitives as a type parameter with generics, three new special interfaces were created: IntStream, LongStream, DoubleStream.
concat() in Java. Stream. concat() method creates a concatenated stream in which the elements are all the elements of the first stream followed by all the elements of the second stream. The resulting stream is ordered if both of the input streams are ordered, and parallel if either of the input streams is parallel.
Well, you can't consume the pendingTransactionStream
Stream
multiple times. You can transform it to a List
(or even better, a Set
) of transaction IDs to use in the filter
method.
Set<String> pending = pendingTransactionStream.map(PendingTransaction::getTransactionId)
.collect(Collectors.toSet());
List<ProcessedTransaction> processed =
processedTransactionStream.filter(pt -> pending.contains(pt.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());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With