【问题标题】:Convert java list to map using stream with indexes使用带索引的流将java列表转换为映射
【发布时间】:2018-10-12 22:54:10
【问题描述】:

我正在尝试学习如何使用 Java 8 集合,我想知道是否有一种方法可以使用 Java 流将我的列表转换为地图。

    List<PrimaryCareDTO> batchList = new ArrayList<>();

    PrimaryCareDTO obj = new PrimaryCareDTO();
    obj.setProviderId("123");
    obj.setLocatorCode("abc");
    batchList.add(obj);

    obj = new PrimaryCareDTO();
    obj.setProviderId("456");
    obj.setLocatorCode("def");
    batchList.add(obj);

我想知道如何使用流将上面的列表创建到地图中。我知道如何将 foreach 等与 put 一起使用,但我只是想知道是否有更优雅的方法来使用流构建地图。 (我知道下面的语法不正确,我是流的新手,不知道怎么写)

    AtomicInteger index = new AtomicInteger(0);

    Map<String, Object> result = batchList.stream()
            .map("providerId" + index.getAndIncrement(), PrimaryCareDTO::getProviderId)
            .map("locatorCode" + index.get(), PrimaryCareDTO::getLocatorCode);

目标是代表以下内容。

    Map<String, Object> map = new HashMap<>();

    //Group a
    map.put("providerId1", "123");
    map.put("locatorCode1", "abc");

    //Group b
    map.put("providerId2", "456");
    map.put("locatorCode2", "def");

【问题讨论】:

  • 类似问题,你可以查一下。 stackoverflow.com/questions/35650974/…
  • 您需要跟踪索引(例如,如果流是并行的,您的解决方案可能会中断)并且您需要为每个列表项创建两个映射条目。这两个约束不适用于流。所以可能有一个解决方案,但它可能比使用循环更难看。
  • @assylias 所以你建议坚持使用 for 循环而不是流?
  • 在那个具体的例子中是的。

标签: java


【解决方案1】:
...
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.Map.Entry;
...

AtomicInteger index = new AtomicInteger(0);

List<SimpleEntry<String, String>> providerIds =
        batchList.stream()
                 .map(e -> new SimpleEntry<>("providerId" + index.incrementAndGet(), e.getProviderId()))
                 .collect(Collectors.toList());

index.set(0);

List<SimpleEntry<String, String>> locatorCodes =
        batchList.stream()
                 .map(e -> new SimpleEntry<>("locatorCode" + index.incrementAndGet(), e.getLocatorCode()))
                 .collect(Collectors.toList());

Map<String, String> map = Stream.of(providerIds,
                                    locatorCodes)
                                .flatMap(e -> e.stream())
                                .collect(Collectors.toMap(Entry::getKey, Entry::getValue));

首先它创建两个列表,使用Entry(来自Map)来表示字符串-字符串元组:

  • 将元组providerId# 列为“键”,其值例如"123"
  • 将元组locatorCode# 列为“键”,其值例如"abc"

然后它创建一个包含这两个列表作为“元素”的流,然后将它们与flatMap() 连接以获得Entry 的单个长流,

(前两个不能保持流,我必须通过List 并返回流的原因是因为index.incrementAndGet() 的两个调用否则只会在流被消耗时评估,即在index.set(0);之后。)

然后它使用计数器创建新的键值对并将它们放入映射中(使用Collectors.toMap()

【讨论】:

    【解决方案2】:

    您需要两次蒸汽,因为您想将两个属性添加到地图

        AtomicInteger index = new AtomicInteger(1);
    
        Map<String, String> result1 = batchList.stream()
                .collect(Collectors
                        .toMap(ignored -> "providerId" + index.getAndIncrement(), PrimaryCareDTO::getProviderId)
                        );
    
        index.set(1);
        Map<String, String> result2 = batchList.stream()
                .collect(Collectors
                        .toMap(ignored -> "locatorCode" + index.getAndIncrement(), PrimaryCareDTO::getLocatorCode)
                        );
    
        Map<String, String> result = new HashMap<>();
        result.putAll(result1);
        result.putAll(result2);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-16
      • 1970-01-01
      • 1970-01-01
      • 2013-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-13
      相关资源
      最近更新 更多