如何使用流在Java中生成列表列表地图(Map >>)

问题描述 投票:0回答:3

给出:

enum Food{
FRUITS, VEGGIES;
}

Map<String, List<String>> basketMap = new HashMap<>();
basketMap .put("bucket1", Arrays.asList("apple", "banana"));
basketMap .put("bucket2", Arrays.asList("orange", "kiwi"));
basketMap .put("bucket3", Arrays.asList("banana", "orange"));

需要生成列表列表的地图(populte fruitBaskerMap)

Map<String, Map<Food, List<String>> fruitBasketMap = new HashMap<>();

最终输出:

fruitBasketMap:
[
bucket1, [Food.FRUITS, {"apple", "banana"}],
bucket2, [Food.FRUITS, {"orange", "kiwi"}],
bucket3, [Food.FRUITS, {"banana", "orange"}]
]

我尝试了以下操作(但未成功)

fruitBasketMap = basketMap.entrySet().stream().collect(
    Collectors.toMap(Map.Entry::getKey,
        Collectors.toMap(Food.FRUITS,
            Collectors.toList(Map.Entry::getValue())
        )
    )
);

有人可以让我知道我该怎么做吗?

java collections java-8 stream java-stream
3个回答
1
投票

此实现似乎正在运行(使用Java 9 Map.of):

Map<String, Map<Food, List<String>>> fruitBasketMap = basketMap.entrySet().stream()
        .map(e -> Map.entry(e.getKey(), Map.of(Food.FRUITS, e.getValue())))
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

测试结果:

{
bucket2={FRUITS=[orange, kiwi]}, 
bucket3={FRUITS=[banana, orange]}, 
bucket1={FRUITS=[apple, banana]}
}

0
投票

这应该以Java 8+的方式完成:

fruitBasketMap = 
    basketMap.entrySet()
             .stream()
             .collect(groupingBy(Entry::getKey,
                                 toMap(e -> Food.FRUITS, Entry::getValue)));

以上收集器以下列方式工作:

  1. 通过元素的键对元素进行分组,因此键与原始地图中的键保持相同。
  2. 使用以下命令将条目收集到新地图中
    • 键:Food.FRUITS(所有条目均不变)
    • 值:原始值(字符串列表)

0
投票

您可以用Java-8方式本身来实现。尝试以下之一。由于内部地图将始终只有一个条目,因此您可以使用singletonMap

Map<String, Map<Food, List<String>>> result = basketMap.entrySet()
                .stream()
                .collect(Collectors.toMap(Map.Entry::getKey, entry -> Collections.singletonMap(Food.FRUITS, entry.getValue())));
© www.soinside.com 2019 - 2024. All rights reserved.