我如何同时遍历列表和集合,同时在另一个地图中将它们配对(使用流)

时间:2020-04-12 17:22:57

标签: java java-8 java-stream

我尝试的是为列表创建一个迭代器,并像这样在集合上使用流

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 个答案:

答案 0 :(得分:1)

我认为,您要实现的目标在功能编程中称为“ zip”。在Java中,通过合并给定流的两个对应元素中的每个元素,可以从两个现有流中生成一个新流。

看看这个问题,看看怎么做:

Zipping streams using JDK8 with lambda (java.util.stream.Streams.zip)

答案 1 :(得分:1)

Stream API旨在工作和遍历一个(只有一个)集合,并且不再迭代。

如果要实现称为“ zipping”的迭代,如另一个答案中所述,则必须迭代索引。由于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中的所有值,不能保证键的顺序,并且匹配的键值将是随机的。 / li>
  • 如果要实现这一点,我肯定会在Streams上进行简单的for-loop迭代。