如何将具有相似键的List <Map <String,String >>转换为Map <String,List <String >>?

时间:2019-12-08 13:01:10

标签: java android list dictionary multiple-value

我有以下列表-

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}]

enter image description here

我要实现的最终结果是一张包含一个或多个键的映射,每个键都有一个值字符串列表。例如-我在这里为您展示的产品具有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]}

密钥已重复。为什么?

enter image description here

1 个答案:

答案 0 :(得分:3)

流(> = Java 8)

对于List使用Stream,对Map的条目使用flatMap,然后使用{{3 }}收集器:

// 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循环,例如

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());
    }
}