简体   繁体   English

java8将Map <X,Y> + Map <Y,Z>转换为Map <X,Z>

[英]java8 convert Map<X,Y> + Map<Y,Z> to Map<X,Z>

Does Java8 could convenient to implement below requirement, that is Java8是否可以方便地实现以下要求,即

Map<X,Y> + Map<Y,Z> = Map<X,Z>

Now my code is 现在我的代码是

ArrayList<String> couponCodes = newArrayList("aaa", "bbb", "ccc");
// couponCode -- shopId
ArrayList<ShopCoupon> shopCoupons = newArrayList(new ShopCoupon("aaa", 1), new ShopCoupon("bbb", 2), new ShopCoupon("ccc", 3));
Map<String, Integer> couponCodeShopIdMap = shopCoupons.stream().collect(toMap(sc -> sc.getCouponCode(), sc -> sc.getShopId()));
// shopId -- name
ArrayList<Shop> shops = newArrayList(new Shop(1, "zhangsan"), new Shop(2, "lisi"), new Shop(3, "wangwu"));
Map<Integer, String> shopIdNameMap = shops.stream().collect(toMap(s -> s.getId(), s -> s.getName()));

//couponCode -- name
Map<String, String> couponCodeNameMap = couponCodes.stream().collect(toMap(c -> c, c -> shopIdNameMap.get(couponCodeShopIdMap.get(c))));
System.out.println(couponCodeNameMap);

I want to know is some more convenient manner to implement this requirement? 我想知道实现这个要求是否更方便?

Another way would be to stream over the entry set of the first map directly, eg: 另一种方法是直接流式传输第一个地图的入口集,例如:

public static <X, Y, Z> Map<X, Z> join(Map<X, Y> left, Map<Y, Z> right) {
    return left.entrySet()
               .stream()
               .collect(toMap(Map.Entry::getKey, e -> right.get(e.getValue())));
}

The only thing you have to deal with is when a value is present in the left map and not the corresponding key in the right map, you'll have a NullPointerException , since the value mapper function is not allowed to return null . 您必须处理的唯一事情是当左侧映射中存在值而不是右侧映射中的相应键时,您将具有NullPointerException ,因为不允许值映射器函数返回null In this case you can either use getOrDefault to provide a non-null default value to be associated with using e -> right.getOrDefault(e.getValue(), defaultValue) , or if you don't want to have the mapping in the resulting map, mimick the toMap collector by filtering upfront the inexistant mappings. 在这种情况下,您可以使用getOrDefault提供与使用e -> right.getOrDefault(e.getValue(), defaultValue)关联的非null默认值,或者如果您不希望在生成的地图,通过过滤不必要的映射来toMap收集器。

public static <X, Y, Z> Map<X, Z> join(Map<X, Y> left, Map<Y, Z> right) {
    return left.entrySet().stream().collect(
        HashMap::new,
        (m, e) -> {
            //if you still want the mapping k -> null, 
            //you can just use put directly
            Z value = right.get(e.getValue());
            if(value != null) m.put(e.getKey(), value);
        },
        Map::putAll);
}

您可以简单地使用Java 8中的默认地图方法

shopIdNameMap.forEach((key,value)->shopIdNameMap.replace(key,couponCodeNameMap.get(value)));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM