Как искать между двумя потоками в Java 8 - PullRequest
0 голосов
/ 15 января 2019

Если у меня есть 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());

Ответы [ 2 ]

0 голосов
/ 15 января 2019

Вы не можете повторить Stream s более одного раза. Таким образом, ваш текущий код не работает (вы получаете исключение, например IllegalStateException: Stream already closed. Из java doc :

Поток должен работать на (вызывая промежуточную или терминальную операцию потока) только один раз .

Возможным решением было бы преобразовать pendingTransactionStream в карту, где ключом является тип id (я использую строку, потому что я не знаю keyType):

На самом деле Set было бы лучше, поскольку вам не нужно PendingTransaction для чего-либо еще, например, посмотрите на @ ответ Эрана

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

А затем filter ваш processedTransactionStream, проверив, есть ли идентификатор на карте:

List<ProcessedTransaction> processedTransactionList = processedTransactionStream
    .filter(p -> pendingTransactionMap.containsKey(p.getId()))
    .collect(Collectors.toList());
0 голосов
/ 15 января 2019

Ну, вы не можете потреблять pendingTransactionStream Stream несколько раз. Вы можете преобразовать его в List (или, что еще лучше, Set) идентификаторов транзакций для использования в методе filter.

Set<String> pending = pendingTransactionStream.map(PendingTransaction::getTransactionId)
                                              .collect(Collectors.toSet());
List<ProcessedTransaction> processed = 
    processedTransactionStream.filter(pt -> pending.contains(pt.getTransactionId()))
                              .collect(Collectors.toList());
...