简体   繁体   English

如何在Java 8中的两个Streams之间进行搜索

[英]How to search between two Streams in Java 8

If I have 2 Streams like coming in a method as shown below 如果我有2个Streams,如下面所示的方法

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 我想找到pendingTransactionStream中存在的所有对象,这些对象也存在于processedTransactionStream基于某些条件,如

if transaction.getId() is same for an Transaction object present in pendingTransactionStream and processedTransactionStreamthen that object is same and we can collect them in a list. 如果transaction.getId()是相同的存在于交易对象pendingTransactionStreamprocessedTransactionStreamthen该对象是相同的,我们可以在一个列表收集它们。

I tried doing like this but its giving error 我尝试这样做,但它给出了错误

processedTransactionStream
        .filter( (processedTransaction)->
        {
            pendingTransactionStream.anyMatch(s->s.getTransactionId().equals(processedTransaction.getTransactionId()) );
        } 
        ).collect(Collectors.toList());

Well, you can't consume the pendingTransactionStream Stream multiple times. 好吧,你不能多次使用pendingTransactionStream Stream You can transform it to a List (or even better, a Set ) of transaction IDs to use in the filter method. 您可以将其转换为要在filter方法中使用的事务ID的List (甚至更好,一Set )。

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. 您不能多次迭代Stream s。 So your current code doesn't work (you get an exception like IllegalStateException: Stream already closed . From the java doc : 所以你当前的代码不起作用(你得到一个异常,如IllegalStateException: Stream already closed 。来自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): 一个可能的解决方案是将pendingTransactionStream转换为一个映射,其中键是id的类型(我使用字符串,因为我不知道keyType):

Actually a Set would be better as you don't need the PendingTransaction for anything else, for an example have a look at @Eran's answer 实际上Set会更好,因为你不需要PendingTransaction用于其他任何事情,例如看看@Eran的回答

Map<String, PendingTransaction> pendingTransactionMap = pendingTransactionStream
    .collect(PendingTransaction::getId, Function.identity());

And then filter your processedTransactionStream , by checking if the id is in the map: 然后通过检查id是否在地图中来filter您的processedTransactionStream

List<ProcessedTransaction> processedTransactionList = processedTransactionStream
    .filter(p -> pendingTransactionMap.containsKey(p.getId()))
    .collect(Collectors.toList());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM