Java8是否可以方便地实现以下要求,即
Map<X,Y> + Map<Y,Z> = Map<X,Z>
现在我的代码是
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);
我想知道实现这一要求是否更方便?
答案 0 :(得分:7)
另一种方法是直接流式传输第一张地图的入口集,例如:
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())));
}
你唯一需要处理的是左边地图中存在一个值,而右边地图中没有相应的键,你将拥有NullPointerException
,因为不允许使用值mapper函数返回null
。在这种情况下,您可以使用getOrDefault
提供与使用e -> right.getOrDefault(e.getValue(), defaultValue)
相关联的非null默认值,或者如果您不希望在生成的地图中使用映射,则可以模仿{ {1}}收集器通过过滤不必要的映射。
toMap
答案 1 :(得分:0)
您可以简单地使用Java 8中的默认地图方法
shopIdNameMap.forEach((key,value)->shopIdNameMap.replace(key,couponCodeNameMap.get(value)));