【问题标题】:Using Java 8 streams, how do I replace the key in a map with its index?使用 Java 8 流,如何将地图中的键替换为其索引?
【发布时间】:2018-05-12 13:22:23
【问题描述】:

所以我有一个Map<String, Map<String, Integer>>,我想将其转换为Map<Integer, Map<String, Integer>>,其中字符串键被替换为其在映射中的索引(0,1,2,.....)。我知道地图中的索引不准确,但这对我来说并不重要。 我尝试使用 AtomicInteger 作为在流上的每次操作后递增的索引,但我无法解决问题....

【问题讨论】:

标签: java lambda java-8 java-stream


【解决方案1】:

正如 Michael 所指出的那样,一个 Map 的键只有 Integer 相互跟随可以减少为 List<Map<String, Integer>>,但如果你真的是你的特定结构:

  1. 你可以使用AtomicInteger

    AtomicInteger a = new AtomicInteger(0);
    before.forEach((key, value) -> after.put(a.getAndIncrement(), value));
    

    => Working example here


  1. 或者,after 是否在开始时为空

    before.values().forEach(value -> after.put(after.size(), value));
    

    => Working example here

【讨论】:

  • 假设after最初是空的,你也可以使用before.values().forEach(value -> after.put(after.size(), value));
  • @Holger 非常聪明!
【解决方案2】:

具有连续整数键的映射在概念上与列表没有什么不同,因此您真正想要的是List<Map<String, Integer>>

你可以这样实现:

List<Map<String, Integer>> after = before.values().stream().collect(Collectors.toList());

【讨论】:

  • 谢谢!这种方法有效,但实际上我确实需要得到一个 Map 结果.....
  • 或者只是new ArrayList&lt;&gt;(before.values())...
  • @Holger 这是那些问题之一,它不必要地将自己限制为“使用 Java 8 流......”
  • 对;因为 Collection API 比 Stackoverflow 更老,所以从来没有类似的一堆“我如何使用 Collection API 解决这个问题?”问题。我认为,值得展示所有替代方案,以帮助开发人员了解有多少事情可以轻松解决,即使没有 Stream API……顺便说一句,公认的答案也不使用 Stream API……
  • @Holger StackOverflow 不适合实用主义!
【解决方案3】:

由于您明确要求Map&lt;Integer, Map&lt;String, Integer&gt;&gt;,您可以分两步完成。

首先,将地图的值收集到一个列表中:

List<Map<String, Integer>> temporaryResult = new ArrayList<>(myMap.values());

然后生成索引和地图:

Map<Integer, Map<String, Integer>> resultSet =
            IntStream.range(0, temporaryResult.size())
                    .mapToObj(i -> new AbstractMap.SimpleEntry<>(i,
                            temporaryResult.get(i)))
                    .collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey,
                            AbstractMap.SimpleEntry::getValue));

或者不映射到中间AbstractMap.SimpleEntry's

Map<Integer, Map<String, Integer>> resultSet =
               IntStream.range(0, temporaryResult.size())
                        .boxed()
                        .collect(Collectors.toMap(Function.identity(),
                                temporaryResult::get));

【讨论】:

    【解决方案4】:

    您可以使用整数序列并对其进行压缩,或映射到这些整数: IntStream.range(0, yourCollection.length)...

    这将是代码,您可能需要稍作调整。你可以得到拉链的想法。 `

    import java.util.Map;
    import java.util.HashMap;
    import java.util.List;
    import java.util.ArrayList;
    import java.util.stream.IntStream;
    
    class JavaTest{
        public int main(String[] args){
            Map<String, String> myMap = new HashMap<>();
            myMap.put("Key1", "Value1");
            myMap.put("Key2", "Value2");
            myMap.put("Key3", "Value3");
    
            List<String> values = new ArrayList<String>(myMap.values());
    
            Map<Integer, String> newMap = new HashMap<>();
    
            IntStream
            .range(0, values.size())
            .forEach(i -> newMap.put(i, values.get(i)));
    
            return 1;
        }
    }
    

    ` 附言您的即时否决真的有助于我回答问题;)

    【讨论】:

      猜你喜欢
      • 2016-01-13
      • 1970-01-01
      • 2016-07-10
      • 2016-07-28
      • 2018-05-05
      • 2020-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多