Как одновременно выполнить итерацию по списку и набору при объединении их в другую карту (используя поток) - PullRequest
1 голос
/ 12 апреля 2020

Я попробовал создать итератор для списка и использовать поток на множестве как таковой

Set //some object which has a getId method
Iterator<String> iterator = list.iterator();
someSet.stream()
     .map(Collectors.toMap(e -> e.getId(), e -> iterator.next() );

Ответы [ 2 ]

1 голос
/ 12 апреля 2020

Stream API предназначен для работы и перебора одной и только одной коллекции и не более.

Если вы хотите выполнить такую ​​итерацию, которая называется «zip», как упоминалось в другом ответе, вы должны выполнить итерации индексов. Так как Set не заказан, вы должны использовать вместо него List и знать, что порядок не предсказуем.

Однако использование Stream API здесь должно быть хорошо:

Set<MyObject> set = ...                                             // MyObject with getId method
List<MyObject> listFromSet = new ArrayList<>(set);
List<MyObject> list = ...                                           // existing list

IntStream.range(0, Math.min(list.size(), listFromSet.size()))
        .mapToObj(index -> new AbstractMap.SimpleEntry<>(
            listFromSet.get(index).getId(),                         // key
            list.get(index))                                        // value
        )
        .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); // to Map

Несколько замечаний:

  • Чтобы узнать наибольшее число, которое вы можете перебрать, вам нужно найти меньшее из размеров итерируемых элементов: Math.min(list.size(), listFromSet.size()).
  • map(Collector.toMap(...)) число не преобразуйте Stream в Map, но не является допустимой конструкцией, более того, метод map не является терминальной операцией. Вместо этого используйте .collect(Collectors.toMap(...)).
  • Можно использовать не все ключи из set, не все значения из list, не существует гарантированного порядка ключей и соответствующего ключа -значение будет случайным.
  • Если бы я это реализовал, я бы определенно go за простую итерацию for-loop над потоками.
1 голос
/ 12 апреля 2020

Я думаю, то, чего вы добились, называется «молнией» в функциональном программировании. Это было бы в Java для создания нового потока из двух существующих потоков путем объединения каждого из двух соответствующих элементов заданных потоков.

Посмотрите на этот вопрос, чтобы увидеть, как это сделать:

Сжатие потоков с использованием JDK8 с лямбдами (java .util.stream.Streams.zip)

...