所以我有一个 Map<String, Map<String, List<Person>>>
我想将其转换为 Map<Integer, Map<String, Integer>>
其中第一个 Integer 键代表数字 1,2,3.....(从第一个映射中获取的当前条目的索引),第二个 Integer 给出了 List<Person>
的大小。 。
内部映射中的字符串保持不变......
首先,我只是尝试用列表的大小替换 map 中的第二个整数,但它不起作用......
Map<String, Map<String, List<Person>>> map2 =...
Map<String, Map<String, Integer>> map = map2.entrySet().stream().collect(
Collectors.groupingBy(p -> p.getKey(), Collectors.toMap(p -> p.getValue().getKey(), p->p.getValue().values().size())));
最佳答案
根据定义, map 没有索引。您可能尝试根据插入顺序为映射的条目指定一个从 1 开始的编号。如果您使用的是 LinkedHashMap
有一种方法可以实现这一点。
但是,HashMap
不保证 map 的顺序。此外,它不保证顺序随着时间的推移保持不变;因此,为这些条目指定一个数字并不总是能产生预期的结果。
也就是说,您可能只想对 map 中的条目进行编号 1
至n
哪里n
是 map 的大小,与上面提到的条目的插入顺序无关,即第一个插入的条目不一定必须编号为 1,第二个插入的条目不一定必须编号为 2 等..
现在,解决方案:
您可以拥有List<Map<String, Integer>>
作为临时结果集,当您需要条目编号时,只需循环遍历元素并使用 i + 1
获取编号哪里i
是控制变量。
假设我们有这个列表的示例:
List<Map<String, Integer>> temporaryResult = myMap.values()
.stream()
.map(a -> a.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey,
c -> c.getValue().size()))
)
.collect(Collectors.toList());
然后我们可以得到 Map<Integer, Map<String, Integer>>
与:
Map<Integer, Map<String, Integer>> resultSet =
IntStream.range(0, temporaryResult.size())
.mapToObj(i -> new AbstractMap.SimpleEntry<>(i + 1,
temporaryResult.get(i)))
.collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey,
AbstractMap.SimpleEntry::getValue));
注意-
- 如果编号应基于插入顺序,则仅当您使用的 map 保持插入顺序时,此代码才会产生预期结果。
- 如果编号不一定基于映射中条目的插入顺序,则无论使用何种映射实现,此解决方案都将有效。
关于java - 使用 Java 8 流,如何将 Map<String, Map<String, List<Person>>> 转换为 Map<Integer, Map<String, Integer>>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50305784/