【问题标题】:How to turn a List<Map<String, String>> with similar keys to a Map<String,List<String>>?如何将具有相似键的 List<Map<String, String>> 转换为 Map<String,List<String>>?
【发布时间】:2019-12-08 13:01:10
【问题描述】:

我有以下列表 -

private MiniProductModel selectedProduct;
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_product_page);
        mPresenter = new ProductPagePresenter(this);
        mPresenter.initViews();
        mPresenter.initProductData();

        Gson gson = new Gson();
        List<Map<String, String>> attributesList = selectedProduct.getAttributesList(); //this is the list

所以我得到的原始价值如下 -

[{value=Pink, key=Color}, {value=Yellow, key=Color}]

我想要实现的最终结果是一个包含一个或多个键的映射,每个键都有一个值字符串列表。例如 - 我在这里向您展示的产品有 2 种不同的颜色,所以我需要地图有一个名为 Color 的键和一个包含多个 String 值的值列表。

如何将我的列表转到想要的地图?

编辑 -

这是我目前使用 Wards 解决方案的结果 -

{value=[Sensitive Skin, Normal Skin, Combination Skin, Oily Skin, MEN], key=[Skin Type, Skin Type, Skin Type, Skin Type, Skin Type]}

密钥已重复。为什么?

【问题讨论】:

  • 到目前为止你有什么尝试?
  • 试图将其转换为包含字符串值列表的映射,但无法弄清楚如何迭代整个列表并将键与每个键进行比较并将它们添加到正确的列表中相同的键值@Ward
  • 您的结果显示了一个包含 2 个键的地图:文字 "key""value",这有点奇怪
  • 谢谢你,这就是问题所在 - 在我得到答案之前结合你的答案。再次感谢! :)

标签: java android list dictionary multiple-value


【解决方案1】:

流 (>= Java 8)

这可以通过将Stream 用于ListflatMapMaps 的条目来非常优雅地完成,然后使用groupingBy 收集器收集:

// Note that Map.of/List.of require Java 9, but this is not part of the solution
List<Map<String, String>> listOfMaps = List.of(
        Map.of("1", "a1", "2", "a2"),
        Map.of("1", "b1", "2", "b2")
);

final Map<String, List<String>> mapOfLists = listOfMaps.stream()
        .flatMap(map -> map.entrySet().stream())
        .collect(groupingBy(Entry::getKey, mapping(Entry::getValue, toList())));

mapOfLists.forEach((k, v) -> System.out.printf("%s -> %s%n", k, v));

输出是

1 -> [a1, b1]
2 -> [a2, b2]

for循环

如果流不是一个选项,您可以使用普通的旧 for 循环,例如

final Map<String, List<String>> mapOfLists = new HashMap<>();
for (Map<String, String> map : list) {
    for (Entry<String, String> entry : map.entrySet()) {
        if (!mapOfLists.containsKey(entry.getKey())) {
            mapOfLists.put(entry.getKey(), new ArrayList<>());
        }
        mapOfLists.get(entry.getKey()).add(entry.getValue());
    }
}

【讨论】:

  • 谢谢,看起来真的很优雅!虽然我现在正在使用 Java,所以我需要将此解决方案翻译成 Java 以便我使用它
  • 嗯,这实际上是 Java。该解决方案应该从 Java 8... 开始工作
  • 实际上,您至少需要 Java 9 才能使用 List.of 和 Map.of。
  • 起初我虽然这是一个 Kotlin 解决方案,但很高兴知道 Java 正在朝着看起来更优雅的方向发展:) 无论如何,如果你能给我一个可以与 Android (Java 8) 编译的解决方案这将解决我的问题。
  • 不代表 Ward,但 Java 9 元素只是为了建立示例。据我所知,从“最终地图”...开始的任何内容都与 Java 8 兼容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-21
  • 2020-04-01
  • 1970-01-01
  • 2015-11-21
  • 2021-12-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多